From 91ca99a8670a7652366bf2ef909dc1989b3c1015 Mon Sep 17 00:00:00 2001 From: Felix Becker Date: Thu, 23 Nov 2017 01:20:42 -0800 Subject: [PATCH] Revert "differenciate member and non member definitions" This reverts commit 48bbbb5d14a3d1fc01fce7e48383f0ba1690c2bb. --- src/CompletionProvider.php | 14 +++-- src/Index/AbstractAggregateIndex.php | 10 ++- src/Index/Index.php | 91 +++++---------------------- src/Index/ReadableIndex.php | 6 +- tests/Server/Workspace/SymbolTest.php | 31 ++++----- 5 files changed, 47 insertions(+), 105 deletions(-) diff --git a/src/CompletionProvider.php b/src/CompletionProvider.php index a5f9119..2f22333 100644 --- a/src/CompletionProvider.php +++ b/src/CompletionProvider.php @@ -221,10 +221,10 @@ class CompletionProvider // 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) { + foreach ($this->index->getDescendantDefinitionsForFqn($parentFqn) as $fqn => $def) { // Add the object access operator to only get members of all parents $prefix = $parentFqn . '->'; - if (substr($fqn, 0, strlen($prefix)) === $prefix) { + if (substr($fqn, 0, strlen($prefix)) === $prefix && $def->isMember) { $list->items[] = CompletionItem::fromDefinition($def); } } @@ -251,10 +251,10 @@ class CompletionProvider // 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) { + foreach ($this->index->getDescendantDefinitionsForFqn($parentFqn) as $fqn => $def) { // Append :: operator to only get static members of all parents $prefix = strtolower($parentFqn . '::'); - if (substr(strtolower($fqn), 0, strlen($prefix)) === $prefix) { + if (substr(strtolower($fqn), 0, strlen($prefix)) === $prefix && $def->isMember) { $list->items[] = CompletionItem::fromDefinition($def); } } @@ -321,12 +321,14 @@ class CompletionProvider // 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(false) as $fqn => $def) { + foreach ($this->index->getDefinitions() 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 diff --git a/src/Index/AbstractAggregateIndex.php b/src/Index/AbstractAggregateIndex.php index 3458d55..90490ab 100644 --- a/src/Index/AbstractAggregateIndex.php +++ b/src/Index/AbstractAggregateIndex.php @@ -102,13 +102,12 @@ abstract class AbstractAggregateIndex implements ReadableIndex * Returns a Generator providing an associative array [string => Definition] * that maps fully qualified symbol names to Definitions (global or not) * - * @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(bool $member = null): \Generator + public function getDefinitions(): \Generator { foreach ($this->getIndexes() as $index) { - yield from $index->getDefinitions($member); + yield from $index->getDefinitions(); } } @@ -116,13 +115,12 @@ abstract class AbstractAggregateIndex implements ReadableIndex * 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 + public function getDescendantDefinitionsForFqn(string $fqn): \Generator { foreach ($this->getIndexes() as $index) { - yield from $index->getDescendantDefinitionsForFqn($fqn, $member); + yield from $index->getDescendantDefinitionsForFqn($fqn); } } diff --git a/src/Index/Index.php b/src/Index/Index.php index 1099fab..dcb1b8f 100644 --- a/src/Index/Index.php +++ b/src/Index/Index.php @@ -16,12 +16,13 @@ class Index implements ReadableIndex, \Serializable /** * An associative array that maps splitted fully qualified symbol names - * to non-member definitions, eg : + * to definitions, eg : * [ * 'Psr' => [ * '\Log' => [ * '\LoggerInterface' => [ - * '' => $definition, + * '' => $def1, // definition for 'Psr\Log\LoggerInterface' which is non-member + * '->log()' => $def2, // definition for 'Psr\Log\LoggerInterface->log()' which is a member definition * ], * ], * ], @@ -29,24 +30,7 @@ class Index implements ReadableIndex, \Serializable * * @var array */ - private $nonMemberDefinitions = []; - - /** - * An associative array that maps splitted fully qualified symbol names - * to member definitions, eg : - * [ - * 'Psr' => [ - * '\Log' => [ - * '\LoggerInterface' => [ - * '->log()' => $definition, - * ], - * ], - * ], - * ] - * - * @var array - */ - private $memberDefinitions = []; + private $definitions = []; /** * An associative array that maps fully qualified symbol names @@ -115,29 +99,20 @@ class Index implements ReadableIndex, \Serializable * Returns a Generator providing an associative array [string => Definition] * that maps fully qualified symbol names to Definitions (global or not) * - * @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(bool $member = null): \Generator + public function getDefinitions(): \Generator { - if (true === $member) { - yield from $this->yieldDefinitionsRecursively($this->memberDefinitions); - } elseif (false === $member) { - yield from $this->yieldDefinitionsRecursively($this->nonMemberDefinitions); - } else { - yield from $this->yieldDefinitionsRecursively($this->memberDefinitions); - yield from $this->yieldDefinitionsRecursively($this->nonMemberDefinitions); - } + yield from $this->yieldDefinitionsRecursively($this->definitions); } /** * 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 + public function getDescendantDefinitionsForFqn(string $fqn): \Generator { $parts = $this->splitFqn($fqn); if ('' === end($parts)) { @@ -146,13 +121,12 @@ class Index implements ReadableIndex, \Serializable array_pop($parts); } - if (true === $member) { - yield from $this->doGetDescendantDefinitionsForFqn($fqn, $parts, $this->memberDefinitions); - } elseif (false === $member) { - yield from $this->doGetDescendantDefinitionsForFqn($fqn, $parts, $this->nonMemberDefinitions); - } else { - yield from $this->doGetDescendantDefinitionsForFqn($fqn, $parts, $this->memberDefinitions); - yield from $this->doGetDescendantDefinitionsForFqn($fqn, $parts, $this->nonMemberDefinitions); + $result = $this->getIndexValue($parts, $this->definitions); + + if ($result instanceof Definition) { + yield $fqn => $result; + } elseif (is_array($result)) { + yield from $this->yieldDefinitionsRecursively($result, $fqn); } } @@ -166,13 +140,8 @@ class Index implements ReadableIndex, \Serializable public function getDefinition(string $fqn, bool $globalFallback = false) { $parts = $this->splitFqn($fqn); + $result = $this->getIndexValue($parts, $this->definitions); - $result = $this->getIndexValue($parts, $this->memberDefinitions); - if ($result instanceof Definition) { - return $result; - } - - $result = $this->getIndexValue($parts, $this->nonMemberDefinitions); if ($result instanceof Definition) { return $result; } @@ -195,12 +164,7 @@ class Index implements ReadableIndex, \Serializable public function setDefinition(string $fqn, Definition $definition) { $parts = $this->splitFqn($fqn); - - if ($definition->isMember) { - $this->indexDefinition(0, $parts, $this->memberDefinitions, $definition); - } else { - $this->indexDefinition(0, $parts, $this->nonMemberDefinitions, $definition); - } + $this->indexDefinition(0, $parts, $this->definitions, $definition); $this->emit('definition-added'); } @@ -215,8 +179,7 @@ class Index implements ReadableIndex, \Serializable public function removeDefinition(string $fqn) { $parts = $this->splitFqn($fqn); - $this->removeIndexedDefinition(0, $parts, $this->memberDefinitions, $this->memberDefinitions); - $this->removeIndexedDefinition(0, $parts, $this->nonMemberDefinitions, $this->nonMemberDefinitions); + $this->removeIndexedDefinition(0, $parts, $this->definitions, $this->definitions); unset($this->references[$fqn]); } @@ -316,26 +279,6 @@ class Index implements ReadableIndex, \Serializable ]); } - /** - * Returns a Generator that yields all the descendant Definitions of a given FQN - * in the given definition index. - * - * @param string $fqn - * @param string[] $parts The splitted FQN - * @param array &$storage The definitions index to look into - * @return \Generator yields Definition - */ - private function doGetDescendantDefinitionsForFqn(string $fqn, array $parts, array &$storage): \Generator - { - $result = $this->getIndexValue($parts, $storage); - - if ($result instanceof Definition) { - yield $fqn => $result; - } elseif (is_array($result)) { - yield from $this->yieldDefinitionsRecursively($result, $fqn); - } - } - /** * Returns a Generator that yields all the Definitions in the given $storage recursively. * The generator yields key => value pairs, e.g. @@ -488,7 +431,7 @@ class Index implements ReadableIndex, \Serializable $this->removeIndexedDefinition(0, array_slice($parts, 0, $level), $rootStorage, $rootStorage); } } - } elseif (isset($storage[$part])) { + } else { $this->removeIndexedDefinition($level + 1, $parts, $storage[$part], $rootStorage); } } diff --git a/src/Index/ReadableIndex.php b/src/Index/ReadableIndex.php index d02f22b..90ddcc4 100644 --- a/src/Index/ReadableIndex.php +++ b/src/Index/ReadableIndex.php @@ -33,19 +33,17 @@ interface ReadableIndex extends EmitterInterface * Returns a Generator providing an associative array [string => Definition] * that maps fully qualified symbol names to Definitions (global or not) * - * @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(bool $member = null): \Generator; + public function getDefinitions(): \Generator; /** * 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; + public function getDescendantDefinitionsForFqn(string $fqn): \Generator; /** * Returns the Definition object by a specific FQN diff --git a/tests/Server/Workspace/SymbolTest.php b/tests/Server/Workspace/SymbolTest.php index 02de5ab..765841b 100644 --- a/tests/Server/Workspace/SymbolTest.php +++ b/tests/Server/Workspace/SymbolTest.php @@ -30,40 +30,41 @@ class SymbolTest extends ServerTestCase // @codingStandardsIgnoreStart $this->assertEquals([ - // member + new SymbolInformation('TestNamespace', SymbolKind::NAMESPACE, new Location($referencesUri, new Range(new Position(2, 0), new Position(2, 24))), ''), + // Namespaced + new SymbolInformation('TEST_CONST', SymbolKind::CONSTANT, $this->getDefinitionLocation('TestNamespace\\TEST_CONST'), 'TestNamespace'), + new SymbolInformation('TestClass', SymbolKind::CLASS_, $this->getDefinitionLocation('TestNamespace\\TestClass'), 'TestNamespace'), new SymbolInformation('TEST_CLASS_CONST', SymbolKind::CONSTANT, $this->getDefinitionLocation('TestNamespace\\TestClass::TEST_CLASS_CONST'), 'TestNamespace\\TestClass'), new SymbolInformation('staticTestProperty', SymbolKind::PROPERTY, $this->getDefinitionLocation('TestNamespace\\TestClass::staticTestProperty'), 'TestNamespace\\TestClass'), new SymbolInformation('testProperty', SymbolKind::PROPERTY, $this->getDefinitionLocation('TestNamespace\\TestClass::testProperty'), 'TestNamespace\\TestClass'), new SymbolInformation('staticTestMethod', SymbolKind::METHOD, $this->getDefinitionLocation('TestNamespace\\TestClass::staticTestMethod()'), 'TestNamespace\\TestClass'), new SymbolInformation('testMethod', SymbolKind::METHOD, $this->getDefinitionLocation('TestNamespace\\TestClass::testMethod()'), 'TestNamespace\\TestClass'), - new SymbolInformation('__construct', SymbolKind::CONSTRUCTOR, $this->getDefinitionLocation('TestNamespace\\Example::__construct'), 'TestNamespace\\Example'), - new SymbolInformation('__destruct', SymbolKind::CONSTRUCTOR, $this->getDefinitionLocation('TestNamespace\\Example::__destruct'), 'TestNamespace\\Example'), - new SymbolInformation('TEST_CLASS_CONST', SymbolKind::CONSTANT, $this->getDefinitionLocation('TestClass::TEST_CLASS_CONST'), 'TestClass'), - new SymbolInformation('staticTestProperty', SymbolKind::PROPERTY, $this->getDefinitionLocation('TestClass::staticTestProperty'), 'TestClass'), - new SymbolInformation('testProperty', SymbolKind::PROPERTY, $this->getDefinitionLocation('TestClass::testProperty'), 'TestClass'), - new SymbolInformation('staticTestMethod', SymbolKind::METHOD, $this->getDefinitionLocation('TestClass::staticTestMethod()'), 'TestClass'), - new SymbolInformation('testMethod', SymbolKind::METHOD, $this->getDefinitionLocation('TestClass::testMethod()'), 'TestClass'), - // non member - new SymbolInformation('TEST_DEFINE_CONSTANT', SymbolKind::CONSTANT, $this->getDefinitionLocation('TEST_DEFINE_CONSTANT'), ''), - new SymbolInformation('unusedProperty', SymbolKind::PROPERTY, $this->getDefinitionLocation('UnusedClass::unusedProperty'), 'UnusedClass'), - new SymbolInformation('unusedMethod', SymbolKind::METHOD, $this->getDefinitionLocation('UnusedClass::unusedMethod'), 'UnusedClass'), - new SymbolInformation('TestNamespace', SymbolKind::NAMESPACE, new Location($referencesUri, new Range(new Position(2, 0), new Position(2, 24))), ''), - new SymbolInformation('TEST_CONST', SymbolKind::CONSTANT, $this->getDefinitionLocation('TestNamespace\\TEST_CONST'), 'TestNamespace'), - new SymbolInformation('TestClass', SymbolKind::CLASS_, $this->getDefinitionLocation('TestNamespace\\TestClass'), 'TestNamespace'), new SymbolInformation('TestTrait', SymbolKind::CLASS_, $this->getDefinitionLocation('TestNamespace\\TestTrait'), 'TestNamespace'), new SymbolInformation('TestInterface', SymbolKind::INTERFACE, $this->getDefinitionLocation('TestNamespace\\TestInterface'), 'TestNamespace'), new SymbolInformation('test_function', SymbolKind::FUNCTION, $this->getDefinitionLocation('TestNamespace\\test_function()'), 'TestNamespace'), new SymbolInformation('ChildClass', SymbolKind::CLASS_, $this->getDefinitionLocation('TestNamespace\\ChildClass'), 'TestNamespace'), new SymbolInformation('Example', SymbolKind::CLASS_, $this->getDefinitionLocation('TestNamespace\\Example'), 'TestNamespace'), + new SymbolInformation('__construct', SymbolKind::CONSTRUCTOR, $this->getDefinitionLocation('TestNamespace\\Example::__construct'), 'TestNamespace\\Example'), + new SymbolInformation('__destruct', SymbolKind::CONSTRUCTOR, $this->getDefinitionLocation('TestNamespace\\Example::__destruct'), 'TestNamespace\\Example'), new SymbolInformation('whatever', SymbolKind::FUNCTION, $this->getDefinitionLocation('TestNamespace\\whatever()'), 'TestNamespace'), + // Global new SymbolInformation('TEST_CONST', SymbolKind::CONSTANT, $this->getDefinitionLocation('TEST_CONST'), ''), new SymbolInformation('TestClass', SymbolKind::CLASS_, $this->getDefinitionLocation('TestClass'), ''), + new SymbolInformation('TEST_CLASS_CONST', SymbolKind::CONSTANT, $this->getDefinitionLocation('TestClass::TEST_CLASS_CONST'), 'TestClass'), + new SymbolInformation('staticTestProperty', SymbolKind::PROPERTY, $this->getDefinitionLocation('TestClass::staticTestProperty'), 'TestClass'), + new SymbolInformation('testProperty', SymbolKind::PROPERTY, $this->getDefinitionLocation('TestClass::testProperty'), 'TestClass'), + new SymbolInformation('staticTestMethod', SymbolKind::METHOD, $this->getDefinitionLocation('TestClass::staticTestMethod()'), 'TestClass'), + new SymbolInformation('testMethod', SymbolKind::METHOD, $this->getDefinitionLocation('TestClass::testMethod()'), 'TestClass'), new SymbolInformation('TestTrait', SymbolKind::CLASS_, $this->getDefinitionLocation('TestTrait'), ''), new SymbolInformation('TestInterface', SymbolKind::INTERFACE, $this->getDefinitionLocation('TestInterface'), ''), new SymbolInformation('test_function', SymbolKind::FUNCTION, $this->getDefinitionLocation('test_function()'), ''), new SymbolInformation('ChildClass', SymbolKind::CLASS_, $this->getDefinitionLocation('ChildClass'), ''), + new SymbolInformation('TEST_DEFINE_CONSTANT', SymbolKind::CONSTANT, $this->getDefinitionLocation('TEST_DEFINE_CONSTANT'), ''), new SymbolInformation('UnusedClass', SymbolKind::CLASS_, $this->getDefinitionLocation('UnusedClass'), ''), + new SymbolInformation('unusedProperty', SymbolKind::PROPERTY, $this->getDefinitionLocation('UnusedClass::unusedProperty'), 'UnusedClass'), + new SymbolInformation('unusedMethod', SymbolKind::METHOD, $this->getDefinitionLocation('UnusedClass::unusedMethod'), 'UnusedClass'), new SymbolInformation('whatever', SymbolKind::FUNCTION, $this->getDefinitionLocation('whatever()'), ''), + new SymbolInformation('SecondTestNamespace', SymbolKind::NAMESPACE, $this->getDefinitionLocation('SecondTestNamespace'), ''), ], $result); // @codingStandardsIgnoreEnd