Skip to content

Commit

Permalink
Merge pull request #329 from Yoast/JRF/yoastcs-codecoverageignoredepr…
Browse files Browse the repository at this point in the history
…ecated-various-improvements

Commenting/CodeCoverageIgnoreDeprecated: apply rule to OO docblocks too + small other improvements
  • Loading branch information
jrfnl authored Nov 4, 2023
2 parents 4630432 + 66ee5cb commit ae39773
Show file tree
Hide file tree
Showing 5 changed files with 225 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
>
<standard>
<![CDATA[
Deprecated functions and methods should be ignored for code coverage calculations.
Deprecated OO structures, functions and methods should be ignored for code coverage calculations.
]]>
</standard>
<code_comparison>
Expand Down
29 changes: 19 additions & 10 deletions Yoast/Sniffs/Commenting/CodeCoverageIgnoreDeprecatedSniff.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\Sniff;
use PHP_CodeSniffer\Util\Tokens;
use PHPCSUtils\Tokens\Collections;

/**
* Verifies functions which are marked as `deprecated` have a `codeCoverageIgnore` tag
* Verifies functions/OO structures which are marked as `deprecated` have a `codeCoverageIgnore` tag
* in their docblock.
*
* @since 1.1.0
* @since 3.0.0 Not just checks function docblocks, but also class/OO docblocks.
*/
final class CodeCoverageIgnoreDeprecatedSniff implements Sniff {

Expand All @@ -20,9 +22,13 @@ final class CodeCoverageIgnoreDeprecatedSniff implements Sniff {
* @return array<int|string>
*/
public function register() {
return [
\T_FUNCTION,
];
$targets = Tokens::$ooScopeTokens;
// Ignore interfaces as they can't contain code. Ignore anon classes as they are normally nested in another construct.
unset( $targets[ \T_ANON_CLASS ], $targets[ \T_INTERFACE ] );

$targets[ \T_FUNCTION ] = \T_FUNCTION;

return $targets;
}

/**
Expand All @@ -37,17 +43,20 @@ public function process( File $phpcsFile, $stackPtr ) {

$tokens = $phpcsFile->getTokens();

$ignore = Tokens::$methodPrefixes;
if ( $tokens[ $stackPtr ]['code'] === \T_FUNCTION ) {
$ignore = Tokens::$methodPrefixes;
}
else {
$ignore = Collections::classModifierKeywords();
}
$ignore[ \T_WHITESPACE ] = \T_WHITESPACE;

for ( $commentEnd = ( $stackPtr - 1 ); $commentEnd >= 0; $commentEnd-- ) {
if ( isset( $ignore[ $tokens[ $commentEnd ]['code'] ] ) === true ) {
continue;
}

if ( $tokens[ $commentEnd ]['code'] === \T_ATTRIBUTE_END
&& isset( $tokens[ $commentEnd ]['attribute_opener'] ) === true
) {
if ( isset( $tokens[ $commentEnd ]['attribute_opener'] ) === true ) {
$commentEnd = $tokens[ $commentEnd ]['attribute_opener'];
continue;
}
Expand All @@ -71,7 +80,7 @@ public function process( File $phpcsFile, $stackPtr ) {
}

if ( $deprecated === false ) {
// Not a deprecated function.
// Not a deprecated function/OO structure.
return;
}

Expand All @@ -91,7 +100,7 @@ public function process( File $phpcsFile, $stackPtr ) {
$hasTagAsString = $phpcsFile->findNext( \T_DOC_COMMENT_STRING, ( $commentStart + 1 ), $commentEnd, false, 'codeCoverageIgnore' );
if ( $hasTagAsString !== false ) {
$prev = $phpcsFile->findPrevious( \T_DOC_COMMENT_WHITESPACE, ( $hasTagAsString - 1 ), $commentStart, true );
if ( $prev !== false && $tokens[ $prev ]['code'] === \T_DOC_COMMENT_STAR ) {
if ( $tokens[ $prev ]['code'] === \T_DOC_COMMENT_STAR ) {
$fix = $phpcsFile->addFixableError(
'The `codeCoverageIgnore` annotation in the function docblock needs to be prefixed with an `@`.',
$hasTagAsString,
Expand Down
99 changes: 96 additions & 3 deletions Yoast/Tests/Commenting/CodeCoverageIgnoreDeprecatedUnitTest.inc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

class SomeThing {
abstract class SomeThing {

/**
* Active (non-deprecated) function.
Expand Down Expand Up @@ -47,12 +47,12 @@ class SomeThing {
*
* This is a sentence containing the phrase codeCoverageIgnore, but should not be regarded as the tag.
*/
static protected function missingStaticCodeCoverageIgnore() {}
final static protected function missingStaticCodeCoverageIgnore() {}

/**
* @deprecated x.x
*/
public function missingCodeCoverageIgnore() {}
public abstract function missingCodeCoverageIgnore();

/**
* @deprecated x.x
Expand Down Expand Up @@ -89,3 +89,96 @@ class SomeThing {
#[fietsbel /*comment*/]
public function inlineCommentWithinAttribute() {}
}

