Repository: phpactor/phpactor (php)

Issue:
False positive for unused import
I found a false positive for unused import.
Compact use in a namespaced file will trigger an *Unused import* diagnostic on the last namespace part.

I've written the unit test for this case (here is the [commit](https://github.com/Nicals/phpactor/commit/9443934c386fb1d81c1a0f706ff2ac3007c2a049)).
In this case, the diagnostic is:
```
Phpactor\WorseReflection\Core\Diagnostics^ {#160
  -diagnostics: array:1 [
    0 => Phpactor\WorseReflection\Bridge\TolerantParser\Diagnostics\UnusedImportDiagnostic^ {#543
      -range: Phpactor\TextDocument\ByteOffsetRange^ {#540
        -start: Phpactor\TextDocument\ByteOffset^ {#538
          -offset: 44
        }
        -end: Phpactor\TextDocument\ByteOffset^ {#541
          -offset: 48
        }
      }
      -name: "Foobar"
    }
  ]
}
```

I'm not familiar with this codebase, I might take some time to make a PR about this if I find some time but it won't be soon.

Pull request:
Gh 2048 compact use statement false positive
Fixes #2048

Patch:
diff --git a/lib/WorseReflection/Bridge/TolerantParser/Diagnostics/UnusedImportProvider.php b/lib/WorseReflection/Bridge/TolerantParser/Diagnostics/UnusedImportProvider.php
index 9ce0a0ba..fa3dc604 100644
--- a/lib/WorseReflection/Bridge/TolerantParser/Diagnostics/UnusedImportProvider.php
+++ b/lib/WorseReflection/Bridge/TolerantParser/Diagnostics/UnusedImportProvider.php
@@ -63,8 +63,7 @@ class UnusedImportProvider implements DiagnosticProvider
                         continue;
                     }
 
-                    $lastPart = $this->lastPart($groupClause->namespaceName->getNamespacedName()->__toString());
-                    $this->imported[$this->prefixedName($groupClause, $lastPart)] = $groupClause;
+                    $this->imported[$this->prefixedName($groupClause, $groupClause->__toString())] = $groupClause;
                 }
                 return [];
             }
@@ -138,6 +137,7 @@ class UnusedImportProvider implements DiagnosticProvider
         return str_contains($contents, '@' . $imported);
     }
 
+    /** @phpstan-ignore-next-line TP lies */
     private function lastPart(string $name): string
     {
         $parts = array_filter(explode('\\', $name));


Test patch:
diff --git a/lib/WorseReflection/Tests/Integration/Bridge/TolerantParser/Diagonstics/UnusedImportProvider/CompactNamespacedUse.test b/lib/WorseReflection/Tests/Integration/Bridge/TolerantParser/Diagonstics/UnusedImportProvider/CompactNamespacedUse.test
new file mode 100644
index 00000000..d467564a
--- /dev/null
+++ b/lib/WorseReflection/Tests/Integration/Bridge/TolerantParser/Diagonstics/UnusedImportProvider/CompactNamespacedUse.test
@@ -0,0 +1,8 @@
+<?php
+
+namespace Foo\Foobar;
+
+use Foo\{Ham, Spam};
+
+new Ham();
+new Spam();
diff --git a/lib/WorseReflection/Tests/Integration/Bridge/TolerantParser/Diagonstics/UnusedImportProviderTest.php b/lib/WorseReflection/Tests/Integration/Bridge/TolerantParser/Diagonstics/UnusedImportProviderTest.php
index bdee6902..5fa43665 100644
--- a/lib/WorseReflection/Tests/Integration/Bridge/TolerantParser/Diagonstics/UnusedImportProviderTest.php
+++ b/lib/WorseReflection/Tests/Integration/Bridge/TolerantParser/Diagonstics/UnusedImportProviderTest.php
@@ -101,6 +101,11 @@ class UnusedImportProviderTest extends DiagnosticsTestCase
         self::assertCount(0, $diagnostics);
     }
 
+    public function checkCompactNamespacedUse(Diagnostics $diagnostics): void
+    {
+        self::assertCount(0, $diagnostics);
+    }
+
     protected function provider(): DiagnosticProvider
     {
         return new UnusedImportProvider();