diff --git a/WordPress-Docs/ruleset.xml b/WordPress-Docs/ruleset.xml index 05f0ec87db..00eed4a0ce 100644 --- a/WordPress-Docs/ruleset.xml +++ b/WordPress-Docs/ruleset.xml @@ -116,4 +116,7 @@ + + + diff --git a/WordPress/Sniffs/Commenting/FunctionCommentSniff.php b/WordPress/Sniffs/Commenting/FunctionCommentSniff.php new file mode 100755 index 0000000000..b8b6389724 --- /dev/null +++ b/WordPress/Sniffs/Commenting/FunctionCommentSniff.php @@ -0,0 +1,110 @@ +phpcsFile->findPrevious( + array_merge( Tokens::$methodPrefixes, array( T_WHITESPACE ) ), + ( $stackPtr - 1 ), + null, + true + ); + + if ( T_DOC_COMMENT_CLOSE_TAG !== $this->tokens[ $commentEnd ]['code'] ) { + // Invalid function comment. Handled elsewhere. + return; + } + + $commentStart = $this->tokens[ $commentEnd ]['comment_opener']; + + $this->process_return( $stackPtr, $commentStart ); + } + + /** + * Process this function's return comment. + * + * @param int $stackPtr The position of the current token in the stack. + * @param int $commentStart The position in the stack where the comment started. + * @return void + */ + protected function process_return( $stackPtr, $commentStart ) { + $returnTag = null; + + foreach ( $this->tokens[ $commentStart ]['comment_tags'] as $tag ) { + if ( '@return' === $this->tokens[ $tag ]['content'] ) { + $returnTag = $tag; + // Multiple return tags are invalid, but flagged elsewhere. + break; + } + } + + if ( ! $returnTag ) { + return; + } + + $returnCommentPtr = ( $returnTag + 2 ); + $returnComment = $this->tokens[ $returnCommentPtr ]; + + if ( empty( $returnComment['content'] ) || T_DOC_COMMENT_STRING !== $returnComment['code'] ) { + // Invalid return comment. Handled elsewhere. + return; + } + + // Extracted from PHP_CodeSniffer\Standards\Squiz\Sniffs\Commenting\FunctionCommentSniff::processReturn(). + preg_match( '`^((?:\|?(?:array\([^\)]*\)|[\\\\a-z0-9\[\]]+))*)( .*)?`i', $returnComment['content'], $commentParts ); + + if ( empty( $commentParts[1] ) ) { + return; + } + + $returnTypes = array_unique( explode( '|', $commentParts[1] ) ); + + /* + * Disallow `@return void`. + * See https://make.wordpress.org/core/handbook/best-practices/inline-documentation-standards/php/#phpdoc-tags. + */ + if ( array( 'void' ) === $returnTypes ) { + $this->phpcsFile->addError( + '`@return void` should not be used. Omit the `@return` tag instead', + $returnTag, + 'NoReturnVoid' + ); + } + } + +} diff --git a/WordPress/Tests/Commenting/FunctionCommentUnitTest.inc b/WordPress/Tests/Commenting/FunctionCommentUnitTest.inc new file mode 100755 index 0000000000..d90b88cd8f --- /dev/null +++ b/WordPress/Tests/Commenting/FunctionCommentUnitTest.inc @@ -0,0 +1,51 @@ + => + */ + public function getErrorList() { + return array( + 5 => 1, + 14 => 1, + ); + } + + /** + * Returns the lines where warnings should occur. + * + * @return array => + */ + public function getWarningList() { + return array(); + } + +} // End class. diff --git a/bin/phpcs.xml b/bin/phpcs.xml index 89152ebfee..2a27766e55 100644 --- a/bin/phpcs.xml +++ b/bin/phpcs.xml @@ -18,7 +18,10 @@ - + + + +