/**
* Description.
*
* @deprecated
*/
class C_IsDeprecatedNotIgnored {}

/**
* Description.
*
* @deprecated
*/
abstract class C_IsDeprecatedNotIgnoredAbstract {}

/**
* Description.
*
* @deprecated
*/
#[AllowDynamicProperties]
final class C_IsDeprecatedNotIgnoredFinal {}

/**
* Description.
*
* @deprecated
*/
readonly class C_IsDeprecatedNotIgnoredReadonly {}

/**
* Description.
*
* @deprecated
*/
final readonly class C_IsDeprecatedNotIgnoredFinalReadonly {}

/**
* Description.
*
* @codeCoverageIgnore
* @deprecated
*/
readonly final class C_IsDeprecatedAndIgnored {}

/**
* @deprecated
*/
#[MyAttribute, AnotherAttribute]
interface I_IsDeprecatedNotIgnored {}

/**
* @codeCoverageIgnore
* @deprecated
*/
interface I_IsDeprecatedAndIgnored {}

/**
* Description.
*
* @deprecated
*/
trait T_IsDeprecatedNotIgnored {}

/**
* @deprecated
* codeCoverageIgnore
*/
trait T_IsDeprecatedAndIgnored {}

/**
* @deprecated
*/
enum E_IsDeprecatedNotIgnored {}

/**
* Description.
*
* @deprecated
* @codeCoverageIgnore
*/
enum E_IsDeprecatedAndIgnored {}

/**
* Not necessarily correct, but as this is an anomymous class, this won't be flagged
* same as closures/arrow functions won't be flagged.
*
* @deprecated
*/
$anon = new
#[AllowDynamicProperties]
#[AnotherAttribute([1, 2, 3])]
class {};
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

class SomeThing {
abstract class SomeThing {

/**
* Active (non-deprecated) function.
Expand Down Expand Up @@ -47,12 +47,12 @@ class SomeThing {
*
* This is a sentence containing the phrase codeCoverageIgnore, but should not be regarded as the tag.
*/
static protected function missingStaticCodeCoverageIgnore() {}
final static protected function missingStaticCodeCoverageIgnore() {}

/**
* @deprecated x.x
*/
public function missingCodeCoverageIgnore() {}
public abstract function missingCodeCoverageIgnore();

/**
* @deprecated x.x
Expand Down Expand Up @@ -89,3 +89,96 @@ class SomeThing {
#[fietsbel /*comment*/]
public function inlineCommentWithinAttribute() {}
}

/**
* Description.
*
* @deprecated
*/
class C_IsDeprecatedNotIgnored {}

/**
* Description.
*
* @deprecated
*/
abstract class C_IsDeprecatedNotIgnoredAbstract {}

/**
* Description.
*
* @deprecated
*/
#[AllowDynamicProperties]
final class C_IsDeprecatedNotIgnoredFinal {}

/**
* Description.
*
* @deprecated
*/
readonly class C_IsDeprecatedNotIgnoredReadonly {}

/**
* Description.
*
* @deprecated
*/
final readonly class C_IsDeprecatedNotIgnoredFinalReadonly {}

/**
* Description.
*
* @codeCoverageIgnore
* @deprecated
*/
readonly final class C_IsDeprecatedAndIgnored {}

/**
* @deprecated
*/
#[MyAttribute, AnotherAttribute]
interface I_IsDeprecatedNotIgnored {}

/**
* @codeCoverageIgnore
* @deprecated
*/
interface I_IsDeprecatedAndIgnored {}

/**
* Description.
*
* @deprecated
*/
trait T_IsDeprecatedNotIgnored {}

/**
* @deprecated
* @codeCoverageIgnore
*/
trait T_IsDeprecatedAndIgnored {}

/**
* @deprecated
*/
enum E_IsDeprecatedNotIgnored {}

/**
* Description.
*
* @deprecated
* @codeCoverageIgnore
*/
enum E_IsDeprecatedAndIgnored {}

/**
* Not necessarily correct, but as this is an anomymous class, this won't be flagged
* same as closures/arrow functions won't be flagged.
*
* @deprecated
*/
$anon = new
#[AllowDynamicProperties]
#[AnotherAttribute([1, 2, 3])]
class {};
18 changes: 13 additions & 5 deletions Yoast/Tests/Commenting/CodeCoverageIgnoreDeprecatedUnitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,19 @@ final class CodeCoverageIgnoreDeprecatedUnitTest extends AbstractSniffUnitTest {
*/
public function getErrorList(): array {
return [
41 => 1,
50 => 1,
55 => 1,
69 => 1,
90 => 1,
41 => 1,
50 => 1,
55 => 1,
69 => 1,
90 => 1,
98 => 1,
105 => 1,
113 => 1,
120 => 1,
127 => 1,
154 => 1,
158 => 1,
165 => 1,
];
}

Expand Down

0 comments on commit ae39773

Please sign in to comment.