diff --git a/PHPCSUtils/Utils/ObjectDeclarations.php b/PHPCSUtils/Utils/ObjectDeclarations.php index 9b74caaf..45373b09 100644 --- a/PHPCSUtils/Utils/ObjectDeclarations.php +++ b/PHPCSUtils/Utils/ObjectDeclarations.php @@ -213,7 +213,11 @@ public static function getClassProperties(File $phpcsFile, $stackPtr) /** * Retrieves the name of the class that the specified class extends. - * (works for classes, anonymous classes and interfaces) + * + * Works for classes, anonymous classes and interfaces, though it is strongly recommended + * to use the {@see \PHPCSUtils\Utils\ObjectDeclarations::findExtendedInterfaceNames()} + * method to examine interfaces instead. Interfaces can extend multiple parent interfaces, + * and that use case is not handled by this method. * * Main differences with the PHPCS version: * - Bugs fixed: @@ -222,8 +226,10 @@ public static function getClassProperties(File $phpcsFile, $stackPtr) * - Improved handling of parse errors. * - The returned name will be clean of superfluous whitespace and/or comments. * - * @see \PHP_CodeSniffer\Files\File::findExtendedClassName() Original source. - * @see \PHPCSUtils\BackCompat\BCFile::findExtendedClassName() Cross-version compatible version of the original. + * @see \PHP_CodeSniffer\Files\File::findExtendedClassName() Original source. + * @see \PHPCSUtils\BackCompat\BCFile::findExtendedClassName() Cross-version compatible version of + * the original. + * @see \PHPCSUtils\Utils\ObjectDeclarations::findExtendedInterfaceNames() Similar method for extended interfaces. * * @since 1.0.0 * @@ -271,6 +277,29 @@ public static function findImplementedInterfaceNames(File $phpcsFile, $stackPtr) return self::findNames($phpcsFile, $stackPtr, \T_IMPLEMENTS, Collections::$OOCanImplement); } + /** + * Retrieves the names of the interfaces that the specified interface extends. + * + * @see \PHPCSUtils\Utils\ObjectDeclarations::findExtendedClassName() Similar method for extended classes. + * + * @since 1.0.0 + * + * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found. + * @param int $stackPtr The stack position of the interface keyword. + * + * @return array|false Array with names of the extended interfaces or FALSE on + * error or if there are no extended interface names. + */ + public static function findExtendedInterfaceNames(File $phpcsFile, $stackPtr) + { + return self::findNames( + $phpcsFile, + $stackPtr, + \T_EXTENDS, + [\T_INTERFACE => \T_INTERFACE] + ); + } + /** * Retrieves the names of the extended classes or interfaces or the implemented * interfaces that the specific class/interface declaration extends/implements. diff --git a/Tests/Utils/ObjectDeclarations/FindExtendedInterfaceNamesTest.inc b/Tests/Utils/ObjectDeclarations/FindExtendedInterfaceNamesTest.inc new file mode 100644 index 00000000..420ead9d --- /dev/null +++ b/Tests/Utils/ObjectDeclarations/FindExtendedInterfaceNamesTest.inc @@ -0,0 +1,33 @@ +assertFalse($result); + } + + /** + * Test getting a `false` result when a token other than one of the supported tokens is passed. + * + * @return void + */ + public function testNotAnInterface() + { + $token = $this->getTargetToken('/* testNotAnInterface */', [\T_FUNCTION]); + $result = ObjectDeclarations::findExtendedInterfaceNames(self::$phpcsFile, $token); + $this->assertFalse($result); + } + + /** + * Test retrieving the names of the interfaces being extended by another interface. + * + * @dataProvider dataFindExtendedInterfaceNames + * + * @param string $testMarker The comment which prefaces the target token in the test file. + * @param array|false $expected Expected function output. + * + * @return void + */ + public function testFindExtendedInterfaceNames($testMarker, $expected) + { + $interface = $this->getTargetToken($testMarker, [\T_INTERFACE]); + $result = ObjectDeclarations::findExtendedInterfaceNames(self::$phpcsFile, $interface); + $this->assertSame($expected, $result); + } + + /** + * Data provider. + * + * @see testFindExtendedInterfaceNames() For the array format. + * + * @return array + */ + public function dataFindExtendedInterfaceNames() + { + return [ + 'not-extended' => [ + '/* testInterface */', + false, + ], + 'extends-one' => [ + '/* testExtendedInterface */', + ['testInterface'], + ], + 'extends-two' => [ + '/* testMultiExtendedInterface */', + [ + 'testInterfaceA', + 'testInterfaceB', + ], + ], + 'extends-one-namespaced' => [ + '/* testExtendedNamespacedInterface */', + ['\PHPCSUtils\Tests\ObjectDeclarations\testInterface'], + ], + 'extends-two-namespaced' => [ + '/* testMultiExtendedNamespacedInterface */', + [ + '\PHPCSUtils\Tests\ObjectDeclarations\testInterfaceA', + '\PHPCSUtils\Tests\ObjectDeclarations\testFEINInterfaceB', + ], + ], + 'extends-with-comments' => [ + '/* testMultiExtendedInterfaceWithComments */', + [ + 'testInterfaceA', + '\PHPCSUtils\Tests\Some\Declarations\testInterfaceB', + '\testInterfaceC', + ], + ], + 'parse-error' => [ + '/* testParseError */', + false, + ], + ]; + } +}