From f957255badf637035888eebf43bfb642c385f9bb Mon Sep 17 00:00:00 2001 From: jrfnl Date: Sun, 13 Sep 2020 19:38:46 +0200 Subject: [PATCH] BCFile/various methods: compatibility with the PHP 8 identifier name tokenization While PHPCS itself won't backfill, nor start supporting the PHP 8 identifier name tokens until PHPCS 4.x, for compatibility with PHPCS < 3.5.7 in combination with PHP 8, the `BCFile::getMethodParameters()`, `BCFile::isReference()`, `BCFile::findExtendedClassName()` and `BCFile::findImplementedInterfaceNames()` methods still need adjusting to allow for cross-version compatibility. Relevant unit tests for this were already added for most methods in PR 205. For the `isReference()` method, select unit tests are now moved from the `Diff` test file to the `BCFile` test files. --- PHPCSUtils/BackCompat/BCFile.php | 35 ++++++++++++++----- Tests/BackCompat/BCFile/IsReferenceTest.inc | 3 ++ Tests/BackCompat/BCFile/IsReferenceTest.php | 4 +++ Tests/Utils/Operators/IsReferenceDiffTest.inc | 3 -- Tests/Utils/Operators/IsReferenceDiffTest.php | 4 --- 5 files changed, 33 insertions(+), 16 deletions(-) diff --git a/PHPCSUtils/BackCompat/BCFile.php b/PHPCSUtils/BackCompat/BCFile.php index 22fef010..38556d08 100644 --- a/PHPCSUtils/BackCompat/BCFile.php +++ b/PHPCSUtils/BackCompat/BCFile.php @@ -261,6 +261,7 @@ public static function getDeclarationName(File $phpcsFile, $stackPtr) * * @since 1.0.0 * @since 1.0.0-alpha2 Added BC support for PHP 7.4 arrow functions. + * @since 1.0.0-alpha4 Added support for PHP 8.0 identifier name tokens. * * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. * @param int $stackPtr The position in the stack of the function token @@ -381,7 +382,10 @@ public static function getMethodParameters(File $phpcsFile, $stackPtr) } break; case 'T_STRING': - // This is a string, so it may be a type hint, but it could + case 'T_NAME_QUALIFIED': + case 'T_NAME_FULLY_QUALIFIED': + case 'T_NAME_RELATIVE': + // This is an identifier name, so it may be a type hint, but it could // also be a constant used as a default value. $prevComma = false; for ($t = $i; $t >= $opener; $t--) { @@ -987,6 +991,7 @@ public static function getClassProperties(File $phpcsFile, $stackPtr) * * @since 1.0.0 * @since 1.0.0-alpha2 Added BC support for PHP 7.4 arrow functions. + * @since 1.0.0-alpha4 Added support for PHP 8.0 identifier name tokens. * * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. * @param int $stackPtr The position of the `T_BITWISE_AND` token. @@ -1074,7 +1079,11 @@ public static function isReference(File $phpcsFile, $stackPtr) if ($tokens[$tokenAfter]['code'] === T_VARIABLE) { return true; } else { - $skip = Tokens::$emptyTokens; + $skip = Tokens::$emptyTokens; + + // BC for PHP 8 in combination with PHPCS < 3.5.7. + $skip += Collections::nameTokens(); + $skip[] = T_NS_SEPARATOR; $skip[] = T_SELF; $skip[] = T_PARENT; @@ -1457,6 +1466,7 @@ public static function getCondition(File $phpcsFile, $stackPtr, $type, $first = * @see \PHPCSUtils\Utils\ObjectDeclarations::findExtendedClassName() PHPCSUtils native improved version. * * @since 1.0.0 + * @since 1.0.0-alpha4 Added support for PHP 8.0 identifier name tokens. * * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. * @param int $stackPtr The stack position of the class or interface. @@ -1491,11 +1501,14 @@ public static function findExtendedClassName(File $phpcsFile, $stackPtr) } $find = [ - T_NS_SEPARATOR, - T_STRING, - T_WHITESPACE, + T_NS_SEPARATOR => T_NS_SEPARATOR, + T_STRING => T_STRING, + T_WHITESPACE => T_WHITESPACE, ]; + // BC for PHP 8 in combination with PHPCS < 3.5.7. + $find += Collections::nameTokens(); + $end = $phpcsFile->findNext($find, ($extendsIndex + 1), ($classOpenerIndex + 1), true); $name = $phpcsFile->getTokensAsString(($extendsIndex + 1), ($end - $extendsIndex - 1)); $name = trim($name); @@ -1520,6 +1533,7 @@ public static function findExtendedClassName(File $phpcsFile, $stackPtr) * @see \PHPCSUtils\Utils\ObjectDeclarations::findImplementedInterfaceNames() PHPCSUtils native improved version. * * @since 1.0.0 + * @since 1.0.0-alpha4 Added support for PHP 8.0 identifier name tokens. * * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. * @param int $stackPtr The stack position of the class. @@ -1553,12 +1567,15 @@ public static function findImplementedInterfaceNames(File $phpcsFile, $stackPtr) } $find = [ - T_NS_SEPARATOR, - T_STRING, - T_WHITESPACE, - T_COMMA, + T_NS_SEPARATOR => T_NS_SEPARATOR, + T_STRING => T_STRING, + T_WHITESPACE => T_WHITESPACE, + T_COMMA => T_COMMA, ]; + // BC for PHP 8 in combination with PHPCS < 3.5.7. + $find += Collections::nameTokens(); + $end = $phpcsFile->findNext($find, ($implementsIndex + 1), ($classOpenerIndex + 1), true); $name = $phpcsFile->getTokensAsString(($implementsIndex + 1), ($end - $implementsIndex - 1)); $name = trim($name); diff --git a/Tests/BackCompat/BCFile/IsReferenceTest.inc b/Tests/BackCompat/BCFile/IsReferenceTest.inc index 7c843669..f8632fd6 100644 --- a/Tests/BackCompat/BCFile/IsReferenceTest.inc +++ b/Tests/BackCompat/BCFile/IsReferenceTest.inc @@ -154,6 +154,9 @@ functionCall($something, &\SomeNS\SomeClass::$somethingElse); /* testPassByReferenceJ */ functionCall($something, &namespace\SomeClass::$somethingElse); +/* testPassByReferencePartiallyQualifiedName */ +functionCall($something, &Sub\Level\SomeClass::$somethingElse); + /* testNewByReferenceA */ $foobar2 = &new Foobar(); diff --git a/Tests/BackCompat/BCFile/IsReferenceTest.php b/Tests/BackCompat/BCFile/IsReferenceTest.php index cd29ca53..5b04a17a 100644 --- a/Tests/BackCompat/BCFile/IsReferenceTest.php +++ b/Tests/BackCompat/BCFile/IsReferenceTest.php @@ -296,6 +296,10 @@ public function dataIsReference() '/* testPassByReferenceJ */', true, ], + [ + '/* testPassByReferencePartiallyQualifiedName */', + true, + ], [ '/* testNewByReferenceA */', true, diff --git a/Tests/Utils/Operators/IsReferenceDiffTest.inc b/Tests/Utils/Operators/IsReferenceDiffTest.inc index aeda55b1..a1695c0c 100644 --- a/Tests/Utils/Operators/IsReferenceDiffTest.inc +++ b/Tests/Utils/Operators/IsReferenceDiffTest.inc @@ -20,6 +20,3 @@ $fn = fn($param, &...$moreParams) => 1; /* testArrowFunctionNonReferenceInDefault */ $fn = fn( $one = E_NOTICE & E_STRICT) => 1; - -/* testPassByReferencePartiallyQualifiedName */ -functionCall($something, &Sub\Level\SomeClass::$somethingElse); diff --git a/Tests/Utils/Operators/IsReferenceDiffTest.php b/Tests/Utils/Operators/IsReferenceDiffTest.php index 11a8d410..bdfc44ff 100644 --- a/Tests/Utils/Operators/IsReferenceDiffTest.php +++ b/Tests/Utils/Operators/IsReferenceDiffTest.php @@ -97,10 +97,6 @@ public function dataIsReference() '/* testArrowFunctionNonReferenceInDefault */', false, ], - 'pass-by-ref-partially-qualified-name-param-type' => [ - '/* testPassByReferencePartiallyQualifiedName */', - true, - ], ]; } }