From e92d83832fdf261895f0c56d2261030baf0ffd32 Mon Sep 17 00:00:00 2001 From: Robert-Jan de Dreu <160743+rjd22@users.noreply.github.com> Date: Wed, 4 Feb 2026 11:03:42 +0100 Subject: [PATCH 1/2] feat: Use different warning and errors for namespaced names --- .../Generic/Sniffs/Files/LineLengthSniff.php | 36 +++++++++++++++++- .../Tests/Files/LineLengthUnitTest.5.inc | 37 +++++++++++++++++++ .../Tests/Files/LineLengthUnitTest.php | 18 +++++++++ 3 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 src/Standards/Generic/Tests/Files/LineLengthUnitTest.5.inc diff --git a/src/Standards/Generic/Sniffs/Files/LineLengthSniff.php b/src/Standards/Generic/Sniffs/Files/LineLengthSniff.php index ba05bb08e4..aa18861fa1 100644 --- a/src/Standards/Generic/Sniffs/Files/LineLengthSniff.php +++ b/src/Standards/Generic/Sniffs/Files/LineLengthSniff.php @@ -177,21 +177,53 @@ protected function checkLineLength(File $phpcsFile, array $tokens, int $stackPtr if ($this->absoluteLineLimit > 0 && $lineLength > $this->absoluteLineLimit ) { + $code = 'MaxExceeded'; + if ($this->isLineNamespacedName($tokens, $tokens[$stackPtr]['line']) === true) { + $code = 'NamespacedNameMaxExceeded'; + } + $data = [ $this->absoluteLineLimit, $lineLength, ]; $error = 'Line exceeds maximum limit of %s characters; contains %s characters'; - $phpcsFile->addError($error, $stackPtr, 'MaxExceeded', $data); + $phpcsFile->addError($error, $stackPtr, $code, $data); } elseif ($lineLength > $this->lineLimit) { + $code = 'TooLong'; + if ($this->isLineNamespacedName($tokens, $tokens[$stackPtr]['line']) === true) { + $code = 'NamespacedNameTooLong'; + } + $data = [ $this->lineLimit, $lineLength, ]; $warning = 'Line exceeds %s characters; contains %s characters'; - $phpcsFile->addWarning($warning, $stackPtr, 'TooLong', $data); + $phpcsFile->addWarning($warning, $stackPtr, $code, $data); } } + + + /** + * Checks if a line is a namespaced name + * + * @param array $tokens The token stack. + * @param int $line The line to check validate + * + * @return bool + */ + private function isLineNamespacedName(array $tokens, int $line): bool + { + $filteredTokens = array_filter( + $tokens, + function ($token) use ($line) { + return $token['line'] === $line + && in_array($token['code'], [T_NAME_QUALIFIED, T_NAME_FULLY_QUALIFIED, T_NAME_RELATIVE], true); + } + ); + + return $filteredTokens !== []; + } } diff --git a/src/Standards/Generic/Tests/Files/LineLengthUnitTest.5.inc b/src/Standards/Generic/Tests/Files/LineLengthUnitTest.5.inc new file mode 100644 index 0000000000..4638314328 --- /dev/null +++ b/src/Standards/Generic/Tests/Files/LineLengthUnitTest.5.inc @@ -0,0 +1,37 @@ + 1]; + case 'LineLengthUnitTest.5.inc': + return [ + 10 => 1, + 23 => 1, + 24 => 1, + 25 => 1, + 36 => 1, + 37 => 1, + ]; default: return []; @@ -103,6 +112,15 @@ public function getWarningList($testFile = '') 10 => 1, 14 => 1, ]; + case 'LineLengthUnitTest.5.inc': + return [ + 7 => 1, + 18 => 1, + 19 => 1, + 20 => 1, + 32 => 1, + 33 => 1, + ]; default: return []; From 31c7c059a955ac348c1e31f62e82b0b2b80174c4 Mon Sep 17 00:00:00 2001 From: Robert-Jan de Dreu <160743+rjd22@users.noreply.github.com> Date: Mon, 16 Feb 2026 13:13:09 +0100 Subject: [PATCH 2/2] Only throw namespace error and warning if line cannot be shortened --- .../Generic/Sniffs/Files/LineLengthSniff.php | 33 ++++++++++++------- .../Tests/Files/LineLengthUnitTest.5.inc | 12 +++++-- .../Tests/Files/LineLengthUnitTest.php | 4 +++ 3 files changed, 35 insertions(+), 14 deletions(-) diff --git a/src/Standards/Generic/Sniffs/Files/LineLengthSniff.php b/src/Standards/Generic/Sniffs/Files/LineLengthSniff.php index aa18861fa1..04f4d67004 100644 --- a/src/Standards/Generic/Sniffs/Files/LineLengthSniff.php +++ b/src/Standards/Generic/Sniffs/Files/LineLengthSniff.php @@ -178,7 +178,7 @@ protected function checkLineLength(File $phpcsFile, array $tokens, int $stackPtr && $lineLength > $this->absoluteLineLimit ) { $code = 'MaxExceeded'; - if ($this->isLineNamespacedName($tokens, $tokens[$stackPtr]['line']) === true) { + if ($this->isNamespacedNameExceedingLength($tokens, $stackPtr, $this->absoluteLineLimit) === true) { $code = 'NamespacedNameMaxExceeded'; } @@ -191,7 +191,7 @@ protected function checkLineLength(File $phpcsFile, array $tokens, int $stackPtr $phpcsFile->addError($error, $stackPtr, $code, $data); } elseif ($lineLength > $this->lineLimit) { $code = 'TooLong'; - if ($this->isLineNamespacedName($tokens, $tokens[$stackPtr]['line']) === true) { + if ($this->isNamespacedNameExceedingLength($tokens, $stackPtr, $this->lineLimit) === true) { $code = 'NamespacedNameTooLong'; } @@ -209,21 +209,30 @@ protected function checkLineLength(File $phpcsFile, array $tokens, int $stackPtr /** * Checks if a line is a namespaced name * - * @param array $tokens The token stack. - * @param int $line The line to check validate + * @param array $tokens The token stack. + * @param int $stackPtr The last token on the line. + * @param int $lineLimit The line limit. * * @return bool */ - private function isLineNamespacedName(array $tokens, int $line): bool + private function isNamespacedNameExceedingLength(array $tokens, int $stackPtr, int $lineLimit): bool { - $filteredTokens = array_filter( - $tokens, - function ($token) use ($line) { - return $token['line'] === $line - && in_array($token['code'], [T_NAME_QUALIFIED, T_NAME_FULLY_QUALIFIED, T_NAME_RELATIVE], true); + $line = $tokens[$stackPtr]['line']; + + for ($i = $stackPtr; $tokens[$i]['line'] === $line; $i--) { + $length = ($tokens[$i]['column'] + $tokens[$i]['length'] - 1); + + // Check the line limit of the namespaced name is equal or over the line length. This check accounts for the + // fact that namespaced names are or closed by ; or opened by ( or {. + if ($length >= $lineLimit + && ($tokens[$i]['code'] === T_NAME_QUALIFIED + || $tokens[$i]['code'] === T_NAME_FULLY_QUALIFIED + || $tokens[$i]['code'] === T_NAME_RELATIVE) + ) { + return true; } - ); + } - return $filteredTokens !== []; + return false; } } diff --git a/src/Standards/Generic/Tests/Files/LineLengthUnitTest.5.inc b/src/Standards/Generic/Tests/Files/LineLengthUnitTest.5.inc index 4638314328..9c72008b63 100644 --- a/src/Standards/Generic/Tests/Files/LineLengthUnitTest.5.inc +++ b/src/Standards/Generic/Tests/Files/LineLengthUnitTest.5.inc @@ -33,5 +33,13 @@ echo \ThisReallyLong\Long\Looooong\Loooooooong\UseStatement\ThatShouldThrowAWarn new \ThisReallyLong\Long\Looooong\Loooooooooooong\UseStatement\ThatShouldThrowAWarning\BecauseItsNotTooLong\ClassName(); // These are just a bit too long and should throw a NamespacedNameMaxExceeded error -echo \ThisReallyLong\Long\Long\Looong\UseStatement\ThatShouldNotBeAllowed\AndThrowErrorsBecauseItsTooLong\functionCall(); -new \ThisReallyLong\Long\Long\Looooooong\UseStatement\ThatShouldNotBeAllowed\AndThrowErrorsBecauseItsTooLong\ClassName(); \ No newline at end of file +echo \ThisReallyLong\Long\Long\Looooong\UseStatement\ThatShouldNotBeAllowed\AndThrowErrorsBecauseItsTooLong\functionCall(); +new \ThisReallyLong\Long\Long\Looooooooong\UseStatement\ThatShouldNotBeAllowed\AndThrowErrorsBecauseItsTooLong\ClassName(); + +// These are a bit too long but can be shortened and should throw a TooLong warning +echo \This\Name\Space\IsGoingToBeJustWithinLimits\LongLongLooong\functionCall('foo', 'bar', 'baz'); +new \This\Name\Space\IsGoingToBeJustWithinLimits\LongLongLongLooong\ClassName('foo', 'bar', 'baz'); + +// These are just a bit too long but can be shortened and should throw a MaxExceeded error +echo \ThisReallyLong\Long\Long\Looong\UseStatement\ThatShouldNotBeAllowed\AndThrowErrorsBecauseItsTooLong\functionCall('foo', 'bar', 'baz'); +new \ThisReallyLong\Long\Long\Looooooong\UseStatement\ThatShouldNotBeAllowed\AndThrowErrorsBecauseItsTooLong\ClassName('foo', 'bar', 'baz'); diff --git a/src/Standards/Generic/Tests/Files/LineLengthUnitTest.php b/src/Standards/Generic/Tests/Files/LineLengthUnitTest.php index 162704d2df..892b58a606 100644 --- a/src/Standards/Generic/Tests/Files/LineLengthUnitTest.php +++ b/src/Standards/Generic/Tests/Files/LineLengthUnitTest.php @@ -68,6 +68,8 @@ public function getErrorList($testFile = '') 25 => 1, 36 => 1, 37 => 1, + 44 => 1, + 45 => 1, ]; default: @@ -120,6 +122,8 @@ public function getWarningList($testFile = '') 20 => 1, 32 => 1, 33 => 1, + 40 => 1, + 41 => 1, ]; default: