parent
4786fe173c
commit
48c71e5bc1
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace LanguageServer\NodeVisitors;
|
||||
|
||||
use PhpParser\{NodeVisitorAbstract, Node};
|
||||
use LanguageServer\Protocol\Position;
|
||||
|
||||
/**
|
||||
* Finds the Node at a specified position
|
||||
* Depends on ColumnCalculator
|
||||
*/
|
||||
class NodeAtPositionFinder extends NodeVisitorAbstract
|
||||
{
|
||||
/**
|
||||
* The node at the position, if found
|
||||
*
|
||||
* @var Node
|
||||
*/
|
||||
public $node;
|
||||
|
||||
/**
|
||||
* @var Position
|
||||
*/
|
||||
private $position;
|
||||
|
||||
/**
|
||||
* @param Position $position The position where the node is located
|
||||
*/
|
||||
public function __construct(Position $position)
|
||||
{
|
||||
$this->position = $position;
|
||||
}
|
||||
|
||||
public function leaveNode(Node $node)
|
||||
{
|
||||
if (
|
||||
!isset($this->node)
|
||||
&& $node->getAttribute('startLine') <= $this->position->line + 1
|
||||
&& $node->getAttribute('endLine') >= $this->position->line + 1
|
||||
&& $node->getAttribute('startColumn') <= $this->position->character + 1
|
||||
&& $node->getAttribute('endColumn') >= $this->position->character + 1
|
||||
) {
|
||||
$this->node = $node;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,7 +4,7 @@ declare(strict_types = 1);
|
|||
namespace LanguageServer;
|
||||
|
||||
use LanguageServer\Protocol\{Diagnostic, DiagnosticSeverity, Range, Position, SymbolKind, TextEdit};
|
||||
use LanguageServer\NodeVisitors\{ReferencesAdder, SymbolFinder, ColumnCalculator};
|
||||
use LanguageServer\NodeVisitors\{NodeAtPositionFinder, ReferencesAdder, SymbolFinder, ColumnCalculator};
|
||||
use PhpParser\{Error, Comment, Node, ParserFactory, NodeTraverser, Lexer, Parser};
|
||||
use PhpParser\PrettyPrinter\Standard as PrettyPrinter;
|
||||
use PhpParser\NodeVisitor\NameResolver;
|
||||
|
@ -104,7 +104,7 @@ class PhpDocument
|
|||
* Re-parses a source file, updates symbols, reports parsing errors
|
||||
* that may have occured as diagnostics and returns parsed nodes.
|
||||
*
|
||||
* @return \PhpParser\Node[]
|
||||
* @return void
|
||||
*/
|
||||
public function parse()
|
||||
{
|
||||
|
@ -155,9 +155,9 @@ class PhpDocument
|
|||
$traverser->traverse($stmts);
|
||||
|
||||
$this->symbols = $symbolFinder->symbols;
|
||||
}
|
||||
|
||||
return $stmts;
|
||||
$this->stmts = $stmts;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -167,14 +167,13 @@ class PhpDocument
|
|||
*/
|
||||
public function getFormattedText()
|
||||
{
|
||||
$stmts = $this->parse();
|
||||
if (empty($stmts)) {
|
||||
if (empty($this->stmts)) {
|
||||
return [];
|
||||
}
|
||||
$prettyPrinter = new PrettyPrinter();
|
||||
$edit = new TextEdit();
|
||||
$edit->range = new Range(new Position(0, 0), new Position(PHP_INT_MAX, PHP_INT_MAX));
|
||||
$edit->newText = $prettyPrinter->prettyPrintFile($stmts);
|
||||
$edit->newText = $prettyPrinter->prettyPrintFile($this->stmts);
|
||||
return [$edit];
|
||||
}
|
||||
|
||||
|
@ -187,4 +186,22 @@ class PhpDocument
|
|||
{
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the node at a specified position
|
||||
*
|
||||
* @param Position $position
|
||||
* @return Node|null
|
||||
*/
|
||||
public function getNodeAtPosition(Position $position)
|
||||
{
|
||||
if ($this->stmts === null) {
|
||||
return null;
|
||||
}
|
||||
$traverser = new NodeTraverser;
|
||||
$finder = new NodeAtPositionFinder($position);
|
||||
$traverser->addVisitor($finder);
|
||||
$traverser->traverse($this->stmts);
|
||||
return $finder->node;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,9 @@ namespace LanguageServer\Tests\Server;
|
|||
use PHPUnit\Framework\TestCase;
|
||||
use LanguageServer\Tests\MockProtocolStream;
|
||||
use LanguageServer\{LanguageClient, Project};
|
||||
use LanguageServer\Protocol\SymbolKind;
|
||||
use LanguageServer\NodeVisitors\NodeAtPositionFinder;
|
||||
use LanguageServer\Protocol\{SymbolKind, Position};
|
||||
use PhpParser\Node;
|
||||
|
||||
class PhpDocumentTest extends TestCase
|
||||
{
|
||||
|
@ -23,7 +25,7 @@ class PhpDocumentTest extends TestCase
|
|||
public function testParsesVariableVariables()
|
||||
{
|
||||
$document = $this->project->getDocument('whatever');
|
||||
|
||||
|
||||
$document->updateContent("<?php\n$\$a = 'foo';\n\$bar = 'baz';\n");
|
||||
|
||||
$symbols = $document->getSymbols();
|
||||
|
@ -67,4 +69,13 @@ class PhpDocumentTest extends TestCase
|
|||
]
|
||||
], json_decode(json_encode($symbols), true));
|
||||
}
|
||||
|
||||
public function testGetNodeAtPosition()
|
||||
{
|
||||
$document = $this->project->getDocument('whatever');
|
||||
$document->updateContent("<?php\n$\$a = new SomeClass;");
|
||||
$node = $document->getNodeAtPosition(new Position(1, 13));
|
||||
$this->assertInstanceOf(Node\Name\FullyQualified::class, $node);
|
||||
$this->assertEquals('SomeClass', (string)$node);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue