Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add sniff for 'void' in @return tags #1240

Open
wants to merge 15 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions WordPress-Docs/ruleset.xml
Original file line number Diff line number Diff line change
Expand Up @@ -116,4 +116,6 @@
<!-- WP allows @todo's in comments -->
<exclude name="Generic.Commenting.Todo.TaskFound"/>
</rule>

<rule ref="WordPress.Commenting.NoReturnVoid"/>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A comment could be added here referencing the handbook rule that this sniff relates to.

</ruleset>
100 changes: 100 additions & 0 deletions WordPress/Sniffs/Commenting/NoReturnVoidSniff.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<?php
/**
* WordPress Coding Standard.
*
* @package WPCS\WordPressCodingStandards
* @link https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards
* @license https://opensource.org/licenses/MIT MIT
*/

namespace WordPress\Sniffs\Commenting;

use WordPress\Sniff;
use PHP_CodeSniffer_Tokens as Tokens;

/**
* Disallows the 'void' return type.
*
* @link https://make.wordpress.org/core/handbook/best-practices/inline-documentation-standards/php/#phpdoc-tags
*
* @package WPCS\WordPressCodingStandards
*
* @since X.Y.Z
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The version number will end up being 0.16.0 (0.15.0 is going to be dedicated to just renaming some things).

*/
class NoReturnVoidSniff extends Sniff {

/**
* Registers the tokens that this sniff wants to listen for.
*
* @return array
*/
public function register() {
return array( T_FUNCTION );
}

/**
* Processes this test when one of its tokens is encountered.
*
* @param int $stackPtr The position of the current token in the stack.
* @return int Integer stack pointer to skip the rest of the file.
*/
public function process_token( $stackPtr ) {
$commentEnd = $this->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'];

$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] ) );

foreach ( $returnTypes as $type ) {
if ( 'void' === $type ) {
$this->phpcsFile->addError(
sprintf( '`@return void` should not be used outside of the default bundled themes', $type ),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sprintf() is unnecessary here, since the message doesn't contain any placeholders.

Also, I think that perhaps the message should be simplified to just be something like @return void should not be used. I don't think it is necessary to mention the exception for the bundled themes.

Perhaps the message should include something like "null should be used instead, if needed, or the @return tag should be omitted".

$returnTag,
'ReturnVoidFound'
);

break;
}
}
}

}
49 changes: 49 additions & 0 deletions WordPress/Tests/Commenting/NoReturnVoidUnitTest.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php
/**
* Return types should not be void.
*
* @return void
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For thoroughness, it would be good to add some tests that also include a comment:

 * @return void Nothing.

*/
function no_return_void() {
echo 'test';
}

/**
* Return types should not be void.
*
* @return void|string
*/
function no_return_void_string() {
echo 'test';
}

/**
* Return types should not be void.
*
* @return string|void
*/
function no_return_string_void() {
echo 'test';
}

/**
* Return types should not be void.
*
* @return array|string|void
*/
function no_return_array_string_void() {
echo 'test';
}

/**
* Return types should not be void.
*
* @return string
*/
function return_string() {
if ( foo() ) {
return 'bar';
}

echo 'test';
}
46 changes: 46 additions & 0 deletions WordPress/Tests/Commenting/NoReturnVoidUnitTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php
/**
* Unit test class for WordPress Coding Standard.
*
* @package WPCS\WordPressCodingStandards
* @link https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards
* @license https://opensource.org/licenses/MIT MIT
*/

namespace WordPress\Tests\Commenting;

use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest;

/**
* Unit test class for the NoReturnVoid sniff.
*
* @package WPCS\WordPressCodingStandards
*
* @since X.Y.Z
*/
class NoReturnVoidUnitTest extends AbstractSniffUnitTest {

/**
* Returns the lines where errors should occur.
*
* @return array <int line number> => <int number of errors>
*/
public function getErrorList() {
return array(
5 => 1,
14 => 1,
23 => 1,
32 => 1,
);
}

/**
* Returns the lines where warnings should occur.
*
* @return array <int line number> => <int number of warnings>
*/
public function getWarningList() {
return array();
}

} // End class.