From 679621528cb60100954fb234c56080ca67074722 Mon Sep 17 00:00:00 2001 From: Choraimy Kroonstuiver <3661474+axlon@users.noreply.github.com> Date: Mon, 21 Nov 2022 14:29:46 +0100 Subject: [PATCH 01/10] Fix `Squiz.Commenting.FunctionComment.InvalidNoReturn` false positive when return type is `never` --- .../Squiz/Sniffs/Commenting/FunctionCommentSniff.php | 9 ++++++--- .../Squiz/Tests/Commenting/FunctionCommentUnitTest.inc | 5 +++++ .../Tests/Commenting/FunctionCommentUnitTest.inc.fixed | 5 +++++ 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/Standards/Squiz/Sniffs/Commenting/FunctionCommentSniff.php b/src/Standards/Squiz/Sniffs/Commenting/FunctionCommentSniff.php index 38170d22e4..3c79a7a8c4 100644 --- a/src/Standards/Squiz/Sniffs/Commenting/FunctionCommentSniff.php +++ b/src/Standards/Squiz/Sniffs/Commenting/FunctionCommentSniff.php @@ -143,9 +143,12 @@ protected function processReturn(File $phpcsFile, $stackPtr, $commentStart) } } }//end if - } else if ($returnType !== 'mixed' && in_array('void', $typeNames, true) === false) { - // If return type is not void, there needs to be a return statement - // somewhere in the function that returns something. + } else if ($returnType !== 'mixed' + && $returnType !== 'never' + && in_array('void', $typeNames, true) === false + ) { + // If return type is not void, never, or mixed, there needs to be a + // return statement somewhere in the function that returns something. if (isset($tokens[$stackPtr]['scope_closer']) === true) { $endToken = $tokens[$stackPtr]['scope_closer']; for ($returnToken = $stackPtr; $returnToken < $endToken; $returnToken++) { diff --git a/src/Standards/Squiz/Tests/Commenting/FunctionCommentUnitTest.inc b/src/Standards/Squiz/Tests/Commenting/FunctionCommentUnitTest.inc index 55e0fe9bb9..a44f5e0e2e 100644 --- a/src/Standards/Squiz/Tests/Commenting/FunctionCommentUnitTest.inc +++ b/src/Standards/Squiz/Tests/Commenting/FunctionCommentUnitTest.inc @@ -1129,3 +1129,8 @@ public function variableCaseTest( public function variableOrderMismatch($bar, $baz, $foo) { return; } + +/** + * @return never + */ +function foo() {} diff --git a/src/Standards/Squiz/Tests/Commenting/FunctionCommentUnitTest.inc.fixed b/src/Standards/Squiz/Tests/Commenting/FunctionCommentUnitTest.inc.fixed index 22474caf85..3d2e10fd6a 100644 --- a/src/Standards/Squiz/Tests/Commenting/FunctionCommentUnitTest.inc.fixed +++ b/src/Standards/Squiz/Tests/Commenting/FunctionCommentUnitTest.inc.fixed @@ -1129,3 +1129,8 @@ public function variableCaseTest( public function variableOrderMismatch($bar, $baz, $foo) { return; } + +/** + * @return never + */ +function foo() {} From 2dd54f064ced73708e54607889874f5d14d09f2c Mon Sep 17 00:00:00 2001 From: Daimona Eaytoy Date: Wed, 19 Apr 2023 14:25:20 +0200 Subject: [PATCH 02/10] Make InnerFunctionsSniff detect functions inside closures --- src/Standards/Squiz/Sniffs/PHP/InnerFunctionsSniff.php | 7 +++++-- src/Standards/Squiz/Tests/PHP/InnerFunctionsUnitTest.inc | 7 +++++++ src/Standards/Squiz/Tests/PHP/InnerFunctionsUnitTest.php | 1 + 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/Standards/Squiz/Sniffs/PHP/InnerFunctionsSniff.php b/src/Standards/Squiz/Sniffs/PHP/InnerFunctionsSniff.php index 4e3ee2152c..c8afb57dfa 100644 --- a/src/Standards/Squiz/Sniffs/PHP/InnerFunctionsSniff.php +++ b/src/Standards/Squiz/Sniffs/PHP/InnerFunctionsSniff.php @@ -43,8 +43,11 @@ public function process(File $phpcsFile, $stackPtr) $function = $phpcsFile->getCondition($stackPtr, T_FUNCTION); if ($function === false) { - // Not a nested function. - return; + $function = $phpcsFile->getCondition($stackPtr, T_CLOSURE); + if ($function === false) { + // Not a nested function. + return; + } } $class = $phpcsFile->getCondition($stackPtr, T_ANON_CLASS, false); diff --git a/src/Standards/Squiz/Tests/PHP/InnerFunctionsUnitTest.inc b/src/Standards/Squiz/Tests/PHP/InnerFunctionsUnitTest.inc index dd851461b9..0c69e06794 100644 --- a/src/Standards/Squiz/Tests/PHP/InnerFunctionsUnitTest.inc +++ b/src/Standards/Squiz/Tests/PHP/InnerFunctionsUnitTest.inc @@ -48,3 +48,10 @@ new class { } } }; + +$outerClosure = function () +{ + // Functions inside closures are not allowed. + function innerFunction() { + } +}; diff --git a/src/Standards/Squiz/Tests/PHP/InnerFunctionsUnitTest.php b/src/Standards/Squiz/Tests/PHP/InnerFunctionsUnitTest.php index 3c9ad07bd3..606d23563c 100644 --- a/src/Standards/Squiz/Tests/PHP/InnerFunctionsUnitTest.php +++ b/src/Standards/Squiz/Tests/PHP/InnerFunctionsUnitTest.php @@ -28,6 +28,7 @@ public function getErrorList() return [ 5 => 1, 46 => 1, + 55 => 1, ]; }//end getErrorList() From 07c94c7e43d5d3b454fa95406d1dd3dc6316e9e9 Mon Sep 17 00:00:00 2001 From: Daimona Eaytoy Date: Wed, 19 Apr 2023 18:30:09 +0200 Subject: [PATCH 03/10] Allow methods inside OOP structures within functions --- .../Squiz/Sniffs/PHP/InnerFunctionsSniff.php | 42 +++++++++++++------ .../Tests/PHP/InnerFunctionsUnitTest.inc | 21 ++++++++++ 2 files changed, 50 insertions(+), 13 deletions(-) diff --git a/src/Standards/Squiz/Sniffs/PHP/InnerFunctionsSniff.php b/src/Standards/Squiz/Sniffs/PHP/InnerFunctionsSniff.php index c8afb57dfa..efcf06c65a 100644 --- a/src/Standards/Squiz/Sniffs/PHP/InnerFunctionsSniff.php +++ b/src/Standards/Squiz/Sniffs/PHP/InnerFunctionsSniff.php @@ -41,25 +41,41 @@ public function process(File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); - $function = $phpcsFile->getCondition($stackPtr, T_FUNCTION); - if ($function === false) { - $function = $phpcsFile->getCondition($stackPtr, T_CLOSURE); - if ($function === false) { - // Not a nested function. - return; + if (isset($tokens[$stackPtr]['conditions']) === false) { + return; + } + + $conditions = $tokens[$stackPtr]['conditions']; + + $outerFuncToken = null; + foreach ($conditions as $condToken => $condition) { + if ($condition === T_FUNCTION || $condition === T_CLOSURE) { + $outerFuncToken = $condToken; + break; } } - $class = $phpcsFile->getCondition($stackPtr, T_ANON_CLASS, false); - if ($class !== false && $class > $function) { - // Ignore methods in anon classes. + if ($outerFuncToken === null) { + // Not a nested function. return; } - $prev = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true); - if ($tokens[$prev]['code'] === T_EQUAL) { - // Ignore closures. - return; + $reversedConditions = array_reverse($conditions, true); + $allowedOOPConditions = [ + T_ANON_CLASS => true, + T_CLASS => true, + T_TRAIT => true, + T_INTERFACE => true, + ]; + foreach ($reversedConditions as $condToken => $condition) { + if ($condToken <= $outerFuncToken) { + break; + } + + if (\array_key_exists($condition, $allowedOOPConditions) === true) { + // Ignore methods in OOP structures defined within functions. + return; + } } $error = 'The use of inner functions is forbidden'; diff --git a/src/Standards/Squiz/Tests/PHP/InnerFunctionsUnitTest.inc b/src/Standards/Squiz/Tests/PHP/InnerFunctionsUnitTest.inc index 0c69e06794..6f78608809 100644 --- a/src/Standards/Squiz/Tests/PHP/InnerFunctionsUnitTest.inc +++ b/src/Standards/Squiz/Tests/PHP/InnerFunctionsUnitTest.inc @@ -55,3 +55,24 @@ $outerClosure = function () function innerFunction() { } }; + +// Allow methods in classes/traits/interfaces defined inside functions +function foo() { + if (class_exists('MyClass') === false) { + class MyClass { + function foo() {} + } + } + + if (trait_exists('MyTrait') === false) { + trait MyTrait { + function foo() {} + } + } + + if (interface_exists('MyInterface') === false) { + interface MyInterface { + function foo(); + } + } +} From d027abb2a56fdfd6f59f11f61b810115465a47fd Mon Sep 17 00:00:00 2001 From: Daimona Eaytoy Date: Wed, 19 Apr 2023 23:26:50 +0200 Subject: [PATCH 04/10] Simplify and improve OOP scope check for nested functions --- .../Squiz/Sniffs/PHP/InnerFunctionsSniff.php | 28 ++++++------------- .../Tests/PHP/InnerFunctionsUnitTest.inc | 9 ++++++ .../Tests/PHP/InnerFunctionsUnitTest.php | 1 + 3 files changed, 18 insertions(+), 20 deletions(-) diff --git a/src/Standards/Squiz/Sniffs/PHP/InnerFunctionsSniff.php b/src/Standards/Squiz/Sniffs/PHP/InnerFunctionsSniff.php index efcf06c65a..721c0aeda8 100644 --- a/src/Standards/Squiz/Sniffs/PHP/InnerFunctionsSniff.php +++ b/src/Standards/Squiz/Sniffs/PHP/InnerFunctionsSniff.php @@ -11,6 +11,7 @@ use PHP_CodeSniffer\Files\File; use PHP_CodeSniffer\Sniffs\Sniff; +use PHP_CodeSniffer\Util\Tokens; class InnerFunctionsSniff implements Sniff { @@ -45,14 +46,19 @@ public function process(File $phpcsFile, $stackPtr) return; } - $conditions = $tokens[$stackPtr]['conditions']; + $reversedConditions = array_reverse($tokens[$stackPtr]['conditions'], true); $outerFuncToken = null; - foreach ($conditions as $condToken => $condition) { + foreach ($reversedConditions as $condToken => $condition) { if ($condition === T_FUNCTION || $condition === T_CLOSURE) { $outerFuncToken = $condToken; break; } + + if (\array_key_exists($condition, Tokens::$ooScopeTokens) === true) { + // Ignore methods in OOP structures defined within functions. + return; + } } if ($outerFuncToken === null) { @@ -60,24 +66,6 @@ public function process(File $phpcsFile, $stackPtr) return; } - $reversedConditions = array_reverse($conditions, true); - $allowedOOPConditions = [ - T_ANON_CLASS => true, - T_CLASS => true, - T_TRAIT => true, - T_INTERFACE => true, - ]; - foreach ($reversedConditions as $condToken => $condition) { - if ($condToken <= $outerFuncToken) { - break; - } - - if (\array_key_exists($condition, $allowedOOPConditions) === true) { - // Ignore methods in OOP structures defined within functions. - return; - } - } - $error = 'The use of inner functions is forbidden'; $phpcsFile->addError($error, $stackPtr, 'NotAllowed'); diff --git a/src/Standards/Squiz/Tests/PHP/InnerFunctionsUnitTest.inc b/src/Standards/Squiz/Tests/PHP/InnerFunctionsUnitTest.inc index 6f78608809..d16c7f2eb6 100644 --- a/src/Standards/Squiz/Tests/PHP/InnerFunctionsUnitTest.inc +++ b/src/Standards/Squiz/Tests/PHP/InnerFunctionsUnitTest.inc @@ -75,4 +75,13 @@ function foo() { function foo(); } } + + // But disallow functions nested inside those methods + if (class_exists('NestedFunctionInMethod') === false) { + class NestedFunctionInMethod { + function foo() { + function innerFunction() {} + } + } + } } diff --git a/src/Standards/Squiz/Tests/PHP/InnerFunctionsUnitTest.php b/src/Standards/Squiz/Tests/PHP/InnerFunctionsUnitTest.php index 606d23563c..b0b13b6147 100644 --- a/src/Standards/Squiz/Tests/PHP/InnerFunctionsUnitTest.php +++ b/src/Standards/Squiz/Tests/PHP/InnerFunctionsUnitTest.php @@ -29,6 +29,7 @@ public function getErrorList() 5 => 1, 46 => 1, 55 => 1, + 83 => 1, ]; }//end getErrorList() From 47b9cbb75585db5c1c8917f649806f5f7294952e Mon Sep 17 00:00:00 2001 From: Daimona Eaytoy Date: Wed, 19 Apr 2023 23:43:02 +0200 Subject: [PATCH 05/10] Micro-optimize array_reverse call --- src/Standards/Squiz/Sniffs/PHP/InnerFunctionsSniff.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Standards/Squiz/Sniffs/PHP/InnerFunctionsSniff.php b/src/Standards/Squiz/Sniffs/PHP/InnerFunctionsSniff.php index 721c0aeda8..e42ef5a16a 100644 --- a/src/Standards/Squiz/Sniffs/PHP/InnerFunctionsSniff.php +++ b/src/Standards/Squiz/Sniffs/PHP/InnerFunctionsSniff.php @@ -46,7 +46,8 @@ public function process(File $phpcsFile, $stackPtr) return; } - $reversedConditions = array_reverse($tokens[$stackPtr]['conditions'], true); + $conditions = $tokens[$stackPtr]['conditions']; + $reversedConditions = array_reverse($conditions, true); $outerFuncToken = null; foreach ($reversedConditions as $condToken => $condition) { From 84621dd4b5c33601ebb69d2940bdfe33a5ee1ca6 Mon Sep 17 00:00:00 2001 From: Dan Wallis Date: Tue, 11 Jul 2023 09:27:53 +0100 Subject: [PATCH 06/10] Handle @param when var passed by reference --- .../Commenting/FunctionCommentSniff.php | 32 ++++++-- .../Commenting/FunctionCommentUnitTest.inc | 75 +++++++++++++++++++ .../FunctionCommentUnitTest.inc.fixed | 75 +++++++++++++++++++ .../Commenting/FunctionCommentUnitTest.php | 25 ++++++- 4 files changed, 199 insertions(+), 8 deletions(-) diff --git a/src/Standards/Squiz/Sniffs/Commenting/FunctionCommentSniff.php b/src/Standards/Squiz/Sniffs/Commenting/FunctionCommentSniff.php index f63d09c43b..38170d22e4 100644 --- a/src/Standards/Squiz/Sniffs/Commenting/FunctionCommentSniff.php +++ b/src/Standards/Squiz/Sniffs/Commenting/FunctionCommentSniff.php @@ -555,16 +555,38 @@ protected function processParams(File $phpcsFile, $stackPtr, $commentStart) // Make sure the param name is correct. if (isset($realParams[$pos]) === true) { - $realName = $realParams[$pos]['name']; - if ($realName !== $param['var']) { + $realName = $realParams[$pos]['name']; + $paramVarName = $param['var']; + + if ($param['var'][0] === '&') { + // Even when passed by reference, the variable name in $realParams does not have + // a leading '&'. This sniff will accept both '&$var' and '$var' in these cases. + $paramVarName = substr($param['var'], 1); + + // This makes sure that the 'MissingParamTag' check won't throw a false positive. + $foundParams[(count($foundParams) - 1)] = $paramVarName; + + if ($realParams[$pos]['pass_by_reference'] !== true && $realName === $paramVarName) { + // Don't complain about this unless the param name is otherwise correct. + $error = 'Doc comment for parameter %s is prefixed with "&" but parameter is not passed by reference'; + $code = 'ParamNameUnexpectedAmpersandPrefix'; + $data = [$paramVarName]; + + // We're not offering an auto-fix here because we can't tell if the docblock + // is wrong, or the parameter should be passed by reference. + $phpcsFile->addError($error, $param['tag'], $code, $data); + } + } + + if ($realName !== $paramVarName) { $code = 'ParamNameNoMatch'; $data = [ - $param['var'], + $paramVarName, $realName, ]; $error = 'Doc comment for parameter %s does not match '; - if (strtolower($param['var']) === strtolower($realName)) { + if (strtolower($paramVarName) === strtolower($realName)) { $error .= 'case of '; $code = 'ParamNameNoCaseMatch'; } @@ -572,7 +594,7 @@ protected function processParams(File $phpcsFile, $stackPtr, $commentStart) $error .= 'actual variable name %s'; $phpcsFile->addError($error, $param['tag'], $code, $data); - } + }//end if } else if (substr($param['var'], -4) !== ',...') { // We must have an extra parameter comment. $error = 'Superfluous parameter comment'; diff --git a/src/Standards/Squiz/Tests/Commenting/FunctionCommentUnitTest.inc b/src/Standards/Squiz/Tests/Commenting/FunctionCommentUnitTest.inc index d57017daf5..55e0fe9bb9 100644 --- a/src/Standards/Squiz/Tests/Commenting/FunctionCommentUnitTest.inc +++ b/src/Standards/Squiz/Tests/Commenting/FunctionCommentUnitTest.inc @@ -1054,3 +1054,78 @@ function throwCommentOneLine() {} * @return void */ function doublePipeFatalError(?stdClass $object) {} + +/** + * Test for passing variables by reference + * + * This sniff treats the '&' as optional for parameters passed by reference, but + * forbidden for parameters which are not passed by reference. + * + * Because mismatches may be in either direction, we cannot auto-fix these. + * + * @param string $foo A string passed in by reference. + * @param string &$bar A string passed in by reference. + * @param string $baz A string NOT passed in by reference. + * @param string &$qux A string NOT passed in by reference. + * @param string &$case1 A string passed in by reference with a case mismatch. + * @param string &$CASE2 A string NOT passed in by reference, also with a case mismatch. + * + * @return void + */ +public function variablesPassedByReference(&$foo, &$bar, $baz, $qux, &$CASE1, $case2) +{ + return; +} + +/** + * Test for param tag containing ref, but param in declaration not being by ref. + * + * @param string &$foo This should be flagged as (only) ParamNameUnexpectedAmpersandPrefix. + * @param string &$bar This should be flagged as (only) ParamNameNoMatch. + * @param string &$baz This should be flagged as (only) ParamNameNoCaseMatch. + * + * @return void + */ +function passedByRefMismatch($foo, $bra, $BAZ) { + return; +} + +/** + * Test variable case + * + * @param string $foo This parameter is lowercase. + * @param string $BAR This parameter is UPPERCASE. + * @param string $BazQux This parameter is TitleCase. + * @param string $corgeGrault This parameter is camelCase. + * @param string $GARPLY This parameter should be in lowercase. + * @param string $waldo This parameter should be in TitleCase. + * @param string $freD This parameter should be in UPPERCASE. + * @param string $PLUGH This parameter should be in TitleCase. + * + * @return void + */ +public function variableCaseTest( + $foo, + $BAR, + $BazQux, + $corgeGrault, + $garply, + $Waldo, + $FRED, + $PluGh +) { + return; +} + +/** + * Test variable order mismatch + * + * @param string $foo This is the third parameter. + * @param string $bar This is the first parameter. + * @param string $baz This is the second parameter. + * + * @return void + */ +public function variableOrderMismatch($bar, $baz, $foo) { + return; +} diff --git a/src/Standards/Squiz/Tests/Commenting/FunctionCommentUnitTest.inc.fixed b/src/Standards/Squiz/Tests/Commenting/FunctionCommentUnitTest.inc.fixed index 10e939709b..22474caf85 100644 --- a/src/Standards/Squiz/Tests/Commenting/FunctionCommentUnitTest.inc.fixed +++ b/src/Standards/Squiz/Tests/Commenting/FunctionCommentUnitTest.inc.fixed @@ -1054,3 +1054,78 @@ function throwCommentOneLine() {} * @return void */ function doublePipeFatalError(?stdClass $object) {} + +/** + * Test for passing variables by reference + * + * This sniff treats the '&' as optional for parameters passed by reference, but + * forbidden for parameters which are not passed by reference. + * + * Because mismatches may be in either direction, we cannot auto-fix these. + * + * @param string $foo A string passed in by reference. + * @param string &$bar A string passed in by reference. + * @param string $baz A string NOT passed in by reference. + * @param string &$qux A string NOT passed in by reference. + * @param string &$case1 A string passed in by reference with a case mismatch. + * @param string &$CASE2 A string NOT passed in by reference, also with a case mismatch. + * + * @return void + */ +public function variablesPassedByReference(&$foo, &$bar, $baz, $qux, &$CASE1, $case2) +{ + return; +} + +/** + * Test for param tag containing ref, but param in declaration not being by ref. + * + * @param string &$foo This should be flagged as (only) ParamNameUnexpectedAmpersandPrefix. + * @param string &$bar This should be flagged as (only) ParamNameNoMatch. + * @param string &$baz This should be flagged as (only) ParamNameNoCaseMatch. + * + * @return void + */ +function passedByRefMismatch($foo, $bra, $BAZ) { + return; +} + +/** + * Test variable case + * + * @param string $foo This parameter is lowercase. + * @param string $BAR This parameter is UPPERCASE. + * @param string $BazQux This parameter is TitleCase. + * @param string $corgeGrault This parameter is camelCase. + * @param string $GARPLY This parameter should be in lowercase. + * @param string $waldo This parameter should be in TitleCase. + * @param string $freD This parameter should be in UPPERCASE. + * @param string $PLUGH This parameter should be in TitleCase. + * + * @return void + */ +public function variableCaseTest( + $foo, + $BAR, + $BazQux, + $corgeGrault, + $garply, + $Waldo, + $FRED, + $PluGh +) { + return; +} + +/** + * Test variable order mismatch + * + * @param string $foo This is the third parameter. + * @param string $bar This is the first parameter. + * @param string $baz This is the second parameter. + * + * @return void + */ +public function variableOrderMismatch($bar, $baz, $foo) { + return; +} diff --git a/src/Standards/Squiz/Tests/Commenting/FunctionCommentUnitTest.php b/src/Standards/Squiz/Tests/Commenting/FunctionCommentUnitTest.php index 06ba08f72a..ff1d10c487 100644 --- a/src/Standards/Squiz/Tests/Commenting/FunctionCommentUnitTest.php +++ b/src/Standards/Squiz/Tests/Commenting/FunctionCommentUnitTest.php @@ -48,8 +48,7 @@ public function getErrorList() 138 => 4, 139 => 4, 143 => 2, - 152 => 1, - 155 => 2, + 155 => 1, 159 => 1, 166 => 1, 173 => 1, @@ -117,6 +116,22 @@ public function getErrorList() 1006 => 1, 1029 => 1, 1053 => 1, + 1058 => 2, + 1069 => 1, + 1070 => 1, + 1071 => 1, + 1080 => 2, + 1083 => 1, + 1084 => 1, + 1085 => 1, + 1093 => 4, + 1100 => 1, + 1101 => 1, + 1102 => 1, + 1103 => 1, + 1123 => 1, + 1124 => 1, + 1125 => 1, ]; // Scalar type hints only work from PHP 7 onwards. @@ -132,12 +147,16 @@ public function getErrorList() $errors[575] = 2; $errors[627] = 1; $errors[1002] = 1; + $errors[1075] = 6; + $errors[1089] = 3; + $errors[1107] = 8; + $errors[1129] = 3; } else { $errors[729] = 4; $errors[740] = 2; $errors[752] = 2; $errors[982] = 1; - } + }//end if // Object type hints only work from PHP 7.2 onwards. if (PHP_VERSION_ID >= 70200) { From 6c3f42a12f49d80de541f58213861af607fc9f85 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Tue, 11 Jul 2023 21:54:39 +0200 Subject: [PATCH 07/10] Changelog for #3807 --- package.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/package.xml b/package.xml index dadcb89a03..6a3601c043 100644 --- a/package.xml +++ b/package.xml @@ -71,6 +71,8 @@ http://pear.php.net/dtd/package-2.0.xsd"> - PSR-PER has been used to confirm the order of this keyword so it can be applied to PSR2 and PSR12 correctly -- Thanks to Juliette Reinders Folmer (@jrfnl) for the patch - Squiz.Formatting.OperatorBracket no longer reports false positives in match() structures + - Squiz.PHP.InnerFunctions sniff no longer reports on OO methods for OO structures declared within a function or closure + -- Thanks to @Daimona for the patch - Documentation has been added for the following sniffs: -- PSR2.Files.ClosingTag -- PSR2.Methods.FunctionCallSignature @@ -121,6 +123,8 @@ http://pear.php.net/dtd/package-2.0.xsd"> -- Thanks to Juliette Reinders Folmer (@jrfnl) for the patch - Fixed bug #3805 : Generic/FunctionCallArgumentSpacing: prevent fixer conflict over PHP 7.3+ trailing comma's in function calls -- Thanks to Juliette Reinders Folmer (@jrfnl) for the patch + - Fixed bug #3806 : Squiz.PHP.InnerFunctions sniff now correctly reports inner functions declared within a closure + -- Thanks to @Daimona for the patch - Fixed bug #3816 : PSR12/FileHeader: bug fix - false positives on PHP 8.2+ readonly classes -- Thanks to Juliette Reinders Folmer (@jrfnl) for the patch From 276f68cc74a3e4e1855bab6d01f0089337d00ae0 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Tue, 11 Jul 2023 22:18:21 +0200 Subject: [PATCH 08/10] Changelog for #3813 --- package.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/package.xml b/package.xml index 6a3601c043..0688cd6610 100644 --- a/package.xml +++ b/package.xml @@ -70,6 +70,8 @@ http://pear.php.net/dtd/package-2.0.xsd"> - PSR2 and PSR12 do not have documented rules for this as they pre-date the readonly modifier - PSR-PER has been used to confirm the order of this keyword so it can be applied to PSR2 and PSR12 correctly -- Thanks to Juliette Reinders Folmer (@jrfnl) for the patch + - Squiz/FunctionComment: new ParamNameUnexpectedAmpersandPrefix error for parameters annotated as passed by reference while the parameter is not passed by reference + -- Thanks to Dan Wallis (@fredden) for the patch - Squiz.Formatting.OperatorBracket no longer reports false positives in match() structures - Squiz.PHP.InnerFunctions sniff no longer reports on OO methods for OO structures declared within a function or closure -- Thanks to @Daimona for the patch @@ -125,6 +127,8 @@ http://pear.php.net/dtd/package-2.0.xsd"> -- Thanks to Juliette Reinders Folmer (@jrfnl) for the patch - Fixed bug #3806 : Squiz.PHP.InnerFunctions sniff now correctly reports inner functions declared within a closure -- Thanks to @Daimona for the patch + - Fixed bug #3813 : Squiz/FunctionComment: false positive for parameter name mismatch on parameters annotated as passed by reference + -- Thanks to Dan Wallis (@fredden) for the patch - Fixed bug #3816 : PSR12/FileHeader: bug fix - false positives on PHP 8.2+ readonly classes -- Thanks to Juliette Reinders Folmer (@jrfnl) for the patch From b8d7e94fe41708c3b2d10f72d515fb56723176c9 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Fri, 14 Jul 2023 08:20:15 +0200 Subject: [PATCH 09/10] Changelog for #3717 --- package.xml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/package.xml b/package.xml index 0688cd6610..8fbb8961ba 100644 --- a/package.xml +++ b/package.xml @@ -70,7 +70,7 @@ http://pear.php.net/dtd/package-2.0.xsd"> - PSR2 and PSR12 do not have documented rules for this as they pre-date the readonly modifier - PSR-PER has been used to confirm the order of this keyword so it can be applied to PSR2 and PSR12 correctly -- Thanks to Juliette Reinders Folmer (@jrfnl) for the patch - - Squiz/FunctionComment: new ParamNameUnexpectedAmpersandPrefix error for parameters annotated as passed by reference while the parameter is not passed by reference + - Squiz.Commenting.FunctionComment: new ParamNameUnexpectedAmpersandPrefix error for parameters annotated as passed by reference while the parameter is not passed by reference -- Thanks to Dan Wallis (@fredden) for the patch - Squiz.Formatting.OperatorBracket no longer reports false positives in match() structures - Squiz.PHP.InnerFunctions sniff no longer reports on OO methods for OO structures declared within a function or closure @@ -103,6 +103,8 @@ http://pear.php.net/dtd/package-2.0.xsd"> - Fixed bug #3672 : Incorrect ScopeIndent.IncorrectExact report for match inside array literal - Fixed bug #3694 : Generic.WhiteSpace.SpreadOperatorSpacingAfter does not ignore spread operator in PHP 8.1 first class callables -- Thanks to Juliette Reinders Folmer (@jrfnl) for the patch + - Fixed bug #3717 : Squiz.Commenting.FunctionComment: fixed false positive for InvalidNoReturn when type is never + -- Thanks to Choraimy Kroonstuiver (@axlon) for the patch - Fixed bug #3722 : Potential "Uninitialized string offset 1" in octal notation backfill -- Thanks to Juliette Reinders Folmer (@jrfnl) for the patch - Fixed bug #3728 : PHP 8.2 | PSR1/SideEffects: allow for readonly classes @@ -113,7 +115,7 @@ http://pear.php.net/dtd/package-2.0.xsd"> -- Thanks to Juliette Reinders Folmer (@jrfnl) for the patch - Fixed bug #3779 : Squiz/LowercasePHPFunctions + Generic/ForbiddenFunctions: bug fix for class names in attributes -- Thanks to Juliette Reinders Folmer (@jrfnl) for the patch - - Fixed bug #3785 : Squiz/FunctionComment: potential "Uninitialized string offset 0" when a type contains a duplicate pipe symbol + - Fixed bug #3785 : Squiz.Commenting.FunctionComment: potential "Uninitialized string offset 0" when a type contains a duplicate pipe symbol -- Thanks to Dan Wallis (@fredden) for the patch - Fixed bug #3787 : PEAR/Squiz/[MultiLine]FunctionDeclaration: allow for PHP 8.1 new in initializers -- Thanks to Juliette Reinders Folmer (@jrfnl) for the patch @@ -127,7 +129,7 @@ http://pear.php.net/dtd/package-2.0.xsd"> -- Thanks to Juliette Reinders Folmer (@jrfnl) for the patch - Fixed bug #3806 : Squiz.PHP.InnerFunctions sniff now correctly reports inner functions declared within a closure -- Thanks to @Daimona for the patch - - Fixed bug #3813 : Squiz/FunctionComment: false positive for parameter name mismatch on parameters annotated as passed by reference + - Fixed bug #3813 : Squiz.Commenting.FunctionComment: false positive for parameter name mismatch on parameters annotated as passed by reference -- Thanks to Dan Wallis (@fredden) for the patch - Fixed bug #3816 : PSR12/FileHeader: bug fix - false positives on PHP 8.2+ readonly classes -- Thanks to Juliette Reinders Folmer (@jrfnl) for the patch From 354b4c5ee114a9d10b72f6d311d5d18152162ad0 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sun, 16 Jul 2023 12:58:04 +0200 Subject: [PATCH 10/10] Changelog: remove 3.7.2 entries from 3.8.0 changelog ... and update the version number in the Config class. --- package.xml | 33 ++------------------------------- src/Config.php | 2 +- 2 files changed, 3 insertions(+), 32 deletions(-) diff --git a/package.xml b/package.xml index 8fbb8961ba..00ecd60554 100644 --- a/package.xml +++ b/package.xml @@ -17,8 +17,8 @@ http://pear.php.net/dtd/package-2.0.xsd"> 2022-06-18 - 3.7.2 - 3.7.2 + 3.8.0 + 3.8.0 stable @@ -41,11 +41,6 @@ http://pear.php.net/dtd/package-2.0.xsd"> -- Existing code will continue to work but will throw a deprecation error -- The backwards compatiblity layer will be removed in PHPCS 4.0 -- Thanks to Juliette Reinders Folmer (@jrfnl) for the patch - - Newer versions of Composer will now suggest installing PHPCS using require-dev instead of require - -- Thanks to Gary Jones (@GaryJones) for the patch - - A custom Out Of Memory error will now be shown if PHPCS or PHPCBF run out of memory during a run - -- Error message provides actionable information about how to fix the problem and ensures the error is not silent - -- Thanks to Juliette Reinders Folmer (@jrfnl) and Alain Schlesser (@schlessera) for the patch - When using auto report width (the default) a value of 80 columns will be used if an auto width cannot be determined -- Thanks to Juliette Reinders Folmer (@jrfnl) for the patch - Sniff error messages are now more informative to help bugs get reported to the correct project @@ -64,15 +59,12 @@ http://pear.php.net/dtd/package-2.0.xsd"> -- Squiz.Commenting.FileComment -- Squiz.Commenting.InlineComment -- Thanks to Juliette Reinders Folmer (@jrfnl) for the patch - - Generic.PHP.LowerCaseType sniff now correctly examines types inside arrow functions - -- Thanks to Juliette Reinders Folmer (@jrfnl) for the patch - PSR2.Classes.PropertyDeclaration now enforces that the readonly modifier comes after the visibility modifier - PSR2 and PSR12 do not have documented rules for this as they pre-date the readonly modifier - PSR-PER has been used to confirm the order of this keyword so it can be applied to PSR2 and PSR12 correctly -- Thanks to Juliette Reinders Folmer (@jrfnl) for the patch - Squiz.Commenting.FunctionComment: new ParamNameUnexpectedAmpersandPrefix error for parameters annotated as passed by reference while the parameter is not passed by reference -- Thanks to Dan Wallis (@fredden) for the patch - - Squiz.Formatting.OperatorBracket no longer reports false positives in match() structures - Squiz.PHP.InnerFunctions sniff no longer reports on OO methods for OO structures declared within a function or closure -- Thanks to @Daimona for the patch - Documentation has been added for the following sniffs: @@ -82,27 +74,6 @@ http://pear.php.net/dtd/package-2.0.xsd"> -- Thanks to Atsushi Okui (@blue32a) for the patch - Fixed bug #3557 : Squiz.Arrays.ArrayDeclaration will now ignore PHP 7.4 array unpacking when determining whether an array is associative -- Thanks to Volker Dusch (@edorian) for the patch - - Fixed bug #3616 : Squiz.PHP.DisallowComparisonAssignment false positive for PHP 8 match expression - -- Thanks to Juliette Reinders Folmer (@jrfnl) for the patch - - Fixed bug #3618 : Generic.WhiteSpace.ArbitraryParenthesesSpacing false positive for return new parent() - -- Thanks to Juliette Reinders Folmer (@jrfnl) for the patch - - Fixed bug #3632 : Short list not tokenized correctly in control structures without braces - -- Thanks to Juliette Reinders Folmer (@jrfnl) for the patch - - Fixed bug #3639 : Tokenizer not applying tab replacement to heredoc/nowdoc closers - -- Thanks to Juliette Reinders Folmer (@jrfnl) for the patch - - Fixed bug #3640 : Generic.WhiteSpace.DisallowTabIndent not reporting errors for PHP 7.3 flexible heredoc/nowdoc syntax - -- Thanks to Juliette Reinders Folmer (@jrfnl) for the patch - - Fixed bug #3645 : PHPCS can show 0 exit code when running in parallel even if child process has fatal error - -- Thanks to Alex Panshin (@enl) for the patch - - Fixed bug #3653 : False positives for match() in OperatorSpacingSniff - -- Thanks to Jaroslav HanslĂ­k (@kukulich) for the patch - - Fixed bug #3666 : PEAR.Functions.FunctionCallSignature incorrect indent fix when checking mixed HTML/PHP files - - Fixed bug #3668 : PSR12.Classes.ClassInstantiation.MissingParentheses false positive when instantiating parent classes - -- Similar issues also fixed in Generic.Functions.FunctionCallArgumentSpacing and Squiz.Formatting.OperatorBracket - -- Thanks to Juliette Reinders Folmer (@jrfnl) for the patch - - Fixed bug #3672 : Incorrect ScopeIndent.IncorrectExact report for match inside array literal - - Fixed bug #3694 : Generic.WhiteSpace.SpreadOperatorSpacingAfter does not ignore spread operator in PHP 8.1 first class callables - -- Thanks to Juliette Reinders Folmer (@jrfnl) for the patch - Fixed bug #3717 : Squiz.Commenting.FunctionComment: fixed false positive for InvalidNoReturn when type is never -- Thanks to Choraimy Kroonstuiver (@axlon) for the patch - Fixed bug #3722 : Potential "Uninitialized string offset 1" in octal notation backfill diff --git a/src/Config.php b/src/Config.php index 8d3fb173e6..1ae4c77ee3 100644 --- a/src/Config.php +++ b/src/Config.php @@ -80,7 +80,7 @@ class Config * * @var string */ - const VERSION = '3.7.2'; + const VERSION = '3.8.0'; /** * Package stability; either stable, beta or alpha.