Add Definition class
parent
c19aedcef2
commit
e83f95efca
|
@ -0,0 +1,94 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace LanguageServer;
|
||||||
|
|
||||||
|
use PhpParser\Node;
|
||||||
|
use phpDocumentor\Reflection\{Types, Type, Fqsen, TypeResolver};
|
||||||
|
use LanguageServer\Protocol\SymbolInformation;
|
||||||
|
use Exception;
|
||||||
|
use function LanguageServer\Fqn\getDefinedFqn;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class used to represent definitions that can be referenced by an FQN
|
||||||
|
*/
|
||||||
|
class Definition
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var Protocol\SymbolInformation
|
||||||
|
*/
|
||||||
|
public $symbolInformation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type a reference to this symbol will resolve to.
|
||||||
|
* For properties and constants, this is the type of the property/constant.
|
||||||
|
* For functions and methods, this is the return type.
|
||||||
|
* For any other declaration it will be null.
|
||||||
|
* Can also be a compound type.
|
||||||
|
* If it is unknown, will be Types\Mixed.
|
||||||
|
*
|
||||||
|
* @var \phpDocumentor\Type
|
||||||
|
*/
|
||||||
|
public $type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the definition defined in a node
|
||||||
|
*
|
||||||
|
* @return self
|
||||||
|
* @throws Exception If the node is not a declaration node
|
||||||
|
*/
|
||||||
|
public static function fromNode(Node $node): self
|
||||||
|
{
|
||||||
|
$def = new self;
|
||||||
|
$def->symbolInformation = SymbolInformation::fromNode($node, getDefinedFqn($node));
|
||||||
|
$def->type = self::getTypeFromNode($node);
|
||||||
|
return $def;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the type a reference to this symbol will resolve to.
|
||||||
|
* For properties and constants, this is the type of the property/constant.
|
||||||
|
* For functions and methods, this is the return type.
|
||||||
|
* For classes and interfaces, this is the class type (object).
|
||||||
|
* Variables are not indexed for performance reasons.
|
||||||
|
* Can also be a compound type.
|
||||||
|
* If it is unknown, will be Types\Mixed.
|
||||||
|
* Returns null if the node does not have a type.
|
||||||
|
*
|
||||||
|
* @param Node $node
|
||||||
|
* @return \phpDocumentor\Type|null
|
||||||
|
*/
|
||||||
|
public static function getTypeFromNode(Node $node)
|
||||||
|
{
|
||||||
|
if ($node instanceof Node\FunctionLike) {
|
||||||
|
// Functions/methods
|
||||||
|
$docBlock = $node->getAttribute('docBlock');
|
||||||
|
if ($docBlock !== null && count($returnTags = $docBlock->getTagsByName('return')) > 0) {
|
||||||
|
// Use @return tag
|
||||||
|
return $returnTags[0]->getType();
|
||||||
|
}
|
||||||
|
if ($node->returnType !== null) {
|
||||||
|
// Use PHP7 return type hint
|
||||||
|
if (is_string($node->returnType)) {
|
||||||
|
// Resolve a string like "integer" to a type object
|
||||||
|
return (new TypeResolver)->resolve($node->returnType);
|
||||||
|
}
|
||||||
|
return new Types\Object_(new Fqsen('\\' . (string)$node->returnType));
|
||||||
|
}
|
||||||
|
// Unknown return type
|
||||||
|
return new Types\Mixed;
|
||||||
|
}
|
||||||
|
if ($node instanceof Node\Stmt\PropertyProperty || $node instanceof Node\Const_) {
|
||||||
|
// Property or constant
|
||||||
|
$docBlock = $node->getAttribute('parentNode')->getAttribute('docBlock');
|
||||||
|
if ($docBlock !== null && count($varTags = $docBlock->getTagsByName('var')) > 0) {
|
||||||
|
// Use @var tag
|
||||||
|
return $varTags[0]->getType();
|
||||||
|
}
|
||||||
|
// TODO: read @property tags of class
|
||||||
|
// TODO: Try to infer the type from default value / constant value
|
||||||
|
// Unknown
|
||||||
|
return new Types\Mixed;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,7 +4,7 @@ declare(strict_types = 1);
|
||||||
namespace LanguageServer\NodeVisitor;
|
namespace LanguageServer\NodeVisitor;
|
||||||
|
|
||||||
use PhpParser\{NodeVisitorAbstract, Node};
|
use PhpParser\{NodeVisitorAbstract, Node};
|
||||||
use LanguageServer\Protocol\SymbolInformation;
|
use LanguageServer\Definition;
|
||||||
use function LanguageServer\Fqn\getDefinedFqn;
|
use function LanguageServer\Fqn\getDefinedFqn;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -14,18 +14,18 @@ use function LanguageServer\Fqn\getDefinedFqn;
|
||||||
class DefinitionCollector extends NodeVisitorAbstract
|
class DefinitionCollector extends NodeVisitorAbstract
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Map from fully qualified name (FQN) to Node
|
* Map from fully qualified name (FQN) to Definition
|
||||||
*
|
*
|
||||||
* @var Node[]
|
* @var Definition[]
|
||||||
*/
|
*/
|
||||||
public $definitions = [];
|
public $definitions = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map from FQN to SymbolInformation
|
* Map from fully qualified name (FQN) to Node
|
||||||
*
|
*
|
||||||
* @var SymbolInformation
|
* @var Node[]
|
||||||
*/
|
*/
|
||||||
public $symbols = [];
|
public $nodes = [];
|
||||||
|
|
||||||
public function enterNode(Node $node)
|
public function enterNode(Node $node)
|
||||||
{
|
{
|
||||||
|
@ -33,8 +33,7 @@ class DefinitionCollector extends NodeVisitorAbstract
|
||||||
if ($fqn === null) {
|
if ($fqn === null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$this->definitions[$fqn] = $node;
|
$this->nodes[$fqn] = $node;
|
||||||
$symbol = SymbolInformation::fromNode($node, $fqn);
|
$this->definitions[$fqn] = Definition::fromNode($node);
|
||||||
$this->symbols[$fqn] = $symbol;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ class ReferencesCollector extends NodeVisitorAbstract
|
||||||
*
|
*
|
||||||
* @var Node[][]
|
* @var Node[][]
|
||||||
*/
|
*/
|
||||||
public $references = [];
|
public $nodes = [];
|
||||||
|
|
||||||
public function enterNode(Node $node)
|
public function enterNode(Node $node)
|
||||||
{
|
{
|
||||||
|
@ -41,9 +41,9 @@ class ReferencesCollector extends NodeVisitorAbstract
|
||||||
|
|
||||||
private function addReference(string $fqn, Node $node)
|
private function addReference(string $fqn, Node $node)
|
||||||
{
|
{
|
||||||
if (!isset($this->references[$fqn])) {
|
if (!isset($this->nodes[$fqn])) {
|
||||||
$this->references[$fqn] = [];
|
$this->nodes[$fqn] = [];
|
||||||
}
|
}
|
||||||
$this->references[$fqn][] = $node;
|
$this->nodes[$fqn][] = $node;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ class VariableReferencesCollector extends NodeVisitorAbstract
|
||||||
*
|
*
|
||||||
* @var Node\Expr\Variable[]
|
* @var Node\Expr\Variable[]
|
||||||
*/
|
*/
|
||||||
public $references = [];
|
public $nodes = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var string
|
||||||
|
@ -33,7 +33,7 @@ class VariableReferencesCollector extends NodeVisitorAbstract
|
||||||
public function enterNode(Node $node)
|
public function enterNode(Node $node)
|
||||||
{
|
{
|
||||||
if ($node instanceof Node\Expr\Variable && $node->name === $this->name) {
|
if ($node instanceof Node\Expr\Variable && $node->name === $this->name) {
|
||||||
$this->references[] = $node;
|
$this->nodes[] = $node;
|
||||||
} else if ($node instanceof Node\FunctionLike) {
|
} else if ($node instanceof Node\FunctionLike) {
|
||||||
// If we meet a function node, dont traverse its statements, they are in another scope
|
// If we meet a function node, dont traverse its statements, they are in another scope
|
||||||
// except it is a closure that has imported the variable through use
|
// except it is a closure that has imported the variable through use
|
||||||
|
|
|
@ -74,26 +74,26 @@ class PhpDocument
|
||||||
*/
|
*/
|
||||||
private $stmts;
|
private $stmts;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map from fully qualified name (FQN) to Definition
|
||||||
|
*
|
||||||
|
* @var Definition[]
|
||||||
|
*/
|
||||||
|
private $definitions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map from fully qualified name (FQN) to Node
|
* Map from fully qualified name (FQN) to Node
|
||||||
*
|
*
|
||||||
* @var Node[]
|
* @var Node[]
|
||||||
*/
|
*/
|
||||||
private $definitions;
|
private $definitionNodes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map from fully qualified name (FQN) to array of nodes that reference the symbol
|
* Map from fully qualified name (FQN) to array of nodes that reference the symbol
|
||||||
*
|
*
|
||||||
* @var Node[][]
|
* @var Node[][]
|
||||||
*/
|
*/
|
||||||
private $references;
|
private $referenceNodes;
|
||||||
|
|
||||||
/**
|
|
||||||
* Map from fully qualified name (FQN) to SymbolInformation
|
|
||||||
*
|
|
||||||
* @var SymbolInformation[]
|
|
||||||
*/
|
|
||||||
private $symbols;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $uri The URI of the document
|
* @param string $uri The URI of the document
|
||||||
|
@ -121,7 +121,7 @@ class PhpDocument
|
||||||
*/
|
*/
|
||||||
public function getReferencesByFqn(string $fqn)
|
public function getReferencesByFqn(string $fqn)
|
||||||
{
|
{
|
||||||
return isset($this->references) && isset($this->references[$fqn]) ? $this->references[$fqn] : null;
|
return isset($this->referenceNodes) && isset($this->referenceNodes[$fqn]) ? $this->referenceNodes[$fqn] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -183,26 +183,26 @@ class PhpDocument
|
||||||
|
|
||||||
// Unregister old definitions
|
// Unregister old definitions
|
||||||
if (isset($this->definitions)) {
|
if (isset($this->definitions)) {
|
||||||
foreach ($this->definitions as $fqn => $node) {
|
foreach ($this->definitions as $fqn => $definition) {
|
||||||
$this->project->removeSymbol($fqn);
|
$this->project->removeDefinition($fqn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Register this document on the project for all the symbols defined in it
|
// Register this document on the project for all the symbols defined in it
|
||||||
$this->definitions = $definitionCollector->definitions;
|
$this->definitions = $definitionCollector->definitions;
|
||||||
$this->symbols = $definitionCollector->symbols;
|
$this->definitionNodes = $definitionCollector->nodes;
|
||||||
foreach ($definitionCollector->symbols as $fqn => $symbol) {
|
foreach ($definitionCollector->definitions as $fqn => $definition) {
|
||||||
$this->project->setSymbol($fqn, $symbol);
|
$this->project->setDefinition($fqn, $definition);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unregister old references
|
// Unregister old references
|
||||||
if (isset($this->references)) {
|
if (isset($this->referenceNodes)) {
|
||||||
foreach ($this->references as $fqn => $node) {
|
foreach ($this->referenceNodes as $fqn => $node) {
|
||||||
$this->project->removeReferenceUri($fqn, $this->uri);
|
$this->project->removeReferenceUri($fqn, $this->uri);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Register this document on the project for references
|
// Register this document on the project for references
|
||||||
$this->references = $referencesCollector->references;
|
$this->referenceNodes = $referencesCollector->nodes;
|
||||||
foreach ($referencesCollector->references as $fqn => $nodes) {
|
foreach ($referencesCollector->nodes as $fqn => $nodes) {
|
||||||
$this->project->addReferenceUri($fqn, $this->uri);
|
$this->project->addReferenceUri($fqn, $this->uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,9 +289,9 @@ class PhpDocument
|
||||||
* @param string $fqn
|
* @param string $fqn
|
||||||
* @return Node|null
|
* @return Node|null
|
||||||
*/
|
*/
|
||||||
public function getDefinitionByFqn(string $fqn)
|
public function getDefinitionNodeByFqn(string $fqn)
|
||||||
{
|
{
|
||||||
return $this->definitions[$fqn] ?? null;
|
return $this->definitionNodes[$fqn] ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -299,19 +299,19 @@ class PhpDocument
|
||||||
*
|
*
|
||||||
* @return Node[]
|
* @return Node[]
|
||||||
*/
|
*/
|
||||||
public function getDefinitions()
|
public function getDefinitionNodes()
|
||||||
{
|
{
|
||||||
return $this->definitions;
|
return $this->definitionNodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a map from fully qualified name (FQN) to SymbolInformation
|
* Returns a map from fully qualified name (FQN) to Definition defined in this document
|
||||||
*
|
*
|
||||||
* @return SymbolInformation[]
|
* @return Definition[]
|
||||||
*/
|
*/
|
||||||
public function getSymbols()
|
public function getDefinitions()
|
||||||
{
|
{
|
||||||
return $this->symbols;
|
return $this->definitions;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -332,7 +332,7 @@ class PhpDocument
|
||||||
* @param Node $node
|
* @param Node $node
|
||||||
* @return Promise <Node|null>
|
* @return Promise <Node|null>
|
||||||
*/
|
*/
|
||||||
public function getDefinitionByNode(Node $node): Promise
|
public function getDefinitionNodeByNode(Node $node): Promise
|
||||||
{
|
{
|
||||||
return coroutine(function () use ($node) {
|
return coroutine(function () use ($node) {
|
||||||
// Variables always stay in the boundary of the file and need to be searched inside their function scope
|
// Variables always stay in the boundary of the file and need to be searched inside their function scope
|
||||||
|
@ -358,7 +358,7 @@ class PhpDocument
|
||||||
if (!isset($document)) {
|
if (!isset($document)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return $document->getDefinitionByFqn($fqn);
|
return $document->getDefinitionNodeByFqn($fqn);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -369,7 +369,7 @@ class PhpDocument
|
||||||
* @param Node $node
|
* @param Node $node
|
||||||
* @return Promise <Node[]>
|
* @return Promise <Node[]>
|
||||||
*/
|
*/
|
||||||
public function getReferencesByNode(Node $node): Promise
|
public function getReferenceNodesByNode(Node $node): Promise
|
||||||
{
|
{
|
||||||
return coroutine(function () use ($node) {
|
return coroutine(function () use ($node) {
|
||||||
// Variables always stay in the boundary of the file and need to be searched inside their function scope
|
// Variables always stay in the boundary of the file and need to be searched inside their function scope
|
||||||
|
@ -390,7 +390,7 @@ class PhpDocument
|
||||||
$refCollector = new VariableReferencesCollector($node->name);
|
$refCollector = new VariableReferencesCollector($node->name);
|
||||||
$traverser->addVisitor($refCollector);
|
$traverser->addVisitor($refCollector);
|
||||||
$traverser->traverse($n->getStmts());
|
$traverser->traverse($n->getStmts());
|
||||||
return $refCollector->references;
|
return $refCollector->nodes;
|
||||||
}
|
}
|
||||||
// Definition with a global FQN
|
// Definition with a global FQN
|
||||||
$fqn = getDefinedFqn($node);
|
$fqn = getDefinedFqn($node);
|
||||||
|
|
|
@ -19,11 +19,11 @@ class Project
|
||||||
private $documents = [];
|
private $documents = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An associative array that maps fully qualified symbol names to SymbolInformations
|
* An associative array that maps fully qualified symbol names to Definitions
|
||||||
*
|
*
|
||||||
* @var SymbolInformation[]
|
* @var Definition[]
|
||||||
*/
|
*/
|
||||||
private $symbols = [];
|
private $definitions = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An associative array that maps fully qualified symbol names to arrays of document URIs that reference the symbol
|
* An associative array that maps fully qualified symbol names to arrays of document URIs that reference the symbol
|
||||||
|
@ -170,49 +170,49 @@ class Project
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an associative array [string => string] that maps fully qualified symbol names
|
* Returns an associative array [string => Definition] that maps fully qualified symbol names
|
||||||
* to URIs of the document where the symbol is defined
|
* to Definitions
|
||||||
*
|
*
|
||||||
* @return SymbolInformation[]
|
* @return Definitions[]
|
||||||
*/
|
*/
|
||||||
public function getSymbols()
|
public function getDefinitions()
|
||||||
{
|
{
|
||||||
return $this->symbols;
|
return $this->definitions;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a SymbolInformation for a specific symbol
|
* Registers a definition
|
||||||
*
|
*
|
||||||
* @param string $fqn The fully qualified name of the symbol
|
* @param string $fqn The fully qualified name of the symbol
|
||||||
* @param string $uri The URI
|
* @param string $definition The Definition object
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function setSymbol(string $fqn, SymbolInformation $symbol)
|
public function setDefinition(string $fqn, Definition $definition)
|
||||||
{
|
{
|
||||||
$this->symbols[$fqn] = $symbol;
|
$this->definitions[$fqn] = $definition;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the SymbolInformation index
|
* Sets the SymbolInformation index
|
||||||
*
|
*
|
||||||
* @param SymbolInformation[] $symbols
|
* @param Definition[] $symbols
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function setSymbols(array $symbols)
|
public function setDefinitions(array $definitions)
|
||||||
{
|
{
|
||||||
$this->symbols = $symbols;
|
$this->definitions = $definitions;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unsets the SymbolInformation for a specific symbol
|
* Unsets the Definition for a specific symbol
|
||||||
* and removes all references pointing to that symbol
|
* and removes all references pointing to that symbol
|
||||||
*
|
*
|
||||||
* @param string $fqn The fully qualified name of the symbol
|
* @param string $fqn The fully qualified name of the symbol
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function removeSymbol(string $fqn)
|
public function removeDefinition(string $fqn)
|
||||||
{
|
{
|
||||||
unset($this->symbols[$fqn]);
|
unset($this->definitions[$fqn]);
|
||||||
unset($this->references[$fqn]);
|
unset($this->references[$fqn]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -296,10 +296,10 @@ class Project
|
||||||
*/
|
*/
|
||||||
public function getDefinitionDocument(string $fqn): Promise
|
public function getDefinitionDocument(string $fqn): Promise
|
||||||
{
|
{
|
||||||
if (!isset($this->symbols[$fqn])) {
|
if (!isset($this->definitions[$fqn])) {
|
||||||
return Promise\resolve(null);
|
return Promise\resolve(null);
|
||||||
}
|
}
|
||||||
return $this->getOrLoadDocument($this->symbols[$fqn]->location->uri);
|
return $this->getOrLoadDocument($this->definitions[$fqn]->symbolInformation->location->uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -62,7 +62,11 @@ class TextDocument
|
||||||
public function documentSymbol(TextDocumentIdentifier $textDocument): Promise
|
public function documentSymbol(TextDocumentIdentifier $textDocument): Promise
|
||||||
{
|
{
|
||||||
return $this->project->getOrLoadDocument($textDocument->uri)->then(function (PhpDocument $document) {
|
return $this->project->getOrLoadDocument($textDocument->uri)->then(function (PhpDocument $document) {
|
||||||
return array_values($document->getSymbols());
|
$symbols = [];
|
||||||
|
foreach ($document->getDefinitions() as $fqn => $definition) {
|
||||||
|
$symbols[] = $definition->symbolInformation;
|
||||||
|
}
|
||||||
|
return $symbols;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,7 +140,7 @@ class TextDocument
|
||||||
if ($node === null) {
|
if ($node === null) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
$refs = yield $document->getReferencesByNode($node);
|
$refs = yield $document->getReferenceNodesByNode($node);
|
||||||
$locations = [];
|
$locations = [];
|
||||||
foreach ($refs as $ref) {
|
foreach ($refs as $ref) {
|
||||||
$locations[] = Location::fromNode($ref);
|
$locations[] = Location::fromNode($ref);
|
||||||
|
@ -161,7 +165,7 @@ class TextDocument
|
||||||
if ($node === null) {
|
if ($node === null) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
$def = yield $document->getDefinitionByNode($node);
|
$def = yield $document->getDefinitionNodeByNode($node);
|
||||||
if ($def === null) {
|
if ($def === null) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
@ -187,7 +191,7 @@ class TextDocument
|
||||||
}
|
}
|
||||||
$range = Range::fromNode($node);
|
$range = Range::fromNode($node);
|
||||||
// Get the definition node for whatever node is under the cursor
|
// Get the definition node for whatever node is under the cursor
|
||||||
$def = yield $document->getDefinitionByNode($node);
|
$def = yield $document->getDefinitionNodeByNode($node);
|
||||||
if ($def === null) {
|
if ($def === null) {
|
||||||
return new Hover([], $range);
|
return new Hover([], $range);
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,13 +39,10 @@ class Workspace
|
||||||
*/
|
*/
|
||||||
public function symbol(string $query): array
|
public function symbol(string $query): array
|
||||||
{
|
{
|
||||||
if ($query === '') {
|
|
||||||
return array_values($this->project->getSymbols());
|
|
||||||
}
|
|
||||||
$symbols = [];
|
$symbols = [];
|
||||||
foreach ($this->project->getSymbols() as $fqn => $symbol) {
|
foreach ($this->project->getDefinitions() as $fqn => $definition) {
|
||||||
if (stripos($fqn, $query) !== false) {
|
if ($query === '' || stripos($fqn, $query) !== false) {
|
||||||
$symbols[] = $symbol;
|
$symbols[] = $definition->symbolInformation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $symbols;
|
return $symbols;
|
||||||
|
|
|
@ -28,7 +28,7 @@ class DefinitionCollectorTest extends TestCase
|
||||||
$traverser->addVisitor($definitionCollector);
|
$traverser->addVisitor($definitionCollector);
|
||||||
$stmts = $parser->parse(file_get_contents($uri));
|
$stmts = $parser->parse(file_get_contents($uri));
|
||||||
$traverser->traverse($stmts);
|
$traverser->traverse($stmts);
|
||||||
$defs = $definitionCollector->definitions;
|
$defNodes = $definitionCollector->nodes;
|
||||||
$this->assertEquals([
|
$this->assertEquals([
|
||||||
'TestNamespace\\TEST_CONST',
|
'TestNamespace\\TEST_CONST',
|
||||||
'TestNamespace\\TestClass',
|
'TestNamespace\\TestClass',
|
||||||
|
@ -40,17 +40,17 @@ class DefinitionCollectorTest extends TestCase
|
||||||
'TestNamespace\\TestTrait',
|
'TestNamespace\\TestTrait',
|
||||||
'TestNamespace\\TestInterface',
|
'TestNamespace\\TestInterface',
|
||||||
'TestNamespace\\test_function()'
|
'TestNamespace\\test_function()'
|
||||||
], array_keys($defs));
|
], array_keys($defNodes));
|
||||||
$this->assertInstanceOf(Node\Const_::class, $defs['TestNamespace\\TEST_CONST']);
|
$this->assertInstanceOf(Node\Const_::class, $defNodes['TestNamespace\\TEST_CONST']);
|
||||||
$this->assertInstanceOf(Node\Stmt\Class_::class, $defs['TestNamespace\\TestClass']);
|
$this->assertInstanceOf(Node\Stmt\Class_::class, $defNodes['TestNamespace\\TestClass']);
|
||||||
$this->assertInstanceOf(Node\Const_::class, $defs['TestNamespace\\TestClass::TEST_CLASS_CONST']);
|
$this->assertInstanceOf(Node\Const_::class, $defNodes['TestNamespace\\TestClass::TEST_CLASS_CONST']);
|
||||||
$this->assertInstanceOf(Node\Stmt\PropertyProperty::class, $defs['TestNamespace\\TestClass::staticTestProperty']);
|
$this->assertInstanceOf(Node\Stmt\PropertyProperty::class, $defNodes['TestNamespace\\TestClass::staticTestProperty']);
|
||||||
$this->assertInstanceOf(Node\Stmt\PropertyProperty::class, $defs['TestNamespace\\TestClass::testProperty']);
|
$this->assertInstanceOf(Node\Stmt\PropertyProperty::class, $defNodes['TestNamespace\\TestClass::testProperty']);
|
||||||
$this->assertInstanceOf(Node\Stmt\ClassMethod::class, $defs['TestNamespace\\TestClass::staticTestMethod()']);
|
$this->assertInstanceOf(Node\Stmt\ClassMethod::class, $defNodes['TestNamespace\\TestClass::staticTestMethod()']);
|
||||||
$this->assertInstanceOf(Node\Stmt\ClassMethod::class, $defs['TestNamespace\\TestClass::testMethod()']);
|
$this->assertInstanceOf(Node\Stmt\ClassMethod::class, $defNodes['TestNamespace\\TestClass::testMethod()']);
|
||||||
$this->assertInstanceOf(Node\Stmt\Trait_::class, $defs['TestNamespace\\TestTrait']);
|
$this->assertInstanceOf(Node\Stmt\Trait_::class, $defNodes['TestNamespace\\TestTrait']);
|
||||||
$this->assertInstanceOf(Node\Stmt\Interface_::class, $defs['TestNamespace\\TestInterface']);
|
$this->assertInstanceOf(Node\Stmt\Interface_::class, $defNodes['TestNamespace\\TestInterface']);
|
||||||
$this->assertInstanceOf(Node\Stmt\Function_::class, $defs['TestNamespace\\test_function()']);
|
$this->assertInstanceOf(Node\Stmt\Function_::class, $defNodes['TestNamespace\\test_function()']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testDoesNotCollectReferences()
|
public function testDoesNotCollectReferences()
|
||||||
|
@ -67,8 +67,8 @@ class DefinitionCollectorTest extends TestCase
|
||||||
$traverser->addVisitor($definitionCollector);
|
$traverser->addVisitor($definitionCollector);
|
||||||
$stmts = $parser->parse(file_get_contents($uri));
|
$stmts = $parser->parse(file_get_contents($uri));
|
||||||
$traverser->traverse($stmts);
|
$traverser->traverse($stmts);
|
||||||
$defs = $definitionCollector->definitions;
|
$defNodes = $definitionCollector->nodes;
|
||||||
$this->assertEquals(['TestNamespace\\whatever()'], array_keys($defs));
|
$this->assertEquals(['TestNamespace\\whatever()'], array_keys($defNodes));
|
||||||
$this->assertInstanceOf(Node\Stmt\Function_::class, $defs['TestNamespace\\whatever()']);
|
$this->assertInstanceOf(Node\Stmt\Function_::class, $defNodes['TestNamespace\\whatever()']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue