1
0
Fork 0

moved ancestor generator to Definition

pull/421/head
Ivan Bozhanov 2017-07-06 19:29:13 +03:00
parent 9fb18413f5
commit 56d95102d8
3 changed files with 54 additions and 24 deletions

View File

@ -201,7 +201,7 @@ class CompletionProvider
); );
// Include parent classes // Include parent classes
$prefixes = $this->expandParentFqns($prefixes); $prefixes = iterator_to_array($this->expandParentFqns($prefixes), false);
// Add the object access operator to only get members // Add the object access operator to only get members
foreach ($prefixes as &$prefix) { foreach ($prefixes as &$prefix) {
@ -237,7 +237,7 @@ class CompletionProvider
); );
// Add parent classes // Add parent classes
$prefixes = $this->expandParentFqns($prefixes); $prefixes = iterator_to_array($this->expandParentFqns($prefixes), false);
// Append :: operator to only get static members // Append :: operator to only get static members
foreach ($prefixes as &$prefix) { foreach ($prefixes as &$prefix) {
@ -382,18 +382,15 @@ class CompletionProvider
* @param string[] $fqns * @param string[] $fqns
* @return string[] * @return string[]
*/ */
private function expandParentFqns(array $fqns): array private function expandParentFqns(array $fqns)
{ {
$expanded = $fqns;
foreach ($fqns as $fqn) { foreach ($fqns as $fqn) {
yield $fqn;
$def = $this->index->getDefinition($fqn); $def = $this->index->getDefinition($fqn);
if ($def) { if ($def !== null) {
foreach ($this->expandParentFqns($def->extends ?? []) as $parent) { yield from $def->getAncestorFQNs($this->index);
$expanded[] = $parent;
}
} }
} }
return $expanded;
} }
/** /**

View File

@ -3,6 +3,7 @@ declare(strict_types = 1);
namespace LanguageServer; namespace LanguageServer;
use LanguageServer\Index\ReadableIndex;
use phpDocumentor\Reflection\{Types, Type, Fqsen, TypeResolver}; use phpDocumentor\Reflection\{Types, Type, Fqsen, TypeResolver};
use LanguageServer\Protocol\SymbolInformation; use LanguageServer\Protocol\SymbolInformation;
use Exception; use Exception;
@ -95,4 +96,42 @@ class Definition
* @var string * @var string
*/ */
public $documentation; public $documentation;
/**
* Gets the definitons of all ancestor classes
*
* @return Definition[]
*/
public function getAncestorDefinitions(ReadableIndex $index, bool $includeSelf = false)
{
if ($includeSelf) {
yield $this;
}
if (is_array($this->extends)) {
// iterating once, storing the references and iterating again
// guarantees that closest definitions are returned first
$definitions = [];
foreach ($this->extends as $fqn) {
$def = $index->getDefinition($fqn);
if ($def !== null) {
yield $def;
$definitions[] = $def;
}
}
foreach ($definitions as $def) {
yield from $def->getAncestorDefinitions($index);
}
}
}
/**
* Gets the FQNs of all parent classes
*
* @return string[]
*/
public function getAncestorFQNs(ReadableIndex $index, bool $includeSelf = false)
{
foreach ($this->getAncestorDefinitions($index, $includeSelf) as $def) {
yield $def->fqn;
}
}
} }

View File

@ -670,23 +670,17 @@ class DefinitionResolver
if ($expr->parent instanceof Node\Expression\CallExpression) { if ($expr->parent instanceof Node\Expression\CallExpression) {
$add .= '()'; $add .= '()';
} }
$lookupDefinition = function (string $base, string $add) use (&$lookupDefinition) { $classDef = $this->index->getDefinition($classFqn);
$def = $this->index->getDefinition($base . $add); if ($classDef !== null) {
if ($def !== null) { foreach ($classDef->getAncestorFQNs($this->index, true) as $fqn) {
yield $def; $def = $this->index->getDefinition($fqn . $add);
} if ($def !== null) {
$baseDef = $this->index->getDefinition($base); if ($def->type instanceof Types\This) {
if ($baseDef !== null && is_array($baseDef->extends)) { return new Types\Object_(new Fqsen('\\' . $classFqn));
foreach ($baseDef->extends as $name) { }
yield from $lookupDefinition($name, $add); return $def->type;
} }
} }
};
foreach ($lookupDefinition($classFqn, $add) as $def) {
if ($def->type instanceof Types\This) {
return new Types\Object_(new Fqsen('\\' . $classFqn));
}
return $def->type;
} }
} }
} }