Decorate all nodes with parent, sibling references
parent
658a27f5a5
commit
4786fe173c
|
@ -0,0 +1,41 @@
|
||||||
|
<?php
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace LanguageServer\NodeVisitors;
|
||||||
|
|
||||||
|
use PhpParser\{NodeVisitorAbstract, Node};
|
||||||
|
use LanguageServer\Protocol\{SymbolInformation, SymbolKind, Range, Position, Location};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decorates all nodes with parent and sibling references (similar to DOM nodes)
|
||||||
|
*/
|
||||||
|
class ReferencesAdder extends NodeVisitorAbstract
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var Node[]
|
||||||
|
*/
|
||||||
|
private $stack = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Node
|
||||||
|
*/
|
||||||
|
private $previous;
|
||||||
|
|
||||||
|
public function enterNode(Node $node)
|
||||||
|
{
|
||||||
|
if (!empty($this->stack)) {
|
||||||
|
$node->setAttribute('parentNode', end($this->stack));
|
||||||
|
}
|
||||||
|
if (isset($this->previous) && $this->previous->getAttribute('parentNode') === $node->getAttribute('parentNode')) {
|
||||||
|
$node->setAttribute('previousSibling', $this->previous);
|
||||||
|
$this->previous->setAttribute('nextSibling', $node);
|
||||||
|
}
|
||||||
|
$this->stack[] = $node;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function leaveNode(Node $node)
|
||||||
|
{
|
||||||
|
$this->previous = $node;
|
||||||
|
array_pop($this->stack);
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,7 +4,7 @@ declare(strict_types = 1);
|
||||||
namespace LanguageServer;
|
namespace LanguageServer;
|
||||||
|
|
||||||
use LanguageServer\Protocol\{Diagnostic, DiagnosticSeverity, Range, Position, SymbolKind, TextEdit};
|
use LanguageServer\Protocol\{Diagnostic, DiagnosticSeverity, Range, Position, SymbolKind, TextEdit};
|
||||||
use LanguageServer\NodeVisitors\{SymbolFinder, ColumnCalculator};
|
use LanguageServer\NodeVisitors\{ReferencesAdder, SymbolFinder, ColumnCalculator};
|
||||||
use PhpParser\{Error, Comment, Node, ParserFactory, NodeTraverser, Lexer, Parser};
|
use PhpParser\{Error, Comment, Node, ParserFactory, NodeTraverser, Lexer, Parser};
|
||||||
use PhpParser\PrettyPrinter\Standard as PrettyPrinter;
|
use PhpParser\PrettyPrinter\Standard as PrettyPrinter;
|
||||||
use PhpParser\NodeVisitor\NameResolver;
|
use PhpParser\NodeVisitor\NameResolver;
|
||||||
|
@ -138,13 +138,23 @@ class PhpDocument
|
||||||
// $stmts can be null in case of a fatal parsing error
|
// $stmts can be null in case of a fatal parsing error
|
||||||
if ($stmts) {
|
if ($stmts) {
|
||||||
$traverser = new NodeTraverser;
|
$traverser = new NodeTraverser;
|
||||||
$finder = new SymbolFinder($this->uri);
|
|
||||||
|
// Resolve aliased names to FQNs
|
||||||
$traverser->addVisitor(new NameResolver);
|
$traverser->addVisitor(new NameResolver);
|
||||||
|
|
||||||
|
// Add parentNode, previousSibling, nextSibling attributes
|
||||||
|
$traverser->addVisitor(new ReferencesAdder);
|
||||||
|
|
||||||
|
// Add column attributes to nodes
|
||||||
$traverser->addVisitor(new ColumnCalculator($this->content));
|
$traverser->addVisitor(new ColumnCalculator($this->content));
|
||||||
$traverser->addVisitor($finder);
|
|
||||||
|
// Collect all symbols
|
||||||
|
$symbolFinder = new SymbolFinder($this->uri);
|
||||||
|
$traverser->addVisitor($symbolFinder);
|
||||||
|
|
||||||
$traverser->traverse($stmts);
|
$traverser->traverse($stmts);
|
||||||
|
|
||||||
$this->symbols = $finder->symbols;
|
$this->symbols = $symbolFinder->symbols;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $stmts;
|
return $stmts;
|
||||||
|
|
Loading…
Reference in New Issue