diff --git a/CakePHP/Sniffs/Commenting/FunctionCommentSniff.php b/CakePHP/Sniffs/Commenting/FunctionCommentSniff.php index c6a3fa2..af61743 100644 --- a/CakePHP/Sniffs/Commenting/FunctionCommentSniff.php +++ b/CakePHP/Sniffs/Commenting/FunctionCommentSniff.php @@ -62,12 +62,14 @@ public function process(File $phpcsFile, $stackPtr) null, ); if ($docCommentEnd === false || $tokens[$docCommentEnd]['code'] !== T_DOC_COMMENT_CLOSE_TAG) { - $phpcsFile->addError( - 'Missing doc comment for function %s()', - $stackPtr, - 'Missing', - [$phpcsFile->getDeclarationName($stackPtr)], - ); + if (!$this->hasFullNativeTypes($phpcsFile, $stackPtr)) { + $phpcsFile->addError( + 'Missing doc comment for function %s()', + $stackPtr, + 'Missing', + [$phpcsFile->getDeclarationName($stackPtr)], + ); + } return; } @@ -107,6 +109,38 @@ public function process(File $phpcsFile, $stackPtr) $this->processThrows($phpcsFile, $stackPtr, $commentStart); } + /** + * Checks whether the function has a native return type (or is a constructor) + * and every parameter has a native type declaration. A docblock is considered + * redundant in that case since all type information is already expressed in + * the signature. + * + * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. + * @param int $stackPtr The position of the current token in the stack passed in $tokens. + * @return bool + */ + protected function hasFullNativeTypes(File $phpcsFile, int $stackPtr): bool + { + $name = $phpcsFile->getDeclarationName($stackPtr); + $isConstructor = strtolower((string)$name) === '__construct'; + + if (!$isConstructor) { + $properties = $phpcsFile->getMethodProperties($stackPtr); + if (($properties['return_type'] ?? '') === '') { + return false; + } + } + + $parameters = $phpcsFile->getMethodParameters($stackPtr); + foreach ($parameters as $parameter) { + if (($parameter['type_hint'] ?? '') === '') { + return false; + } + } + + return true; + } + /** * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. * @param int $stackPtr The position of the current token in the stack passed in $tokens. diff --git a/CakePHP/Tests/Commenting/FunctionCommentUnitTest.1.inc b/CakePHP/Tests/Commenting/FunctionCommentUnitTest.1.inc index 0b9cb19..7d50943 100644 --- a/CakePHP/Tests/Commenting/FunctionCommentUnitTest.1.inc +++ b/CakePHP/Tests/Commenting/FunctionCommentUnitTest.1.inc @@ -97,4 +97,22 @@ class Foo throw new \RuntimeException(); return; } + + public function fullyTyped(int $a, string $b): void + { + } + + public function __construct( + public readonly int $id, + public readonly string $name, + ) { + } + + public function noReturnType(int $a) + { + } + + public function missingParamType($a): void + { + } } diff --git a/CakePHP/Tests/Commenting/FunctionCommentUnitTest.php b/CakePHP/Tests/Commenting/FunctionCommentUnitTest.php index ec95273..c2ee09d 100644 --- a/CakePHP/Tests/Commenting/FunctionCommentUnitTest.php +++ b/CakePHP/Tests/Commenting/FunctionCommentUnitTest.php @@ -20,6 +20,8 @@ public function getErrorList($testFile = '') 41 => 1, 50 => 1, 58 => 1, + 111 => 1, + 115 => 1, ]; default: