1
0
Fork 0

Decorate all nodes with parent, sibling references

pull/49/head
Felix Becker 2016-10-08 13:22:34 +02:00
parent 658a27f5a5
commit 4786fe173c
2 changed files with 55 additions and 4 deletions

View File

@ -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);
}
}

View File

@ -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;