From ac0fef80c3e340887ec07c2f1eac4ab15c8bdf23 Mon Sep 17 00:00:00 2001 From: Felix Becker Date: Thu, 20 Oct 2016 02:01:01 +0200 Subject: [PATCH] Hold SymbolInformation table in memory --- src/NodeVisitor/DefinitionCollector.php | 15 ++++++++++++-- src/PhpDocument.php | 24 +++++++++++++++++++--- src/Project.php | 27 +++++++++++++------------ src/Server/TextDocument.php | 6 +----- src/Server/Workspace.php | 9 ++++++--- 5 files changed, 55 insertions(+), 26 deletions(-) diff --git a/src/NodeVisitor/DefinitionCollector.php b/src/NodeVisitor/DefinitionCollector.php index f902fbf..a723bdc 100644 --- a/src/NodeVisitor/DefinitionCollector.php +++ b/src/NodeVisitor/DefinitionCollector.php @@ -4,6 +4,7 @@ declare(strict_types = 1); namespace LanguageServer\NodeVisitor; use PhpParser\{NodeVisitorAbstract, Node}; +use LanguageServer\Protocol\SymbolInformation; use function LanguageServer\Fqn\getDefinedFqn; /** @@ -19,11 +20,21 @@ class DefinitionCollector extends NodeVisitorAbstract */ public $definitions = []; + /** + * Map from FQN to SymbolInformation + * + * @var SymbolInformation + */ + public $symbols = []; + public function enterNode(Node $node) { $fqn = getDefinedFqn($node); - if ($fqn !== null) { - $this->definitions[$fqn] = $node; + if ($fqn === null) { + return; } + $this->definitions[$fqn] = $node; + $symbol = SymbolInformation::fromNode($node, $fqn); + $this->symbols[$fqn] = $symbol; } } diff --git a/src/PhpDocument.php b/src/PhpDocument.php index 0a97ca2..02bb854 100644 --- a/src/PhpDocument.php +++ b/src/PhpDocument.php @@ -85,6 +85,13 @@ class PhpDocument */ private $references; + /** + * Map from fully qualified name (FQN) to SymbolInformation + * + * @var SymbolInformation[] + */ + private $symbols; + /** * @param string $uri The URI of the document * @param string $content The content of the document @@ -181,13 +188,14 @@ class PhpDocument // Unregister old definitions if (isset($this->definitions)) { foreach ($this->definitions as $fqn => $node) { - $this->project->removeDefinition($fqn); + $this->project->removeSymbol($fqn); } } // Register this document on the project for all the symbols defined in it $this->definitions = $definitionCollector->definitions; - foreach ($definitionCollector->definitions as $fqn => $node) { - $this->project->setDefinitionUri($fqn, $this->uri); + $this->symbols = $definitionCollector->symbols; + foreach ($definitionCollector->symbols as $fqn => $symbol) { + $this->project->setSymbol($fqn, $symbol); } // Unregister old references @@ -287,6 +295,16 @@ class PhpDocument return $this->definitions; } + /** + * Returns a map from fully qualified name (FQN) to SymbolInformation + * + * @return SymbolInformation[] + */ + public function getSymbols() + { + return $this->symbols; + } + /** * Returns true if the given FQN is defined in this document * diff --git a/src/Project.php b/src/Project.php index 2cb0162..769a4d2 100644 --- a/src/Project.php +++ b/src/Project.php @@ -3,6 +3,7 @@ declare(strict_types = 1); namespace LanguageServer; +use LanguageServer\Protocol\SymbolInformation; use phpDocumentor\Reflection\DocBlockFactory; use PhpParser\{ParserFactory, Lexer}; @@ -17,11 +18,11 @@ class Project private $documents = []; /** - * An associative array that maps fully qualified symbol names to document URIs that define the symbol + * An associative array that maps fully qualified symbol names to SymbolInformations * - * @var string[] + * @var SymbolInformation[] */ - private $definitions = []; + private $symbols = []; /** * An associative array that maps fully qualified symbol names to arrays of document URIs that reference the symbol @@ -140,34 +141,34 @@ class Project * Returns an associative array [string => string] that maps fully qualified symbol names * to URIs of the document where the symbol is defined * - * @return PhpDocument[] + * @return SymbolInformation[] */ - public function getDefinitionUris() + public function getSymbols() { - return $this->definitions; + return $this->symbols; } /** - * Adds a document URI as the container for a specific symbol + * Adds a SymbolInformation for a specific symbol * * @param string $fqn The fully qualified name of the symbol * @param string $uri The URI * @return void */ - public function setDefinitionUri(string $fqn, string $uri) + public function setSymbol(string $fqn, SymbolInformation $symbol) { - $this->definitions[$fqn] = $uri; + $this->symbols[$fqn] = $symbol; } /** - * Unsets a document URI as the container for a specific symbol + * Unsets the SymbolInformation for a specific symbol * and removes all references pointing to that symbol * * @param string $fqn The fully qualified name of the symbol * @return void */ - public function removeDefinition(string $fqn) { - unset($this->definitions[$fqn]); + public function removeSymbol(string $fqn) { + unset($this->symbols[$fqn]); unset($this->references[$fqn]); } @@ -228,7 +229,7 @@ class Project */ public function getDefinitionDocument(string $fqn) { - return isset($this->definitions[$fqn]) ? $this->getDocument($this->definitions[$fqn]) : null; + return isset($this->symbols[$fqn]) ? $this->getDocument($this->symbols[$fqn]->location->uri) : null; } /** diff --git a/src/Server/TextDocument.php b/src/Server/TextDocument.php index e515e43..188e629 100644 --- a/src/Server/TextDocument.php +++ b/src/Server/TextDocument.php @@ -59,11 +59,7 @@ class TextDocument */ public function documentSymbol(TextDocumentIdentifier $textDocument): array { - $symbols = []; - foreach ($this->project->getDocument($textDocument->uri)->getDefinitions() as $fqn => $node) { - $symbols[] = SymbolInformation::fromNode($node, $fqn); - } - return $symbols; + return array_values($this->project->getDocument($textDocument->uri)->getSymbols()); } /** diff --git a/src/Server/Workspace.php b/src/Server/Workspace.php index 44ee50e..e894c49 100644 --- a/src/Server/Workspace.php +++ b/src/Server/Workspace.php @@ -39,10 +39,13 @@ class Workspace */ public function symbol(string $query): array { + if ($query === '') { + return array_values($this->project->getSymbols()); + } $symbols = []; - foreach ($this->project->getDefinitionUris() as $fqn => $uri) { - if ($query === '' || stripos($fqn, $query) !== false) { - $symbols[] = SymbolInformation::fromNode($this->project->getDocument($uri)->getDefinitionByFqn($fqn), $fqn); + foreach ($this->project->getSymbols() as $fqn => $symbol) { + if (stripos($fqn, $query) !== false) { + $symbols[] = $symbol; } } return $symbols;