1
0
Fork 0

fix bugs for rename

pull/768/head
Florian Schunk 2019-11-28 01:22:41 +01:00
parent db926f0157
commit 80e6f995ae
4 changed files with 60 additions and 42 deletions

View File

@ -72,6 +72,11 @@ class Definition
*/ */
public $symbolInformation; public $symbolInformation;
/**
* @var Location
*/
public $name;
/** /**
* The type a reference to this symbol will resolve to. * The type a reference to this symbol will resolve to.
* For properties and constants, this is the type of the property/constant. * For properties and constants, this is the type of the property/constant.

View File

@ -5,6 +5,7 @@ namespace LanguageServer;
use LanguageServer\Index\ReadableIndex; use LanguageServer\Index\ReadableIndex;
use LanguageServer\Factory\SymbolInformationFactory; use LanguageServer\Factory\SymbolInformationFactory;
use LanguageServer\Factory\LocationFactory;
use LanguageServerProtocol\SymbolInformation; use LanguageServerProtocol\SymbolInformation;
use Microsoft\PhpParser; use Microsoft\PhpParser;
use Microsoft\PhpParser\Node; use Microsoft\PhpParser\Node;
@ -236,6 +237,13 @@ class DefinitionResolver
$def->symbolInformation = SymbolInformationFactory::fromNode($node, $fqn); $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) { if ($def->symbolInformation !== null) {
$def->type = $this->getTypeFromNode($node); $def->type = $this->getTypeFromNode($node);
$def->declarationLine = $this->getDeclarationLineFromNode($node); $def->declarationLine = $this->getDeclarationLineFromNode($node);

View File

@ -187,6 +187,9 @@ class Index implements ReadableIndex, \Serializable
public function removeDefinition(string $fqn) public function removeDefinition(string $fqn)
{ {
$parts = $this->splitFqn($fqn); $parts = $this->splitFqn($fqn);
if (empty($parts)) {
throw new \Exception($fqn);
}
$this->removeIndexedDefinition(0, $parts, $this->definitions, $this->definitions); $this->removeIndexedDefinition(0, $parts, $this->definitions, $this->definitions);
unset($this->references[$fqn]); unset($this->references[$fqn]);
@ -423,6 +426,9 @@ class Index implements ReadableIndex, \Serializable
*/ */
private function removeIndexedDefinition(int $level, array $parts, array &$storage, array &$rootStorage) private function removeIndexedDefinition(int $level, array $parts, array &$storage, array &$rootStorage)
{ {
if (empty($parts)) {
return;
}
$part = $parts[$level]; $part = $parts[$level];
if ($level + 1 === count($parts)) { if ($level + 1 === count($parts)) {

View File

@ -4,7 +4,7 @@ declare(strict_types = 1);
namespace LanguageServer\Server; namespace LanguageServer\Server;
use LanguageServer\{ use LanguageServer\{
CompletionProvider, SignatureHelpProvider, LanguageClient, PhpDocument, PhpDocumentLoader, DefinitionResolver CompletionProvider, SignatureHelpProvider, LanguageClient, PhpDocument, PhpDocumentLoader, DefinitionResolver, Definition
}; };
use LanguageServer\Index\ReadableIndex; use LanguageServer\Index\ReadableIndex;
use LanguageServer\Factory\LocationFactory; 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 ($context->includeDeclaration) {
if ($ref instanceof Node\Expression\AssignmentExpression) { $definitionObjects = yield $this->definitionObject($textDocument, $position);
$location = LocationFactory::fromNode($ref->leftOperand); $definitionLocations = $definitionObjects->name;
$location->range->start->character++; if (gettype($definitionLocations) == "string") {
$locations[] = $location; throw new \Exception($definitionLocations);
} 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 (!is_array($definitionLocations)) {
$definitionLocations = array($definitionLocations);
}
$locations = array_merge($locations, $definitionLocations);
} }
} }
return $locations; return $locations;
@ -322,6 +299,20 @@ class TextDocument
} }
$edits[$location->uri][] = $textEdit; $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); return new WorkspaceEdit($edits);
}); });
} }
@ -353,6 +344,21 @@ class TextDocument
* @return Promise <Location|Location[]> * @return Promise <Location|Location[]>
*/ */
public function definition(TextDocumentIdentifier $textDocument, Position $position): 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) { return coroutine(function () use ($textDocument, $position) {
$document = yield $this->documentLoader->getOrLoad($textDocument->uri); $document = yield $this->documentLoader->getOrLoad($textDocument->uri);
@ -375,14 +381,7 @@ class TextDocument
} }
yield waitForEvent($this->index, 'definition-added'); yield waitForEvent($this->index, 'definition-added');
} }
if ( return $def;
$def === null
|| $def->symbolInformation === null
|| Uri\parse($def->symbolInformation->location->uri)['scheme'] === 'phpstubs'
) {
return [];
}
return $def->symbolInformation->location;
}); });
} }