1
0
Fork 0

globalDefinitions cache to speedup autocomplete

pull/451/head
Nicolas MURE 2017-08-06 23:05:32 +02:00
parent 18f2f4c85c
commit 17602aa768
No known key found for this signature in database
GPG Key ID: E5B036F9145C4CAA
4 changed files with 73 additions and 23 deletions

View File

@ -314,26 +314,22 @@ class CompletionProvider
// Suggest global symbols that either // Suggest global symbols that either
// - start with the current namespace + prefix, if the Name node is not fully qualified // - 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 // - 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; $fqnStartsWithPrefix = substr($fqn, 0, $prefixLen) === $prefix;
if ( if (
// Exclude methods, properties etc. !$prefix
!$def->isMember || (
&& ( // Either not qualified, but a matching prefix with global fallback
!$prefix ($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 $namespaceNode
($def->roamed && !$isQualified && $fqnStartsWithPrefix) && !$isFullyQualified
// Or not in a namespace or a fully qualified name or AND matching the prefix && substr($fqn, 0, $namespacedPrefixLen) === $namespacedPrefix
|| ((!$namespaceNode || $isFullyQualified) && $fqnStartsWithPrefix)
// Or in a namespace, not fully qualified and matching the prefix + current namespace
|| (
$namespaceNode
&& !$isFullyQualified
&& substr($fqn, 0, $namespacedPrefixLen) === $namespacedPrefix
)
) )
) )
// Only suggest classes for `new` // Only suggest classes for `new`

View File

@ -100,7 +100,7 @@ abstract class AbstractAggregateIndex implements ReadableIndex
/** /**
* Returns an associative array [string => Definition] that maps fully qualified symbol names * Returns an associative array [string => Definition] that maps fully qualified symbol names
* to Definitions * to Definitions (global or not)
* *
* @return Definition[] * @return Definition[]
*/ */
@ -115,6 +115,23 @@ abstract class AbstractAggregateIndex implements ReadableIndex
return $defs; 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 * Returns the Definitions that are in the given namespace
* *

View File

@ -15,12 +15,19 @@ class Index implements ReadableIndex, \Serializable
use EmitterTrait; 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[] * @var Definition[]
*/ */
private $definitions = []; 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 * 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 * Returns an associative array [string => Definition] that maps fully qualified symbol names
* to Definitions * to Definitions (global or not)
* *
* @return Definition[] * @return Definition[]
*/ */
@ -101,6 +108,17 @@ class Index implements ReadableIndex, \Serializable
return $this->definitions; 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 * 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) public function setDefinition(string $fqn, Definition $definition)
{ {
$this->definitions[$fqn] = $definition; $this->definitions[$fqn] = $definition;
$this->setGlobalDefinition($fqn, $definition);
$this->setNamespaceDefinition($fqn, $definition); $this->setNamespaceDefinition($fqn, $definition);
$this->emit('definition-added'); $this->emit('definition-added');
} }
@ -158,6 +177,7 @@ class Index implements ReadableIndex, \Serializable
public function removeDefinition(string $fqn) public function removeDefinition(string $fqn)
{ {
unset($this->definitions[$fqn]); unset($this->definitions[$fqn]);
unset($this->globalDefinitions[$fqn]);
unset($this->references[$fqn]); unset($this->references[$fqn]);
$this->removeNamespaceDefinition($fqn); $this->removeNamespaceDefinition($fqn);
} }
@ -227,10 +247,15 @@ class Index implements ReadableIndex, \Serializable
public function unserialize($serialized) public function unserialize($serialized)
{ {
$data = unserialize($serialized); $data = unserialize($serialized);
foreach ($data as $prop => $val) { foreach ($data as $prop => $val) {
$this->$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 * @return void
*/ */
private function buildNamespaceDefinitionsIndex() private function setGlobalDefinition(string $fqn, Definition $definition)
{ {
foreach ($this->definitions as $fqn => $definition) { if ($definition->isGlobal) {
$this->setNamespaceDefinition($fqn, $definition); $this->globalDefinitions[$fqn] = $definition;
} }
} }

View File

@ -31,12 +31,20 @@ interface ReadableIndex extends EmitterInterface
/** /**
* Returns an associative array [string => Definition] that maps fully qualified symbol names * Returns an associative array [string => Definition] that maps fully qualified symbol names
* to Definitions * to Definitions (global or not)
* *
* @return Definitions[] * @return Definitions[]
*/ */
public function getDefinitions(): array; 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 * Returns the Definitions that are in the given namespace
* *