Skip to content

Commit 2adfb12

Browse files
committed
BCFile::findImplementedInterfaceNames(): sync with PHPCS 4.0 / handling of namespace relative interfaces
The PHPCS `File::findImplementedInterfaceNames()` method did not handle namespace relative interfaces correctly prior to PHPCS 4.0. The PHPCSUtils native `ObjectDeclarations::findImplementedInterfaceNames()` method **_did_** already handle this correctly. This commit adds the PHPCS 4.x version of the `findImplementedInterfaceNames()` method to the `BCFile` class. Includes moving related tests from the "Diff" test file to the "normal" test file and updating the docs to annotate this is no longer a difference between the PHPCS native and PHPCSUtils versions of the method.
1 parent dc1f23e commit 2adfb12

File tree

6 files changed

+50
-13
lines changed

6 files changed

+50
-13
lines changed

PHPCSUtils/BackCompat/BCFile.php

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -965,7 +965,7 @@ public static function findExtendedClassName(File $phpcsFile, $stackPtr)
965965
*
966966
* Changelog for the PHPCS native function:
967967
* - Introduced in PHPCS 2.7.0.
968-
* - The upstream method has received no significant updates since PHPCS 3.13.0.
968+
* - PHPCS 4.0.0: Handling of the namespace relative parent class using the namespace keyword as operator.
969969
*
970970
* @see \PHP_CodeSniffer\Files\File::findImplementedInterfaceNames() Original source.
971971
* @see \PHPCSUtils\Utils\ObjectDeclarations::findImplementedInterfaceNames() PHPCSUtils native improved version.
@@ -980,6 +980,44 @@ public static function findExtendedClassName(File $phpcsFile, $stackPtr)
980980
*/
981981
public static function findImplementedInterfaceNames(File $phpcsFile, $stackPtr)
982982
{
983-
return $phpcsFile->findImplementedInterfaceNames($stackPtr);
983+
$tokens = $phpcsFile->getTokens();
984+
985+
// Check for the existence of the token.
986+
if (isset($tokens[$stackPtr]) === false) {
987+
return false;
988+
}
989+
990+
if ($tokens[$stackPtr]['code'] !== T_CLASS
991+
&& $tokens[$stackPtr]['code'] !== T_ANON_CLASS
992+
&& $tokens[$stackPtr]['code'] !== T_ENUM
993+
) {
994+
return false;
995+
}
996+
997+
if (isset($tokens[$stackPtr]['scope_closer']) === false) {
998+
return false;
999+
}
1000+
1001+
$classOpenerIndex = $tokens[$stackPtr]['scope_opener'];
1002+
$implementsIndex = $phpcsFile->findNext(T_IMPLEMENTS, $stackPtr, $classOpenerIndex);
1003+
if ($implementsIndex === false) {
1004+
return false;
1005+
}
1006+
1007+
$find = Collections::namespacedNameTokens();
1008+
$find[] = T_WHITESPACE;
1009+
$find[] = T_COMMA;
1010+
1011+
$end = $phpcsFile->findNext($find, ($implementsIndex + 1), ($classOpenerIndex + 1), true);
1012+
$name = $phpcsFile->getTokensAsString(($implementsIndex + 1), ($end - $implementsIndex - 1));
1013+
$name = trim($name);
1014+
1015+
if ($name === '') {
1016+
return false;
1017+
} else {
1018+
$names = explode(',', $name);
1019+
$names = array_map('trim', $names);
1020+
return $names;
1021+
}
9841022
}
9851023
}

PHPCSUtils/Utils/ObjectDeclarations.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,6 @@ public static function findExtendedClassName(File $phpcsFile, $stackPtr)
277277
* - Bugs fixed:
278278
* - Handling of PHPCS annotations.
279279
* - Handling of comments.
280-
* - Handling of the namespace keyword used as operator.
281280
* - Improved handling of parse errors.
282281
* - The returned name(s) will be clean of superfluous whitespace and/or comments.
283282
* - Support for PHP 8.0 tokenization of identifier/namespaced names, cross-version PHP & PHPCS.

Tests/BackCompat/BCFile/FindImplementedInterfaceNamesTest.inc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ class testFIINNamespacedClass implements \PHP_CodeSniffer\Tests\Core\File\testFI
2121
/* testImplementsPartiallyQualified */
2222
class testFIINQualifiedClass implements Core\File\RelativeInterface {}
2323

24+
/* testImplementsMultipleNamespaceRelativeInterfaces */
25+
class testMultiImplementedNSOperator implements namespace\testInterfaceA, namespace\testInterfaceB {}
26+
2427
/* testClassThatExtendsAndImplements */
2528
class testFECNClassThatExtendsAndImplements extends testFECNClass implements InterfaceA, \NameSpaced\Cat\InterfaceB {}
2629

Tests/BackCompat/BCFile/FindImplementedInterfaceNamesTest.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,13 @@ public static function dataImplementedInterface()
130130
'identifier' => '/* testImplementsPartiallyQualified */',
131131
'expected' => ['Core\File\RelativeInterface'],
132132
],
133+
'class implements multiple interfaces, namespace relative' => [
134+
'identifier' => '/* testImplementsMultipleNamespaceRelativeInterfaces */',
135+
'expected' => [
136+
'namespace\testInterfaceA',
137+
'namespace\testInterfaceB',
138+
],
139+
],
133140
'class extends and implements' => [
134141
'identifier' => '/* testClassThatExtendsAndImplements */',
135142
'expected' => [

Tests/Utils/ObjectDeclarations/FindImplementedInterfaceNamesDiffTest.inc

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,5 @@ class testDeclarationWithComments
1313
// comment
1414
InterfaceB {}
1515

16-
/* testDeclarationMultiImplementedNamespaceOperator */
17-
class testMultiImplementedNSOperator implements namespace\testInterfaceA, namespace\testInterfaceB {}
18-
1916
/* testMultiImplementedStrayComma */
2017
class testMultiImplementedStrayComma implements testInterfaceA, , testInterfaceB {} // Intentional parse error.

Tests/Utils/ObjectDeclarations/FindImplementedInterfaceNamesDiffTest.php

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,6 @@ public static function dataFindImplementedInterfaceNames()
6363
'InterfaceB',
6464
],
6565
],
66-
'namespace-operator' => [
67-
'testMarker' => '/* testDeclarationMultiImplementedNamespaceOperator */',
68-
'expected' => [
69-
'namespace\testInterfaceA',
70-
'namespace\testInterfaceB',
71-
],
72-
],
7366
'parse-error-stray-comma' => [
7467
'testMarker' => '/* testMultiImplementedStrayComma */',
7568
'expected' => [

0 commit comments

Comments
 (0)