From 618f060648e85389ef27c0e9e3cbf7769bb8b3dc Mon Sep 17 00:00:00 2001 From: Ivan Bozhanov Date: Thu, 19 Jan 2017 14:13:32 +0200 Subject: [PATCH] added $this autocompletion --- fixtures/completion/this.php | 15 ++++ fixtures/completion/this_with_prefix.php | 15 ++++ src/CompletionProvider.php | 14 +++- tests/LanguageServerTest.php | 4 +- tests/Server/TextDocument/CompletionTest.php | 84 ++++++++++++++++++++ 5 files changed, 127 insertions(+), 5 deletions(-) create mode 100644 fixtures/completion/this.php create mode 100644 fixtures/completion/this_with_prefix.php diff --git a/fixtures/completion/this.php b/fixtures/completion/this.php new file mode 100644 index 0000000..b3d684c --- /dev/null +++ b/fixtures/completion/this.php @@ -0,0 +1,15 @@ + + } +} diff --git a/fixtures/completion/this_with_prefix.php b/fixtures/completion/this_with_prefix.php new file mode 100644 index 0000000..6325b99 --- /dev/null +++ b/fixtures/completion/this_with_prefix.php @@ -0,0 +1,15 @@ +m + } +} diff --git a/src/CompletionProvider.php b/src/CompletionProvider.php index 99a5d57..d24162c 100644 --- a/src/CompletionProvider.php +++ b/src/CompletionProvider.php @@ -141,9 +141,17 @@ class CompletionProvider // If the name is an Error node, just filter by the class if ($node instanceof Node\Expr\MethodCall || $node instanceof Node\Expr\PropertyFetch) { // For instances, resolve the variable type - $prefixes = DefinitionResolver::getFqnsFromType( - $this->definitionResolver->resolveExpressionNodeToType($node->var) - ); + $classNode = null; + if ($node->var instanceof Node\Expr\Variable && $node->var->name === 'this') { + $classNode = getClosestNode($node, Node\Stmt\Class_::class); + } + if ($classNode !== null && !$classNode->isAnonymous()) { + $prefixes = [(string)$classNode->namespacedName]; + } else { + $prefixes = DefinitionResolver::getFqnsFromType( + $this->definitionResolver->resolveExpressionNodeToType($node->var) + ); + } } else { // Static member reference $prefixes = [$node->class instanceof Node\Name ? (string)$node->class : '']; diff --git a/tests/LanguageServerTest.php b/tests/LanguageServerTest.php index 6bfa3c9..b824427 100644 --- a/tests/LanguageServerTest.php +++ b/tests/LanguageServerTest.php @@ -57,7 +57,7 @@ class LanguageServerTest extends TestCase if ($msg->body->method === 'window/logMessage' && $promise->state === Promise::PENDING) { if ($msg->body->params->type === MessageType::ERROR) { $promise->reject(new Exception($msg->body->params->message)); - } else if (strpos($msg->body->params->message, 'All 25 PHP files parsed') !== false) { + } else if (strpos($msg->body->params->message, 'All 27 PHP files parsed') !== false) { $promise->fulfill(); } } @@ -103,7 +103,7 @@ class LanguageServerTest extends TestCase if ($promise->state === Promise::PENDING) { $promise->reject(new Exception($msg->body->params->message)); } - } else if (strpos($msg->body->params->message, 'All 25 PHP files parsed') !== false) { + } else if (strpos($msg->body->params->message, 'All 27 PHP files parsed') !== false) { if ($run === 1) { $run++; } else { diff --git a/tests/Server/TextDocument/CompletionTest.php b/tests/Server/TextDocument/CompletionTest.php index 15349ed..3711837 100644 --- a/tests/Server/TextDocument/CompletionTest.php +++ b/tests/Server/TextDocument/CompletionTest.php @@ -433,4 +433,88 @@ class CompletionTest extends TestCase ) ], true), $items); } + + public function testThisWithoutPrefix() + { + $completionUri = pathToUri(__DIR__ . '/../../../fixtures/completion/this.php'); + $this->loader->open($completionUri, file_get_contents($completionUri)); + $items = $this->textDocument->completion( + new TextDocumentIdentifier($completionUri), + new Position(12, 15) + )->wait(); + $this->assertEquals(new CompletionList([ + new CompletionItem( + 'foo', + CompletionItemKind::PROPERTY, + 'mixed', // Type of the property + null + ), + new CompletionItem( + 'bar', + CompletionItemKind::PROPERTY, + 'mixed', // Type of the property + null + ), + new CompletionItem( + 'method', + CompletionItemKind::METHOD, + 'mixed', // Return type of the method + null + ), + new CompletionItem( + 'test', + CompletionItemKind::METHOD, + 'mixed', // Return type of the method + null + ) + ], true), $items); + } + + public function testThisWithPrefix() + { + $completionUri = pathToUri(__DIR__ . '/../../../fixtures/completion/this_with_prefix.php'); + $this->loader->open($completionUri, file_get_contents($completionUri)); + $items = $this->textDocument->completion( + new TextDocumentIdentifier($completionUri), + new Position(12, 16) + )->wait(); + $this->assertEquals(new CompletionList([ + new CompletionItem( + 'testProperty', + CompletionItemKind::PROPERTY, + '\TestClass', // Type of the property + 'Reprehenderit magna velit mollit ipsum do.' + ), + new CompletionItem( + 'testMethod', + CompletionItemKind::METHOD, + '\TestClass', // Return type of the method + 'Non culpa nostrud mollit esse sunt laboris in irure ullamco cupidatat amet.' + ), + new CompletionItem( + 'foo', + CompletionItemKind::PROPERTY, + 'mixed', // Type of the property + null + ), + new CompletionItem( + 'bar', + CompletionItemKind::PROPERTY, + 'mixed', // Type of the property + null + ), + new CompletionItem( + 'method', + CompletionItemKind::METHOD, + 'mixed', // Return type of the method + null + ), + new CompletionItem( + 'test', + CompletionItemKind::METHOD, + 'mixed', // Return type of the method + null + ) + ], true), $items); + } }