diff --git a/SlevomatCodingStandard/Helpers/ReferencedName.php b/SlevomatCodingStandard/Helpers/ReferencedName.php index 64bc35177..f4a1fd2ec 100644 --- a/SlevomatCodingStandard/Helpers/ReferencedName.php +++ b/SlevomatCodingStandard/Helpers/ReferencedName.php @@ -5,21 +5,31 @@ class ReferencedName { + const TYPE_DEFAULT = 'default'; + const TYPE_FUNCTION = 'function'; + const TYPE_CONSTANT = 'constant'; + /** @var string */ private $nameAsReferencedInFile; /** @var integer */ private $pointer; + /** @var string */ + private $type; + /** * @param string $nameAsReferencedInFile * @param integer $pointer + * @param string $type */ - public function __construct($nameAsReferencedInFile, $pointer) + public function __construct($nameAsReferencedInFile, $pointer, $type) { $this->nameAsReferencedInFile = $nameAsReferencedInFile; $this->pointer = $pointer; + $this->type = $type; } + /** * @return string */ @@ -36,4 +46,30 @@ public function getPointer() return $this->pointer; } + /** + * @return boolean + */ + public function isConstant() + { + return $this->type === self::TYPE_CONSTANT; + } + + /** + * @return boolean + */ + public function isFunction() + { + return $this->type === self::TYPE_FUNCTION; + } + + /** + * @param \SlevomatCodingStandard\Helpers\UseStatement $useStatement + * @return boolean + */ + public function hasSameUseStatementType(UseStatement $useStatement) + { + return $this->isConstant() === $useStatement->isConstant() + && $this->isFunction() === $useStatement->isFunction(); + } + } diff --git a/SlevomatCodingStandard/Helpers/ReferencedNameHelper.php b/SlevomatCodingStandard/Helpers/ReferencedNameHelper.php index 494a189b0..d81f47789 100644 --- a/SlevomatCodingStandard/Helpers/ReferencedNameHelper.php +++ b/SlevomatCodingStandard/Helpers/ReferencedNameHelper.php @@ -84,7 +84,7 @@ private static function createAllReferencedNames(PHP_CodeSniffer_File $phpcsFile ], true); }); foreach ($referencedNames as $name) { - $types[] = new ReferencedName($name, $nameStartPointer); + $types[] = new ReferencedName($name, $nameStartPointer, ReferencedName::TYPE_DEFAULT); } } }; @@ -124,7 +124,34 @@ private static function createAllReferencedNames(PHP_CodeSniffer_File $phpcsFile ); continue; } - $types[] = new ReferencedName(TokenHelper::getContent($phpcsFile, $nameStartPointer, $nameEndPointer), $nameStartPointer); + + $nextTokenAfterEndPointer = TokenHelper::findNextNonWhitespace($phpcsFile, $nameEndPointer); + $previousTokenBeforeStartPointer = TokenHelper::findPreviousNonWhitespace($phpcsFile, $nameStartPointer - 1); + $type = ReferencedName::TYPE_DEFAULT; + if ($nextTokenAfterEndPointer !== null && $previousTokenBeforeStartPointer !== null) { + if ($tokens[$nextTokenAfterEndPointer]['code'] === T_OPEN_PARENTHESIS) { + if ($tokens[$previousTokenBeforeStartPointer]['code'] !== T_NEW) { + $type = ReferencedName::TYPE_FUNCTION; + } + } elseif ($tokens[$nextTokenAfterEndPointer]['code'] !== T_VARIABLE) { + if ( + !in_array($tokens[$previousTokenBeforeStartPointer]['code'], [ + T_EXTENDS, + T_IMPLEMENTS, + T_INSTANCEOF, + T_USE, // trait + T_NEW, + T_COLON, // return typehint + ], true) + && !in_array($tokens[$nextTokenAfterEndPointer]['code'], [ + T_DOUBLE_COLON, + ], true) + ) { + $type = ReferencedName::TYPE_CONSTANT; + } + } + } + $types[] = new ReferencedName(TokenHelper::getContent($phpcsFile, $nameStartPointer, $nameEndPointer), $nameStartPointer, $type); $beginSearchAtPointer = $nameEndPointer + 1; } return $types; diff --git a/SlevomatCodingStandard/Helpers/UseStatement.php b/SlevomatCodingStandard/Helpers/UseStatement.php index 1237b1f29..483cfd74d 100644 --- a/SlevomatCodingStandard/Helpers/UseStatement.php +++ b/SlevomatCodingStandard/Helpers/UseStatement.php @@ -5,6 +5,10 @@ class UseStatement { + const TYPE_DEFAULT = ReferencedName::TYPE_DEFAULT; + const TYPE_FUNCTION = ReferencedName::TYPE_FUNCTION; + const TYPE_CONSTANT = ReferencedName::TYPE_CONSTANT; + /** @var string */ private $nameAsReferencedInFile; @@ -17,21 +21,27 @@ class UseStatement /** @var integer */ private $usePointer; + /** @var string */ + private $type; + /** * @param string $nameAsReferencedInFile * @param string $fullyQualifiedClassName * @param integer $usePointer T_USE pointer + * @param string $type */ public function __construct( $nameAsReferencedInFile, $fullyQualifiedClassName, - $usePointer + $usePointer, + $type ) { $this->nameAsReferencedInFile = $nameAsReferencedInFile; $this->normalizedNameAsReferencedInFile = self::normalizedNameAsReferencedInFile($nameAsReferencedInFile); $this->fullyQualifiedTypeName = $fullyQualifiedClassName; $this->usePointer = $usePointer; + $this->type = $type; } /** @@ -75,4 +85,44 @@ public function getPointer() return $this->usePointer; } + /** + * @return boolean + */ + public function isConstant() + { + return $this->type === self::TYPE_CONSTANT; + } + + /** + * @return boolean + */ + public function isFunction() + { + return $this->type === self::TYPE_FUNCTION; + } + + /** + * @param self $that + * @return boolean + */ + public function hasSameType(self $that) + { + return $this->type === $that->type; + } + + /** + * @param self $that + * @return integer + */ + public function compareByType(self $that) + { + $order = [ + self::TYPE_DEFAULT => 1, + self::TYPE_CONSTANT => 2, + self::TYPE_FUNCTION => 3, + ]; + + return $order[$this->type] - $order[$that->type]; + } + } diff --git a/SlevomatCodingStandard/Helpers/UseStatementHelper.php b/SlevomatCodingStandard/Helpers/UseStatementHelper.php index b3d5f37d3..01e3c9f79 100644 --- a/SlevomatCodingStandard/Helpers/UseStatementHelper.php +++ b/SlevomatCodingStandard/Helpers/UseStatementHelper.php @@ -72,6 +72,9 @@ public static function getFullyQualifiedTypeNameFromUse(PHP_CodeSniffer_File $ph $nameEndPointer = TokenHelper::findPreviousExcluding($phpcsFile, [T_WHITESPACE], $nameEndPointer - 1) + 1; } $nameStartPointer = $phpcsFile->findNext(TokenHelper::$nameTokenCodes, $usePointer + 1, $nameEndPointer); + if (in_array($tokens[$nameStartPointer]['content'], ['const', 'function'], true)) { + $nameStartPointer = $phpcsFile->findNext(TokenHelper::$nameTokenCodes, $nameStartPointer + 1, $nameEndPointer); + } $name = TokenHelper::getContent($phpcsFile, $nameStartPointer, $nameEndPointer); return NamespaceHelper::normalizeToCanonicalName($name); @@ -85,12 +88,23 @@ public static function getFullyQualifiedTypeNameFromUse(PHP_CodeSniffer_File $ph public static function getUseStatements(PHP_CodeSniffer_File $phpcsFile, $openTagPointer) { $names = []; + $tokens = $phpcsFile->getTokens(); foreach (self::getUseStatementPointers($phpcsFile, $openTagPointer) as $usePointer) { + $nextTokenFromUsePointer = TokenHelper::findNextNonWhitespace($phpcsFile, $usePointer + 1); + $type = UseStatement::TYPE_DEFAULT; + if ($tokens[$nextTokenFromUsePointer]['code'] === T_STRING) { + if ($tokens[$nextTokenFromUsePointer]['content'] === 'const') { + $type = UseStatement::TYPE_CONSTANT; + } elseif ($tokens[$nextTokenFromUsePointer]['content'] === 'function') { + $type = UseStatement::TYPE_FUNCTION; + } + } $name = self::getNameAsReferencedInClassFromUse($phpcsFile, $usePointer); $useStatement = new UseStatement( $name, self::getFullyQualifiedTypeNameFromUse($phpcsFile, $usePointer), - $usePointer + $usePointer, + $type ); $names[$useStatement->getCanonicalNameAsReferencedInFile()] = $useStatement; } diff --git a/SlevomatCodingStandard/Sniffs/Namespaces/AlphabeticallySortedUsesSniff.php b/SlevomatCodingStandard/Sniffs/Namespaces/AlphabeticallySortedUsesSniff.php index a45da342d..ef77f3250 100644 --- a/SlevomatCodingStandard/Sniffs/Namespaces/AlphabeticallySortedUsesSniff.php +++ b/SlevomatCodingStandard/Sniffs/Namespaces/AlphabeticallySortedUsesSniff.php @@ -12,8 +12,8 @@ class AlphabeticallySortedUsesSniff implements \PHP_CodeSniffer_Sniff const CODE_INCORRECT_ORDER = 'IncorrectlyOrderedUses'; - /** @var string */ - private $lastUseTypeName; + /** @var \SlevomatCodingStandard\Helpers\UseStatement */ + private $lastUse; /** * @return integer[] @@ -31,20 +31,19 @@ public function register() */ public function process(PHP_CodeSniffer_File $phpcsFile, $openTagPointer) { - $this->lastUseTypeName = null; + $this->lastUse = null; $useStatements = UseStatementHelper::getUseStatements( $phpcsFile, $openTagPointer ); foreach ($useStatements as $useStatement) { - $typeName = $useStatement->getFullyQualifiedTypeName(); - if ($this->lastUseTypeName === null) { - $this->lastUseTypeName = $typeName; + if ($this->lastUse === null) { + $this->lastUse = $useStatement; } else { - $order = $this->compareStrings($typeName, $this->lastUseTypeName); + $order = $this->compareUseStatements($useStatement, $this->lastUse); if ($order < 0) { $fix = $phpcsFile->addFixableError( - sprintf('Use statements are incorrectly ordered. The first wrong one is %s', $typeName), + sprintf('Use statements are incorrectly ordered. The first wrong one is %s', $useStatement->getFullyQualifiedTypeName()), $useStatement->getPointer(), self::CODE_INCORRECT_ORDER ); @@ -54,7 +53,7 @@ public function process(PHP_CodeSniffer_File $phpcsFile, $openTagPointer) return; } else { - $this->lastUseTypeName = $typeName; + $this->lastUse = $useStatement; } } } @@ -78,7 +77,7 @@ private function fixAlphabeticalOrder( } uasort($useStatements, function (UseStatement $a, UseStatement $b) { - return $this->compareStrings($a->getFullyQualifiedTypeName(), $b->getFullyQualifiedTypeName()); + return $this->compareUseStatements($a, $b); }); $phpcsFile->fixer->addContent($firstUseStatement->getPointer(), implode(PHP_EOL, array_map(function (UseStatement $useStatement) { @@ -93,34 +92,40 @@ private function fixAlphabeticalOrder( } /** - * @param string $a - * @param string $b + * @param \SlevomatCodingStandard\Helpers\UseStatement $a + * @param \SlevomatCodingStandard\Helpers\UseStatement $b * @return integer */ - private function compareStrings($a, $b) + private function compareUseStatements(UseStatement $a, UseStatement $b) { + if (!$a->hasSameType($b)) { + return $a->compareByType($b); + } + $aName = $a->getFullyQualifiedTypeName(); + $bName = $b->getFullyQualifiedTypeName(); + $i = 0; - for (; $i < min(strlen($a), strlen($b)); $i++) { - if ($this->isSpecialCharacter($a[$i]) && !$this->isSpecialCharacter($b[$i])) { + for (; $i < min(strlen($aName), strlen($bName)); $i++) { + if ($this->isSpecialCharacter($aName[$i]) && !$this->isSpecialCharacter($bName[$i])) { return -1; - } elseif (!$this->isSpecialCharacter($a[$i]) && $this->isSpecialCharacter($b[$i])) { + } elseif (!$this->isSpecialCharacter($aName[$i]) && $this->isSpecialCharacter($bName[$i])) { return 1; } - if (is_numeric($a[$i]) && is_numeric($b[$i])) { + if (is_numeric($aName[$i]) && is_numeric($bName[$i])) { break; } - $cmp = strcasecmp($a[$i], $b[$i]); + $cmp = strcasecmp($aName[$i], $bName[$i]); if ( $cmp !== 0 - || ($a[$i] !== $b[$i] && strtolower($a[$i]) === strtolower($b[$i])) + || ($aName[$i] !== $bName[$i] && strtolower($aName[$i]) === strtolower($bName[$i])) ) { return $cmp; } } - return strnatcasecmp(substr($a, $i), substr($b, $i)); + return strnatcasecmp(substr($aName, $i), substr($bName, $i)); } /** diff --git a/SlevomatCodingStandard/Sniffs/Namespaces/FullyQualifiedExceptionsSniff.php b/SlevomatCodingStandard/Sniffs/Namespaces/FullyQualifiedExceptionsSniff.php index e9d242917..c588b2d2b 100644 --- a/SlevomatCodingStandard/Sniffs/Namespaces/FullyQualifiedExceptionsSniff.php +++ b/SlevomatCodingStandard/Sniffs/Namespaces/FullyQualifiedExceptionsSniff.php @@ -55,7 +55,7 @@ public function process(PHP_CodeSniffer_File $phpcsFile, $openTagPointer) $pointer = $referencedName->getPointer(); $name = $referencedName->getNameAsReferencedInFile(); $normalizedName = UseStatement::normalizedNameAsReferencedInFile($name); - if (isset($useStatements[$normalizedName])) { + if (isset($useStatements[$normalizedName]) && $referencedName->hasSameUseStatementType($useStatements[$normalizedName])) { $useStatement = $useStatements[$normalizedName]; if ( !StringHelper::endsWith($useStatement->getFullyQualifiedTypeName(), 'Exception') diff --git a/SlevomatCodingStandard/Sniffs/Namespaces/UnusedUsesSniff.php b/SlevomatCodingStandard/Sniffs/Namespaces/UnusedUsesSniff.php index bd27033b7..8ab7d60ef 100644 --- a/SlevomatCodingStandard/Sniffs/Namespaces/UnusedUsesSniff.php +++ b/SlevomatCodingStandard/Sniffs/Namespaces/UnusedUsesSniff.php @@ -46,6 +46,9 @@ public function process(PHP_CodeSniffer_File $phpcsFile, $openTagPointer) !NamespaceHelper::isFullyQualifiedName($name) && isset($unusedNames[$normalizedNameAsReferencedInFile]) ) { + if (!$referencedName->hasSameUseStatementType($unusedNames[$normalizedNameAsReferencedInFile])) { + continue; + } if ($unusedNames[$normalizedNameAsReferencedInFile]->getNameAsReferencedInFile() !== $nameAsReferencedInFile) { $phpcsFile->addError(sprintf( 'Case of reference name %s and use statement %s do not match', diff --git a/build.xml b/build.xml index 698885026..fb7298688 100644 --- a/build.xml +++ b/build.xml @@ -30,6 +30,8 @@ > + + diff --git a/tests/Helpers/ReferencedNameHelperTest.php b/tests/Helpers/ReferencedNameHelperTest.php index 45e965d3c..b942d030c 100644 --- a/tests/Helpers/ReferencedNameHelperTest.php +++ b/tests/Helpers/ReferencedNameHelperTest.php @@ -10,38 +10,49 @@ public function dataGetAllReferencedNames() return [ [ [ - '\ExtendedClass', - '\ImplementedInterface', - '\FullyQualified\SomeOtherTrait', - 'SomeTrait', - 'TypehintedName', - 'ClassInstance', - 'StaticClass', - '\Foo\Bar\SpecificException', - '\Foo\Bar\Baz\SomeOtherException', + ['\ExtendedClass', false, false], + ['\ImplementedInterface', false, false], + ['\FullyQualified\SomeOtherTrait', false, false], + ['SomeTrait', false, false], + ['TypehintedName', false, false], + ['ClassInstance', false, false], + ['StaticClass', false, false], + ['\Foo\Bar\SpecificException', false, false], + ['\Foo\Bar\Baz\SomeOtherException', false, false], + ['callToFunction', true, false], + ['FOO_CONSTANT', false, true], + ['BAZ_CONSTANT', false, true], + ['LoremClass', false, false], + ['IpsumClass', false, false], ], false, ], [ [ - '\ExtendedClass', - '\ImplementedInterface', - '\FullyQualified\SomeOtherTrait', - 'SomeTrait', - 'ORM\Column', - 'Bar', - 'Lorem', - 'Ipsum', - 'Rasmus', - 'Lerdorf', - '\Foo\BarBaz', - 'TypehintedName', - 'AnotherTypehintedName', - 'Returned_Typehinted_Underscored_Name', - 'ClassInstance', - 'StaticClass', - '\Foo\Bar\SpecificException', - '\Foo\Bar\Baz\SomeOtherException', + ['\ExtendedClass', false, false], + ['\ImplementedInterface', false, false], + ['\FullyQualified\SomeOtherTrait', false, false], + ['SomeTrait', false, false], + ['ORM\Column', false, false], + ['Bar', false, false], + ['Lorem', false, false], + ['Ipsum', false, false], + ['Rasmus', false, false], + ['Lerdorf', false, false], + ['\Foo\BarBaz', false, false], + ['TypehintedName', false, false], + ['AnotherTypehintedName', false, false], + ['Returned_Typehinted_Underscored_Name', false, false], + ['TypehintedName', false, false], + ['ClassInstance', false, false], + ['StaticClass', false, false], + ['\Foo\Bar\SpecificException', false, false], + ['\Foo\Bar\Baz\SomeOtherException', false, false], + ['callToFunction', true, false], + ['FOO_CONSTANT', false, true], + ['BAZ_CONSTANT', false, true], + ['LoremClass', false, false], + ['IpsumClass', false, false], ], true, ], @@ -60,9 +71,12 @@ public function testGetAllReferencedNames(array $foundTypes, $searchAnnotations) ); $names = ReferencedNameHelper::getAllReferencedNames($codeSnifferFile, 0, $searchAnnotations); - $this->assertSame($foundTypes, array_values(array_unique(array_map(function (ReferencedName $name) { - return $name->getNameAsReferencedInFile(); - }, $names)))); + $this->assertCount(count($foundTypes), $names); + foreach ($names as $i => $referencedName) { + $this->assertSame($foundTypes[$i][0], $referencedName->getNameAsReferencedInFile()); + $this->assertSame($foundTypes[$i][1], $referencedName->isFunction(), $foundTypes[$i][0]); + $this->assertSame($foundTypes[$i][2], $referencedName->isConstant(), $foundTypes[$i][0]); + } } public function testFindReferencedNameEndPointerOnNonReferencedName() diff --git a/tests/Helpers/UseStatementHelperTest.php b/tests/Helpers/UseStatementHelperTest.php index bb1b706b1..01ca26eac 100644 --- a/tests/Helpers/UseStatementHelperTest.php +++ b/tests/Helpers/UseStatementHelperTest.php @@ -77,23 +77,29 @@ public function testGetUseStatements() __DIR__ . '/data/useStatements.php' ); $useStatements = UseStatementHelper::getUseStatements($codeSnifferFile, 0); - $this->assertCount(4, $useStatements); + $this->assertCount(6, $useStatements); $this->assertSame(2, $useStatements['baz']->getPointer()); - $this->assertUseStatement('Bar\Baz', 'Baz', $useStatements['baz']); - $this->assertUseStatement('Foo', 'Foo', $useStatements['foo']); - $this->assertUseStatement('Lorem\Ipsum', 'LoremIpsum', $useStatements['loremipsum']); - $this->assertUseStatement('Zero', 'Zero', $useStatements['zero']); + $this->assertUseStatement('Bar\Baz', 'Baz', $useStatements['baz'], false, false); + $this->assertUseStatement('Foo', 'Foo', $useStatements['foo'], false, false); + $this->assertUseStatement('Lorem\Ipsum', 'LoremIpsum', $useStatements['loremipsum'], false, false); + $this->assertUseStatement('Zero', 'Zero', $useStatements['zero'], false, false); + $this->assertUseStatement('Rasmus\FOO_CONSTANT', 'FOO_CONSTANT', $useStatements['foo_constant'], false, true); + $this->assertUseStatement('Lerdorf\isBar', 'isBar', $useStatements['isbar'], true, false); } /** * @param string $fullyQualifiedTypeName * @param string $referencedName * @param \SlevomatCodingStandard\Helpers\UseStatement $useStatement + * @param boolean $isFunction + * @param boolean $isConstant */ - private function assertUseStatement($fullyQualifiedTypeName, $referencedName, UseStatement $useStatement) + private function assertUseStatement($fullyQualifiedTypeName, $referencedName, UseStatement $useStatement, $isFunction, $isConstant) { $this->assertSame($fullyQualifiedTypeName, $useStatement->getFullyQualifiedTypeName()); $this->assertSame($referencedName, $useStatement->getNameAsReferencedInFile()); + $this->assertSame($isFunction, $useStatement->isFunction()); + $this->assertSame($isConstant, $useStatement->isConstant()); } } diff --git a/tests/Helpers/data/lotsOfReferencedNames.php b/tests/Helpers/data/lotsOfReferencedNames.php index 2ccfcbbe3..8ad875c23 100644 --- a/tests/Helpers/data/lotsOfReferencedNames.php +++ b/tests/Helpers/data/lotsOfReferencedNames.php @@ -38,6 +38,11 @@ public function fooMethod(TypehintedName $foo, array $bar) } catch (\Foo\Bar\Baz\SomeOtherException $e) { throw $e; } + + callToFunction(FOO_CONSTANT); + $baz = BAZ_CONSTANT; + $lorem = new LoremClass; + $ipsum = IpsumClass::IPSUM_CONSTANT; } } diff --git a/tests/Helpers/data/useStatements.php b/tests/Helpers/data/useStatements.php index 234da435b..1d7acf155 100644 --- a/tests/Helpers/data/useStatements.php +++ b/tests/Helpers/data/useStatements.php @@ -3,6 +3,8 @@ use Bar\Baz; use Foo; use Lorem\Ipsum as LoremIpsum; +use const Rasmus\FOO_CONSTANT; +use function Lerdorf\isBar; class FooBar { diff --git a/tests/Sniffs/Namespaces/UnusedUsesSniffTest.php b/tests/Sniffs/Namespaces/UnusedUsesSniffTest.php index 4b3f40c64..3a40230d4 100644 --- a/tests/Sniffs/Namespaces/UnusedUsesSniffTest.php +++ b/tests/Sniffs/Namespaces/UnusedUsesSniffTest.php @@ -18,6 +18,18 @@ public function testUnusedUse() UnusedUsesSniff::CODE_UNUSED_USE, 'First\Object' ); + $this->assertSniffError( + $this->getFileReport(), + 12, + UnusedUsesSniff::CODE_UNUSED_USE, + 'FooBar\UnusedFunction' + ); + $this->assertSniffError( + $this->getFileReport(), + 14, + UnusedUsesSniff::CODE_UNUSED_USE, + 'FooBar\UNUSED_CONSTANT' + ); } public function testUnusedUseWithAsPart() @@ -55,6 +67,24 @@ public function testUsedUseWithStaticMethodCall() $this->assertNoSniffError($this->getFileReport(), 11); } + public function testUsedFunction() + { + $this->assertNoSniffError($this->getFileReport(), 13); + } + + public function testUsedConstant() + { + $this->assertNoSniffError($this->getFileReport(), 15); + } + + public function testReturnTypehint() + { + if (PHP_VERSION_ID < 70000) { + $this->markTestSkipped('Available on PHP7 only'); + } + $this->assertNoSniffErrorInFile($this->checkFile(__DIR__ . '/data/php7/unusedUses.php')); + } + public function testFindCaseInsensitiveUse() { $report = $this->checkFile(__DIR__ . '/data/caseInsensitiveUse.php'); diff --git a/tests/Sniffs/Namespaces/data/correctOrder.php b/tests/Sniffs/Namespaces/data/correctOrder.php index 192de908f..8f4eda687 100644 --- a/tests/Sniffs/Namespaces/data/correctOrder.php +++ b/tests/Sniffs/Namespaces/data/correctOrder.php @@ -3,10 +3,18 @@ use Beta; use Charlie; use Gamma; +use const Alpha\BAR_CONSTANT; +use const Alpha\FOO_CONSTANT; +use const Beta\BAZ_CONSTANT; +use const Beta\FOU_CONSTANT; +use function Alpha\barFunction; +use function Alpha\fooFunction; +use function Beta\bazFunction; +use function Beta\fouFunction; class Foo { } -use Omega; +use function Omega\ipsumFunction; diff --git a/tests/Sniffs/Namespaces/data/php7/unusedUses.php b/tests/Sniffs/Namespaces/data/php7/unusedUses.php new file mode 100644 index 000000000..33b5d1de8 --- /dev/null +++ b/tests/Sniffs/Namespaces/data/php7/unusedUses.php @@ -0,0 +1,15 @@ +