From 17602aa7686a893547aa39641135e935bf52b0bc Mon Sep 17 00:00:00 2001 From: Nicolas MURE Date: Sun, 6 Aug 2017 23:05:32 +0200 Subject: [PATCH] globalDefinitions cache to speedup autocomplete --- src/CompletionProvider.php | 26 ++++++++---------- src/Index/AbstractAggregateIndex.php | 19 ++++++++++++- src/Index/Index.php | 41 ++++++++++++++++++++++++---- src/Index/ReadableIndex.php | 10 ++++++- 4 files changed, 73 insertions(+), 23 deletions(-) diff --git a/src/CompletionProvider.php b/src/CompletionProvider.php index 4e313ad..5934813 100644 --- a/src/CompletionProvider.php +++ b/src/CompletionProvider.php @@ -314,26 +314,22 @@ class CompletionProvider // Suggest global symbols that either // - start with the current namespace + prefix, if the Name node is not fully qualified // - start with just the prefix, if the Name node is fully qualified - foreach ($this->index->getDefinitions() as $fqn => $def) { + foreach ($this->index->getGlobalDefinitions() as $fqn => $def) { $fqnStartsWithPrefix = substr($fqn, 0, $prefixLen) === $prefix; if ( - // Exclude methods, properties etc. - !$def->isMember - && ( - !$prefix + !$prefix + || ( + // Either not qualified, but a matching prefix with global fallback + ($def->roamed && !$isQualified && $fqnStartsWithPrefix) + // Or not in a namespace or a fully qualified name or AND matching the prefix + || ((!$namespaceNode || $isFullyQualified) && $fqnStartsWithPrefix) + // Or in a namespace, not fully qualified and matching the prefix + current namespace || ( - // Either not qualified, but a matching prefix with global fallback - ($def->roamed && !$isQualified && $fqnStartsWithPrefix) - // Or not in a namespace or a fully qualified name or AND matching the prefix - || ((!$namespaceNode || $isFullyQualified) && $fqnStartsWithPrefix) - // Or in a namespace, not fully qualified and matching the prefix + current namespace - || ( - $namespaceNode - && !$isFullyQualified - && substr($fqn, 0, $namespacedPrefixLen) === $namespacedPrefix - ) + $namespaceNode + && !$isFullyQualified + && substr($fqn, 0, $namespacedPrefixLen) === $namespacedPrefix ) ) // Only suggest classes for `new` diff --git a/src/Index/AbstractAggregateIndex.php b/src/Index/AbstractAggregateIndex.php index fa13d14..038117a 100644 --- a/src/Index/AbstractAggregateIndex.php +++ b/src/Index/AbstractAggregateIndex.php @@ -100,7 +100,7 @@ abstract class AbstractAggregateIndex implements ReadableIndex /** * Returns an associative array [string => Definition] that maps fully qualified symbol names - * to Definitions + * to Definitions (global or not) * * @return Definition[] */ @@ -115,6 +115,23 @@ abstract class AbstractAggregateIndex implements ReadableIndex return $defs; } + /** + * Returns an associative array [string => Definition] that maps fully qualified symbol names + * to global Definitions + * + * @return Definition[] + */ + public function getGlobalDefinitions(): array + { + $defs = []; + foreach ($this->getIndexes() as $index) { + foreach ($index->getGlobalDefinitions() as $fqn => $def) { + $defs[$fqn] = $def; + } + } + return $defs; + } + /** * Returns the Definitions that are in the given namespace * diff --git a/src/Index/Index.php b/src/Index/Index.php index 8af0688..e33bc3c 100644 --- a/src/Index/Index.php +++ b/src/Index/Index.php @@ -15,12 +15,19 @@ class Index implements ReadableIndex, \Serializable use EmitterTrait; /** - * An associative array that maps fully qualified symbol names to Definitions + * An associative array that maps fully qualified symbol names to Definitions (global or not) * * @var Definition[] */ private $definitions = []; + /** + * An associative array that maps fully qualified symbol names to global Definitions + * + * @var Definition[] + */ + private $globalDefinitions = []; + /** * An associative array that maps namespaces to an associative array of FQN to Definitions * @@ -92,7 +99,7 @@ class Index implements ReadableIndex, \Serializable /** * Returns an associative array [string => Definition] that maps fully qualified symbol names - * to Definitions + * to Definitions (global or not) * * @return Definition[] */ @@ -101,6 +108,17 @@ class Index implements ReadableIndex, \Serializable return $this->definitions; } + /** + * Returns an associative array [string => Definition] that maps fully qualified symbol names + * to global Definitions + * + * @return Definition[] + */ + public function getGlobalDefinitions(): array + { + return $this->globalDefinitions; + } + /** * Returns the Definitions that are in the given namespace * @@ -144,6 +162,7 @@ class Index implements ReadableIndex, \Serializable public function setDefinition(string $fqn, Definition $definition) { $this->definitions[$fqn] = $definition; + $this->setGlobalDefinition($fqn, $definition); $this->setNamespaceDefinition($fqn, $definition); $this->emit('definition-added'); } @@ -158,6 +177,7 @@ class Index implements ReadableIndex, \Serializable public function removeDefinition(string $fqn) { unset($this->definitions[$fqn]); + unset($this->globalDefinitions[$fqn]); unset($this->references[$fqn]); $this->removeNamespaceDefinition($fqn); } @@ -227,10 +247,15 @@ class Index implements ReadableIndex, \Serializable public function unserialize($serialized) { $data = unserialize($serialized); + foreach ($data as $prop => $val) { $this->$prop = $val; } - $this->buildNamespaceDefinitionsIndex(); + + foreach ($this->definitions as $fqn => $definition) { + $this->setGlobalDefinition($fqn, $definition); + $this->setNamespaceDefinition($fqn, $definition); + } } /** @@ -248,12 +273,16 @@ class Index implements ReadableIndex, \Serializable } /** + * Registers a definition to the global definitions index if it is global + * + * @param string $fqn The fully qualified name of the symbol + * @param Definition $definition The Definition object * @return void */ - private function buildNamespaceDefinitionsIndex() + private function setGlobalDefinition(string $fqn, Definition $definition) { - foreach ($this->definitions as $fqn => $definition) { - $this->setNamespaceDefinition($fqn, $definition); + if ($definition->isGlobal) { + $this->globalDefinitions[$fqn] = $definition; } } diff --git a/src/Index/ReadableIndex.php b/src/Index/ReadableIndex.php index c7d5732..62b9c06 100644 --- a/src/Index/ReadableIndex.php +++ b/src/Index/ReadableIndex.php @@ -31,12 +31,20 @@ interface ReadableIndex extends EmitterInterface /** * Returns an associative array [string => Definition] that maps fully qualified symbol names - * to Definitions + * to Definitions (global or not) * * @return Definitions[] */ public function getDefinitions(): array; + /** + * Returns an associative array [string => Definition] that maps fully qualified symbol names + * to global Definitions + * + * @return Definitions[] + */ + public function getGlobalDefinitions(): array; + /** * Returns the Definitions that are in the given namespace *