From 80e6f995ae81fb1eb13e075d2056e8eca6a5f9a3 Mon Sep 17 00:00:00 2001 From: Florian Schunk Date: Thu, 28 Nov 2019 01:22:41 +0100 Subject: [PATCH] fix bugs for rename --- src/Definition.php | 5 +++ src/DefinitionResolver.php | 8 ++++ src/Index/Index.php | 6 +++ src/Server/TextDocument.php | 83 ++++++++++++++++++------------------- 4 files changed, 60 insertions(+), 42 deletions(-) diff --git a/src/Definition.php b/src/Definition.php index d81594d..d101f9f 100644 --- a/src/Definition.php +++ b/src/Definition.php @@ -72,6 +72,11 @@ class Definition */ public $symbolInformation; + /** + * @var Location + */ + public $name; + /** * The type a reference to this symbol will resolve to. * For properties and constants, this is the type of the property/constant. diff --git a/src/DefinitionResolver.php b/src/DefinitionResolver.php index adddf77..f425b97 100644 --- a/src/DefinitionResolver.php +++ b/src/DefinitionResolver.php @@ -5,6 +5,7 @@ namespace LanguageServer; use LanguageServer\Index\ReadableIndex; use LanguageServer\Factory\SymbolInformationFactory; +use LanguageServer\Factory\LocationFactory; use LanguageServerProtocol\SymbolInformation; use Microsoft\PhpParser; use Microsoft\PhpParser\Node; @@ -236,6 +237,13 @@ class DefinitionResolver $def->symbolInformation = SymbolInformationFactory::fromNode($node, $fqn); + if ($node instanceof Node\Statement\ClassDeclaration || + $node instanceof Node\MethodDeclaration) { + $def->name = LocationFactory::fromToken($node, $node->name); + } elseif ($node instanceof Node\Expression\Variable) { + $def->name = LocationFactory::fromToken($node, $node->name); + $def->name->range->start->character++; + } if ($def->symbolInformation !== null) { $def->type = $this->getTypeFromNode($node); $def->declarationLine = $this->getDeclarationLineFromNode($node); diff --git a/src/Index/Index.php b/src/Index/Index.php index 0d61f9c..c72e3e3 100644 --- a/src/Index/Index.php +++ b/src/Index/Index.php @@ -187,6 +187,9 @@ class Index implements ReadableIndex, \Serializable public function removeDefinition(string $fqn) { $parts = $this->splitFqn($fqn); + if (empty($parts)) { + throw new \Exception($fqn); + } $this->removeIndexedDefinition(0, $parts, $this->definitions, $this->definitions); unset($this->references[$fqn]); @@ -423,6 +426,9 @@ class Index implements ReadableIndex, \Serializable */ private function removeIndexedDefinition(int $level, array $parts, array &$storage, array &$rootStorage) { + if (empty($parts)) { + return; + } $part = $parts[$level]; if ($level + 1 === count($parts)) { diff --git a/src/Server/TextDocument.php b/src/Server/TextDocument.php index a2a1935..56c1942 100644 --- a/src/Server/TextDocument.php +++ b/src/Server/TextDocument.php @@ -4,7 +4,7 @@ declare(strict_types = 1); namespace LanguageServer\Server; use LanguageServer\{ - CompletionProvider, SignatureHelpProvider, LanguageClient, PhpDocument, PhpDocumentLoader, DefinitionResolver + CompletionProvider, SignatureHelpProvider, LanguageClient, PhpDocument, PhpDocumentLoader, DefinitionResolver, Definition }; use LanguageServer\Index\ReadableIndex; use LanguageServer\Factory\LocationFactory; @@ -256,41 +256,18 @@ class TextDocument } } } - if ($context->includeDeclaration) { - $refs = $document->getDefinitionNodeByFqn($fqn); - if ($refs !== null) { - if ($refs instanceof Node\Statement\ClassDeclaration) { - if ($refs->name->getText($refs->getFileContents()) === $node->name->getText($node->getFileContents())) { - $location = LocationFactory::fromToken($refs, $refs->name); - $locations[] = $location; - } - } - foreach ($refs as $ref) { - if ($ref !== null) { - if ($ref instanceof Node\Expression\AssignmentExpression) { - $location = LocationFactory::fromNode($ref->leftOperand); - $location->range->start->character++; - $locations[] = $location; - } elseif ($ref instanceof Node\DelimitedList\ExpressionList) { - $location = LocationFactory::fromNode($ref); - $location->range->start->character++; - $locations[] = $location; - } elseif ($ref instanceof Node\ClassMembersNode) { - foreach ($ref->classMemberDeclarations as $declaration) { - if ($declaration instanceof Node\MethodDeclaration) { - if ($declaration->getName() === $name) { - $location = LocationFactory::fromToken($declaration, $declaration->name); - $locations[] = $location; - } - } - } - } - } - } - } + } + if ($context->includeDeclaration) { + $definitionObjects = yield $this->definitionObject($textDocument, $position); + $definitionLocations = $definitionObjects->name; + if (gettype($definitionLocations) == "string") { + throw new \Exception($definitionLocations); } - + if (!is_array($definitionLocations)) { + $definitionLocations = array($definitionLocations); + } + $locations = array_merge($locations, $definitionLocations); } } return $locations; @@ -322,6 +299,20 @@ class TextDocument } $edits[$location->uri][] = $textEdit; } + + foreach ($edits as $uri => $textEdits) { + $document = yield $this->documentLoader->getOrLoad($uri); + $newtext = $document->getContent(); + foreach ($textEdits as $textEdit) { + $startOffset = $textEdit->range->start->toOffset($document->getContent()); + $endOffset = $textEdit->range->end->toOffset($document->getContent()); + $length = $endOffset - $startOffset; + $newtext = substr_replace($newtext, $textEdit->newText, $startOffset, $length); + } + $document->updateContent($newtext); + $this->client->textDocument->publishDiagnostics($uri, $document->getDiagnostics()); + + } return new WorkspaceEdit($edits); }); } @@ -353,6 +344,21 @@ class TextDocument * @return Promise */ public function definition(TextDocumentIdentifier $textDocument, Position $position): Promise + { + return coroutine(function () use ($textDocument, $position) { + $def = yield $this->definitionObject($textDocument, $position); + if ( + $def === null + || $def->symbolInformation === null + || Uri\parse($def->symbolInformation->location->uri)['scheme'] === 'phpstubs' + ) { + return []; + } + return $def->symbolInformation->location; + }); + } + + private function definitionObject(TextDocumentIdentifier $textDocument, Position $position) { return coroutine(function () use ($textDocument, $position) { $document = yield $this->documentLoader->getOrLoad($textDocument->uri); @@ -375,14 +381,7 @@ class TextDocument } yield waitForEvent($this->index, 'definition-added'); } - if ( - $def === null - || $def->symbolInformation === null - || Uri\parse($def->symbolInformation->location->uri)['scheme'] === 'phpstubs' - ) { - return []; - } - return $def->symbolInformation->location; + return $def; }); }