diff --git a/fixtures/completion/used_class.php b/fixtures/completion/used_class.php index 7aa971b..d0143ff 100644 --- a/fixtures/completion/used_class.php +++ b/fixtures/completion/used_class.php @@ -2,8 +2,10 @@ namespace Whatever; -use TestNamespace\{TestClass, TestInterface}; +use TestNamespace\{TestClass, TestInterface, IDontExist}; -TestC +TestC; + +IDont; class OtherClass {} diff --git a/src/CompletionProvider.php b/src/CompletionProvider.php index 4d982d9..36c7c3e 100644 --- a/src/CompletionProvider.php +++ b/src/CompletionProvider.php @@ -408,7 +408,8 @@ class CompletionProvider yield from $this->getCompletionsForAliases( $prefix, $namespaceAliases, - $requireCanBeInstantiated + $requireCanBeInstantiated, + CompletionItemKind::CLASS_ ); // Completions from the current namespace @@ -471,13 +472,15 @@ class CompletionProvider * * @param string $prefix Non-qualified name being completed for * @param QualifiedName[] $aliases Array of alias FQNs indexed by the alias. + * @param int $defaultSymbolKind The SymbolKind:: constant to use when the definition for the alias is not found. * @return \Generator|CompletionItem[] * Yields CompletionItems. */ private function getCompletionsForAliases( string $prefix, array $aliases, - bool $requireCanBeInstantiated + bool $requireCanBeInstantiated, + int $defaultCompletionItemKind ): \Generator { foreach ($aliases as $alias => $aliasFqn) { if (!nameStartsWith($alias, $prefix)) { @@ -491,6 +494,11 @@ class CompletionProvider $completionItem = CompletionItem::fromDefinition($definition); $completionItem->insertText = $alias; yield (string)$aliasFqn => $completionItem; + } else { + // Use clause referred to a symbol which was not indexed. + $completionItem = new CompletionItem($alias, $defaultCompletionItemKind); + $completionItem->detail = nameGetParent((string)$aliasFqn); + yield (string)$aliasFqn => $completionItem; } } } diff --git a/tests/Server/TextDocument/CompletionTest.php b/tests/Server/TextDocument/CompletionTest.php index de33f9f..78dc3d8 100644 --- a/tests/Server/TextDocument/CompletionTest.php +++ b/tests/Server/TextDocument/CompletionTest.php @@ -271,6 +271,29 @@ class CompletionTest extends TestCase $this->assertCompletionsListDoesNotContainLabel('TestInterface', $items); } + /** + * Tests completion at `IDontE|` with `use TestNamespace\IDontExist` + */ + public function testUsedClassNonExistent() + { + $completionUri = pathToUri(__DIR__ . '/../../../fixtures/completion/used_class.php'); + $this->loader->open($completionUri, file_get_contents($completionUri)); + $items = $this->textDocument->completion( + new TextDocumentIdentifier($completionUri), + new Position(8, 5) + )->wait(); + $this->assertEquals(new CompletionList([ + new CompletionItem( + 'IDontExist', + CompletionItemKind::CLASS_, + 'TestNamespace' + ) + ], true), $items); + + $this->assertCompletionsListDoesNotContainLabel('OtherClass', $items); + $this->assertCompletionsListDoesNotContainLabel('TestInterface', $items); + } + /** * Tests completion at `AliasNamespace\I|` with `use TestNamespace\InnerNamespace as AliasNamespace` */