diff --git a/coder_sniffer/Drupal/Sniffs/Commenting/FunctionCommentSniff.php b/coder_sniffer/Drupal/Sniffs/Commenting/FunctionCommentSniff.php index 4aec57de..ef8130c9 100644 --- a/coder_sniffer/Drupal/Sniffs/Commenting/FunctionCommentSniff.php +++ b/coder_sniffer/Drupal/Sniffs/Commenting/FunctionCommentSniff.php @@ -482,7 +482,7 @@ protected function processParams(File $phpcsFile, $stackPtr, $commentStart) $commentLines = []; if ($tokens[($tag + 2)]['code'] === T_DOC_COMMENT_STRING) { $matches = []; - preg_match('/([^$&]*)(?:((?:\$|&)[^\s]+)(?:(\s+)(.*))?)?/', $tokens[($tag + 2)]['content'], $matches); + preg_match('/((?:(?![$.]|&(?=\$)).)*)(?:((?:\.\.\.)?(?:\$|&)[^\s]+)(?:(\s+)(.*))?)?/', $tokens[($tag + 2)]['content'], $matches); $typeLen = strlen($matches[1]); $type = trim($matches[1]); @@ -618,7 +618,7 @@ protected function processParams(File $phpcsFile, $stackPtr, $commentStart) $variableArguments = true; } - if ($typeLen === 0) { + if ($typeLen === 0 && $variableArguments === false) { $error = 'Missing parameter type'; // If there is just one word as comment at the end of the line // then this is probably the data type. Move it before the @@ -677,8 +677,11 @@ protected function processParams(File $phpcsFile, $stackPtr, $commentStart) while (isset($realParams[($checkPos)]) === true) { $realName = $realParams[$checkPos]['name']; - if ($realName === $param['var'] || ($realParams[$checkPos]['pass_by_reference'] === true + if ($realName === $param['var'] + || ($realParams[$checkPos]['pass_by_reference'] === true && ('&'.$realName) === $param['var']) + || ($realParams[$checkPos]['variable_length'] === true + && ('...'.$realName) === $param['var']) ) { $matched = true; break; @@ -923,7 +926,7 @@ public static function suggestType($type) // Also allow some more characters for special type hints supported by // PHPStan: // https://phpstan.org/writing-php-code/phpdoc-types#basic-types . - $type = preg_replace('/[^a-zA-Z0-9_\\\[\]\-<> ,"\{\}\?\':\*]/', '', $type); + $type = preg_replace('/[^a-zA-Z0-9_\\\[\]\-<> ,"\{\}\?\':\*\|\&]/', '', $type); return $type; diff --git a/tests/Drupal/Commenting/FunctionCommentUnitTest.inc b/tests/Drupal/Commenting/FunctionCommentUnitTest.inc index e434e04b..5c48b6d4 100644 --- a/tests/Drupal/Commenting/FunctionCommentUnitTest.inc +++ b/tests/Drupal/Commenting/FunctionCommentUnitTest.inc @@ -903,3 +903,16 @@ function test_return_non_falsy_string(): string { function test_return_literal_string(): string { return ''; } + +/** + * PHP 8 intersection types are ok. + * + * @param Foo&Bar $a + * Intersection type parameter. + * + * @return Foo&Bar + * Intersection type return declaration. + */ +function test_intersection_types(Foo&Bar $a): Foo&Bar { + return new Xyz(); +} diff --git a/tests/Drupal/Commenting/FunctionCommentUnitTest.inc.fixed b/tests/Drupal/Commenting/FunctionCommentUnitTest.inc.fixed index 63575556..f9308b2d 100644 --- a/tests/Drupal/Commenting/FunctionCommentUnitTest.inc.fixed +++ b/tests/Drupal/Commenting/FunctionCommentUnitTest.inc.fixed @@ -929,3 +929,16 @@ function test_return_non_falsy_string(): string { function test_return_literal_string(): string { return ''; } + +/** + * PHP 8 intersection types are ok. + * + * @param Foo&Bar $a + * Intersection type parameter. + * + * @return Foo&Bar + * Intersection type return declaration. + */ +function test_intersection_types(Foo&Bar $a): Foo&Bar { + return new Xyz(); +}