1
0
Fork 0

Hold SymbolInformation table in memory (#101)

pull/102/head^2
Felix Becker 2016-10-20 02:08:23 +02:00 committed by GitHub
parent 9cbca1cd7f
commit 1e00275e02
5 changed files with 55 additions and 26 deletions

View File

@ -4,6 +4,7 @@ declare(strict_types = 1);
namespace LanguageServer\NodeVisitor; namespace LanguageServer\NodeVisitor;
use PhpParser\{NodeVisitorAbstract, Node}; use PhpParser\{NodeVisitorAbstract, Node};
use LanguageServer\Protocol\SymbolInformation;
use function LanguageServer\Fqn\getDefinedFqn; use function LanguageServer\Fqn\getDefinedFqn;
/** /**
@ -19,11 +20,21 @@ class DefinitionCollector extends NodeVisitorAbstract
*/ */
public $definitions = []; public $definitions = [];
/**
* Map from FQN to SymbolInformation
*
* @var SymbolInformation
*/
public $symbols = [];
public function enterNode(Node $node) public function enterNode(Node $node)
{ {
$fqn = getDefinedFqn($node); $fqn = getDefinedFqn($node);
if ($fqn !== null) { if ($fqn === null) {
return;
}
$this->definitions[$fqn] = $node; $this->definitions[$fqn] = $node;
} $symbol = SymbolInformation::fromNode($node, $fqn);
$this->symbols[$fqn] = $symbol;
} }
} }

View File

@ -85,6 +85,13 @@ class PhpDocument
*/ */
private $references; private $references;
/**
* Map from fully qualified name (FQN) to SymbolInformation
*
* @var SymbolInformation[]
*/
private $symbols;
/** /**
* @param string $uri The URI of the document * @param string $uri The URI of the document
* @param string $content The content of the document * @param string $content The content of the document
@ -181,13 +188,14 @@ class PhpDocument
// Unregister old definitions // Unregister old definitions
if (isset($this->definitions)) { if (isset($this->definitions)) {
foreach ($this->definitions as $fqn => $node) { 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 // Register this document on the project for all the symbols defined in it
$this->definitions = $definitionCollector->definitions; $this->definitions = $definitionCollector->definitions;
foreach ($definitionCollector->definitions as $fqn => $node) { $this->symbols = $definitionCollector->symbols;
$this->project->setDefinitionUri($fqn, $this->uri); foreach ($definitionCollector->symbols as $fqn => $symbol) {
$this->project->setSymbol($fqn, $symbol);
} }
// Unregister old references // Unregister old references
@ -287,6 +295,16 @@ class PhpDocument
return $this->definitions; 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 * Returns true if the given FQN is defined in this document
* *

View File

@ -3,6 +3,7 @@ declare(strict_types = 1);
namespace LanguageServer; namespace LanguageServer;
use LanguageServer\Protocol\SymbolInformation;
use phpDocumentor\Reflection\DocBlockFactory; use phpDocumentor\Reflection\DocBlockFactory;
use PhpParser\{ParserFactory, Lexer}; use PhpParser\{ParserFactory, Lexer};
@ -17,11 +18,11 @@ class Project
private $documents = []; 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 * 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 * Returns an associative array [string => string] that maps fully qualified symbol names
* to URIs of the document where the symbol is defined * 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 $fqn The fully qualified name of the symbol
* @param string $uri The URI * @param string $uri The URI
* @return void * @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 * and removes all references pointing to that symbol
* *
* @param string $fqn The fully qualified name of the symbol * @param string $fqn The fully qualified name of the symbol
* @return void * @return void
*/ */
public function removeDefinition(string $fqn) { public function removeSymbol(string $fqn) {
unset($this->definitions[$fqn]); unset($this->symbols[$fqn]);
unset($this->references[$fqn]); unset($this->references[$fqn]);
} }
@ -228,7 +229,7 @@ class Project
*/ */
public function getDefinitionDocument(string $fqn) 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;
} }
/** /**

View File

@ -59,11 +59,7 @@ class TextDocument
*/ */
public function documentSymbol(TextDocumentIdentifier $textDocument): array public function documentSymbol(TextDocumentIdentifier $textDocument): array
{ {
$symbols = []; return array_values($this->project->getDocument($textDocument->uri)->getSymbols());
foreach ($this->project->getDocument($textDocument->uri)->getDefinitions() as $fqn => $node) {
$symbols[] = SymbolInformation::fromNode($node, $fqn);
}
return $symbols;
} }
/** /**

View File

@ -39,10 +39,13 @@ class Workspace
*/ */
public function symbol(string $query): array public function symbol(string $query): array
{ {
if ($query === '') {
return array_values($this->project->getSymbols());
}
$symbols = []; $symbols = [];
foreach ($this->project->getDefinitionUris() as $fqn => $uri) { foreach ($this->project->getSymbols() as $fqn => $symbol) {
if ($query === '' || stripos($fqn, $query) !== false) { if (stripos($fqn, $query) !== false) {
$symbols[] = SymbolInformation::fromNode($this->project->getDocument($uri)->getDefinitionByFqn($fqn), $fqn); $symbols[] = $symbol;
} }
} }
return $symbols; return $symbols;