Skip to content

Autocomplete speedup #451

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 28 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
2d91ee8
speedup autocomplete with ReadableIndex::getDefinitionsForNamespace
nicolasmure Aug 6, 2017
b7c7128
update tests
nicolasmure Aug 6, 2017
6d725a2
speedup static access autocomplete
nicolasmure Aug 6, 2017
18f2f4c
cleanup
nicolasmure Aug 6, 2017
17602aa
globalDefinitions cache to speedup autocomplete
nicolasmure Aug 6, 2017
6d30035
also remove empty namespace index
nicolasmure Aug 8, 2017
ca0caf1
store definitions under the namespaceDefinitions cache key directly
nicolasmure Aug 9, 2017
8768b69
use Generators to get definitions without wasting memory
nicolasmure Aug 9, 2017
8801edb
also yield URIs to save memory
nicolasmure Aug 9, 2017
6a41a7f
add example of indexed definitions
nicolasmure Aug 10, 2017
6a36828
avoid useless array
nicolasmure Aug 10, 2017
e34d8e1
use of null coalescing operator
nicolasmure Aug 10, 2017
14f840b
use correct terminology
nicolasmure Oct 5, 2017
e9fd572
consider the merge of #511
nicolasmure Nov 13, 2017
d1f85f1
use tree representation index
nicolasmure Nov 13, 2017
188a5df
fix definitions storage collision (member / non member)
nicolasmure Nov 14, 2017
cacde1e
use a single array to store definitions
nicolasmure Nov 14, 2017
e162d94
cleanup
nicolasmure Nov 14, 2017
7437d30
Fix formatting
felixfbecker Nov 15, 2017
b118c77
Correct some docblocks
felixfbecker Nov 15, 2017
b3f30f3
cache is backward compatible
nicolasmure Nov 15, 2017
7511e25
Merge branch 'master' into feature/autocomplete-speedup
felixfbecker Nov 15, 2017
fcdf791
use string concatenation instead of sprintf
nicolasmure Nov 16, 2017
3bda390
Merge branch 'master' into feature/autocomplete-speedup
felixfbecker Nov 19, 2017
b03950c
Cleanup
felixfbecker Nov 18, 2017
97ec127
fix definition removal
nicolasmure Nov 19, 2017
48bbbb5
differenciate member and non member definitions
nicolasmure Nov 19, 2017
67dd980
Merge branch 'master' into feature/autocomplete-speedup
felixfbecker Nov 19, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 17 additions & 25 deletions src/CompletionProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -218,16 +218,13 @@ public function provideCompletion(PhpDocument $doc, Position $pos, CompletionCon
$this->definitionResolver->resolveExpressionNodeToType($node->dereferencableExpression)
);

// Add the object access operator to only get members of all parents
$prefixes = [];
foreach ($this->expandParentFqns($fqns) as $prefix) {
$prefixes[] = $prefix . '->';
}

// Collect all definitions that match any of the prefixes
foreach ($this->index->getDefinitions() as $fqn => $def) {
foreach ($prefixes as $prefix) {
if (substr($fqn, 0, strlen($prefix)) === $prefix && $def->isMember) {
// The FQNs of the symbol and its parents (eg the implemented interfaces)
foreach ($this->expandParentFqns($fqns) as $parentFqn) {
// Collect fqn definitions
foreach ($this->index->getDescendantDefinitionsForFqn($parentFqn, true) as $fqn => $def) {
// Add the object access operator to only get members of all parents
$prefix = $parentFqn . '->';
if (substr($fqn, 0, strlen($prefix)) === $prefix) {
$list->items[] = CompletionItem::fromDefinition($def);
}
}
Expand All @@ -251,16 +248,13 @@ public function provideCompletion(PhpDocument $doc, Position $pos, CompletionCon
$classType = $this->definitionResolver->resolveExpressionNodeToType($scoped->scopeResolutionQualifier)
);

// Append :: operator to only get static members of all parents
$prefixes = [];
foreach ($this->expandParentFqns($fqns) as $prefix) {
$prefixes[] = $prefix . '::';
}

// Collect all definitions that match any of the prefixes
foreach ($this->index->getDefinitions() as $fqn => $def) {
foreach ($prefixes as $prefix) {
if (substr(strtolower($fqn), 0, strlen($prefix)) === strtolower($prefix) && $def->isMember) {
// The FQNs of the symbol and its parents (eg the implemented interfaces)
foreach ($this->expandParentFqns($fqns) as $parentFqn) {
// Collect fqn definitions
foreach ($this->index->getDescendantDefinitionsForFqn($parentFqn, true) as $fqn => $def) {
// Append :: operator to only get static members of all parents
$prefix = strtolower($parentFqn . '::');
if (substr(strtolower($fqn), 0, strlen($prefix)) === $prefix) {
$list->items[] = CompletionItem::fromDefinition($def);
}
}
Expand Down Expand Up @@ -324,17 +318,15 @@ public function provideCompletion(PhpDocument $doc, Position $pos, CompletionCon
}
}

// Suggest global symbols that either
// Suggest global (ie non member) 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->getDefinitions(false) as $fqn => $def) {

$fqnStartsWithPrefix = substr($fqn, 0, $prefixLen) === $prefix;

if (
// Exclude methods, properties etc.
!$def->isMember
&& (
(
!$prefix
|| (
// Either not qualified, but a matching prefix with global fallback
Expand Down
41 changes: 24 additions & 17 deletions src/Index/AbstractAggregateIndex.php
Original file line number Diff line number Diff line change
Expand Up @@ -99,20 +99,31 @@ public function isStaticComplete(): bool
}

/**
* Returns an associative array [string => Definition] that maps fully qualified symbol names
* to Definitions
* Returns a Generator providing an associative array [string => Definition]
* that maps fully qualified symbol names to Definitions (global or not)
*
* @return Definition[]
* @param boolean|null $member Indicates if we want member or non-member definitions (null for both, default null)
* @return \Generator yields Definition
*/
public function getDefinitions(): array
public function getDefinitions(bool $member = null): \Generator
{
$defs = [];
foreach ($this->getIndexes() as $index) {
foreach ($index->getDefinitions() as $fqn => $def) {
$defs[$fqn] = $def;
}
yield from $index->getDefinitions($member);
}
}

/**
* Returns a Generator that yields all the descendant Definitions of a given FQN
*
* @param string $fqn
* @param boolean|null $member Indicates if we want member or non-member definitions (null for both, default null)
* @return \Generator yields Definition
*/
public function getDescendantDefinitionsForFqn(string $fqn, bool $member = null): \Generator
{
foreach ($this->getIndexes() as $index) {
yield from $index->getDescendantDefinitionsForFqn($fqn, $member);
}
return $defs;
}

/**
Expand All @@ -132,19 +143,15 @@ public function getDefinition(string $fqn, bool $globalFallback = false)
}

/**
* Returns all URIs in this index that reference a symbol
* Returns a Generator providing all URIs in this index that reference a symbol
*
* @param string $fqn The fully qualified name of the symbol
* @return string[]
* @return \Generator yields string
*/
public function getReferenceUris(string $fqn): array
public function getReferenceUris(string $fqn): \Generator
{
$refs = [];
foreach ($this->getIndexes() as $index) {
foreach ($index->getReferenceUris($fqn) as $ref) {
$refs[] = $ref;
}
yield from $index->getReferenceUris($fqn);
}
return $refs;
}
}
Loading