From f69e2524e8770efb9b3e5ac4a0ebc0d54eb446d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaroslav=20Hansl=C3=ADk?= Date: Mon, 15 May 2023 23:34:35 +0200 Subject: [PATCH] SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly: Fixed false positive --- .../Namespaces/ReferenceUsedNamesOnlySniff.php | 12 +++++++++++- .../ReferenceUsedNamesOnlySniffTest.php | 12 ++++++++++++ .../data/partialUsesWithoutNamespace.php | 15 +++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 tests/Sniffs/Namespaces/data/partialUsesWithoutNamespace.php diff --git a/SlevomatCodingStandard/Sniffs/Namespaces/ReferenceUsedNamesOnlySniff.php b/SlevomatCodingStandard/Sniffs/Namespaces/ReferenceUsedNamesOnlySniff.php index 323da15a0..0c5ee0b0d 100644 --- a/SlevomatCodingStandard/Sniffs/Namespaces/ReferenceUsedNamesOnlySniff.php +++ b/SlevomatCodingStandard/Sniffs/Namespaces/ReferenceUsedNamesOnlySniff.php @@ -40,6 +40,7 @@ use function preg_quote; use function preg_replace; use function sprintf; +use function strpos; use function strtolower; use function substr; use const T_DECLARE; @@ -187,8 +188,17 @@ public function process(File $phpcsFile, $openTagPointer): void $collidingUseStatementUniqueId = UseStatement::getUniqueId($reference->type, $unqualifiedName); + $isPartialUse = false; + foreach ($useStatements as $useStatement) { + $useStatementName = $useStatement->getAlias() ?? $useStatement->getNameAsReferencedInFile(); + if (strpos($name, $useStatementName . '\\') === 0) { + $isPartialUse = true; + break; + } + } + $isFullyQualified = NamespaceHelper::isFullyQualifiedName($name) - || ($namespacePointers === [] && NamespaceHelper::hasNamespace($name)); + || ($namespacePointers === [] && NamespaceHelper::hasNamespace($name) && !$isPartialUse); $isGlobalFallback = !$isFullyQualified && !NamespaceHelper::hasNamespace($name) diff --git a/tests/Sniffs/Namespaces/ReferenceUsedNamesOnlySniffTest.php b/tests/Sniffs/Namespaces/ReferenceUsedNamesOnlySniffTest.php index ddfa4f786..15c406814 100644 --- a/tests/Sniffs/Namespaces/ReferenceUsedNamesOnlySniffTest.php +++ b/tests/Sniffs/Namespaces/ReferenceUsedNamesOnlySniffTest.php @@ -316,6 +316,18 @@ public function testAllowPartialUses(array $ignoredNames): void self::assertNoSniffError($report, 7); } + public function testAllowPartialUsesWithoutNamespace(): void + { + $report = self::checkFile( + __DIR__ . '/data/partialUsesWithoutNamespace.php', + [ + 'allowPartialUses' => true, + ] + ); + + self::assertNoSniffErrorInFile($report); + } + /** * @dataProvider dataIgnoredNamesForIrrelevantTests * @param list $ignoredNames diff --git a/tests/Sniffs/Namespaces/data/partialUsesWithoutNamespace.php b/tests/Sniffs/Namespaces/data/partialUsesWithoutNamespace.php new file mode 100644 index 000000000..e49af8683 --- /dev/null +++ b/tests/Sniffs/Namespaces/data/partialUsesWithoutNamespace.php @@ -0,0 +1,15 @@ += 8.1 + +use Mockery as m; +use PHPUnit\Framework\TestCase; +use Psr\Log\LoggerInterface; + +class MyTestCase extends TestCase +{ + private LoggerInterface&m\MockInterface $loggerMock; + + protected function setUp(): void + { + $this->loggerMock = m::mock(LoggerInterface::class); + } +}