Skip to content

Commit

Permalink
BCFile::getDeclarationName(): sync with upstream
Browse files Browse the repository at this point in the history
Follow up on 451

Upstream PR squizlabs/PHP_CodeSniffer 3797, which will be included in PHPCS 3.8.0, fixes a tokenizer issue which affected the `File::getDeclarationName()` and, by extension, the `BackCompat::getDeclarationName()` method.

The function name for functions named `self`, `parent` or `static` and declared to return by reference, could previously not be retrieved.

The PHPCSUtils native version of the method `ObjectDeclarations::getName()` already handled things correctly.

This commit adds back the BC-layer for the `getDeclarationName()` method and polyfills the fix from PHPCS 3.8.0 to backport it for PHPCS < 3.8.0.

As the methods will now handle these functions in the same way, this commit also moves the related tests from the `GetNameDiffTest` to the `GetDeclarationNameTest`.
  • Loading branch information
jrfnl committed Jul 16, 2023
1 parent 3466697 commit d16f825
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 23 deletions.
42 changes: 40 additions & 2 deletions PHPCSUtils/BackCompat/BCFile.php
Expand Up @@ -50,6 +50,7 @@
* any affected utility functions:
* - `readonly` classes.
* - Constructor property promotion with `readonly` without visibility.
* - OO methods called `self`, `parent` or `static`.
*
* Most functions in this class will have a related twin-function in the relevant
* class in the `PHPCSUtils\Utils` namespace.
Expand All @@ -75,7 +76,7 @@ final class BCFile
*
* Changelog for the PHPCS native function:
* - Introduced in PHPCS 0.0.5.
* - The upstream method has received no significant updates since PHPCS 3.7.1.
* - PHPCS 3.8.0: OO methods called `self`, `parent` or `static` are now correctly recognized.
*
* @see \PHP_CodeSniffer\Files\File::getDeclarationName() Original source.
* @see \PHPCSUtils\Utils\ObjectDeclarations::getName() PHPCSUtils native improved version.
Expand All @@ -97,7 +98,44 @@ final class BCFile
*/
public static function getDeclarationName(File $phpcsFile, $stackPtr)
{
return $phpcsFile->getDeclarationName($stackPtr);
$tokens = $phpcsFile->getTokens();
$tokenCode = $tokens[$stackPtr]['code'];

if ($tokenCode === T_ANON_CLASS || $tokenCode === T_CLOSURE) {
return null;
}

if ($tokenCode !== T_FUNCTION
&& $tokenCode !== T_CLASS
&& $tokenCode !== T_INTERFACE
&& $tokenCode !== T_TRAIT
&& $tokenCode !== T_ENUM
) {
throw new RuntimeException('Token type "' . $tokens[$stackPtr]['type'] . '" is not T_FUNCTION, T_CLASS, T_INTERFACE, T_TRAIT or T_ENUM');
}

if ($tokenCode === T_FUNCTION
&& strtolower($tokens[$stackPtr]['content']) !== 'function'
) {
// This is a function declared without the "function" keyword.
// So this token is the function name.
return $tokens[$stackPtr]['content'];
}

$content = null;
for ($i = ($stackPtr + 1); $i < $phpcsFile->numTokens; $i++) {
if ($tokens[$i]['code'] === T_STRING
// BC: PHPCS < 3.8.0.
|| $tokens[$i]['code'] === T_SELF
|| $tokens[$i]['code'] === T_PARENT
|| $tokens[$i]['code'] === T_STATIC
) {
$content = $tokens[$i]['content'];
break;
}
}

return $content;
}

/**
Expand Down
9 changes: 9 additions & 0 deletions Tests/BackCompat/BCFile/GetDeclarationNameTest.inc
Expand Up @@ -88,6 +88,15 @@ enum Suit: int implements Colorful, CardGame {}
/* testFunctionReturnByRefWithReservedKeywordEach */
function &each() {}

/* testFunctionReturnByRefWithReservedKeywordParent */
function &parent() {}

/* testFunctionReturnByRefWithReservedKeywordSelf */
function &self() {}

/* testFunctionReturnByRefWithReservedKeywordStatic */
function &static() {}

/* testLiveCoding */
// Intentional parse error. This has to be the last test in the file.
function // Comment.
12 changes: 12 additions & 0 deletions Tests/BackCompat/BCFile/GetDeclarationNameTest.php
Expand Up @@ -196,6 +196,18 @@ public static function dataGetDeclarationName()
'/* testFunctionReturnByRefWithReservedKeywordEach */',
'each',
],
'function-return-by-reference-with-reserved-keyword-parent' => [
'/* testFunctionReturnByRefWithReservedKeywordParent */',
'parent',
],
'function-return-by-reference-with-reserved-keyword-self' => [
'/* testFunctionReturnByRefWithReservedKeywordSelf */',
'self',
],
'function-return-by-reference-with-reserved-keyword-static' => [
'/* testFunctionReturnByRefWithReservedKeywordStatic */',
'static',
],
];
}
}
9 changes: 0 additions & 9 deletions Tests/Utils/ObjectDeclarations/GetNameDiffTest.inc
Expand Up @@ -12,15 +12,6 @@ interface switch{ // Intentional parse error.
public function someFunction();
}

/* testFunctionReturnByRefWithReservedKeywordParent */
function &parent() {}

/* testFunctionReturnByRefWithReservedKeywordSelf */
function &self() {}

/* testFunctionReturnByRefWithReservedKeywordStatic */
function &static() {}

/* testLiveCoding */
// Intentional parse error. Redundancy testing.
abstract class
12 changes: 0 additions & 12 deletions Tests/Utils/ObjectDeclarations/GetNameDiffTest.php
Expand Up @@ -117,18 +117,6 @@ public static function dataGetName()
'testMarker' => '/* testInvalidInterfaceName */',
'expected' => 'switch',
],
'function-return-by-reference-with-reserved-keyword-parent' => [
'/* testFunctionReturnByRefWithReservedKeywordParent */',
'parent',
],
'function-return-by-reference-with-reserved-keyword-self' => [
'/* testFunctionReturnByRefWithReservedKeywordSelf */',
'self',
],
'function-return-by-reference-with-reserved-keyword-static' => [
'/* testFunctionReturnByRefWithReservedKeywordStatic */',
'static',
],
];
}
}

0 comments on commit d16f825

Please sign in to comment.