1
0
Fork 0

Add support for definition of static class access (#72)

Getting the definition of TestClass in
TestClass::staticTestMethod();
echo TestClass::$staticTestProperty;
echo TestClass::TEST_CLASS_CONST;
pull/78/head
Felix Becker 2016-10-12 12:40:13 +02:00 committed by GitHub
parent 6fe01183b0
commit c479969758
4 changed files with 125 additions and 14 deletions

View File

@ -35,19 +35,6 @@ class ReferencesCollector extends NodeVisitorAbstract
$this->addReference($globalFqn, $node);
}
}
// Namespaced constant references and function calls also need to register a reference to the global
// Static method calls, constant and property fetches also need to register a reference to the class
// A reference like TestNamespace\TestClass::myStaticMethod() registers a reference for
// - TestNamespace\TestClass
// - TestNamespace\TestClass::myStaticMethod()
if (
($node instanceof Node\Expr\StaticCall
|| $node instanceof Node\Expr\StaticPropertyFetch
|| $node instanceof Node\Expr\ClassConstFetch)
&& $node->class instanceof Node\Name
) {
$this->addReference((string)$node->class, $node->class);
}
}
}

View File

@ -344,9 +344,12 @@ class PhpDocument
$parent instanceof Node\Stmt\ClassLike
|| $parent instanceof Node\Param
|| $parent instanceof Node\Stmt\Function_
|| $parent instanceof Node\Expr\StaticCall
|| $parent instanceof Node\Expr\ClassConstFetch
|| $parent instanceof Node\Expr\StaticPropertyFetch
)
) {
// For extends, implements and type hints use the name directly
// For extends, implements, type hints and classes of classes of static calls use the name directly
$name = (string)$node;
// Only the name node should be considered a reference, not the UseUse node itself
} else if ($parent instanceof Node\Stmt\UseUse) {

View File

@ -60,6 +60,67 @@ class GlobalTest extends TestCase
], json_decode(json_encode($result), true));
}
public function testDefinitionForClassOnStaticMethodCall()
{
// $obj = new TestClass();
// Get definition for TestClass
$result = $this->textDocument->definition(new TextDocumentIdentifier('references'), new Position(7, 6));
$this->assertEquals([
'uri' => 'symbols',
'range' => [
'start' => [
'line' => 6,
'character' => 0
],
'end' => [
'line' => 21,
'character' => 1
]
]
], json_decode(json_encode($result), true));
}
public function testDefinitionForClassOnStaticPropertyFetch()
{
// $obj = new TestClass();
// Get definition for TestClass
$result = $this->textDocument->definition(new TextDocumentIdentifier('references'), new Position(8, 10));
$this->assertEquals([
'uri' => 'symbols',
'range' => [
'start' => [
'line' => 6,
'character' => 0
],
'end' => [
'line' => 21,
'character' => 1
]
]
], json_decode(json_encode($result), true));
}
public function testDefinitionForClassOnConstFetch()
{
// $obj = new TestClass();
// Get definition for TestClass
$result = $this->textDocument->definition(new TextDocumentIdentifier('references'), new Position(9, 10));
$this->assertEquals([
'uri' => 'symbols',
'range' => [
'start' => [
'line' => 6,
'character' => 0
],
'end' => [
'line' => 21,
'character' => 1
]
]
], json_decode(json_encode($result), true));
}
public function testDefinitionForImplements()
{
// class TestClass implements TestInterface

View File

@ -58,6 +58,66 @@ class NamespacedTest extends TestCase
], json_decode(json_encode($result), true));
}
public function testDefinitionForClassOnStaticMethodCall()
{
// $obj = new TestClass();
// Get definition for TestClass
$result = $this->textDocument->definition(new TextDocumentIdentifier('references'), new Position(7, 6));
$this->assertEquals([
'uri' => 'symbols',
'range' => [
'start' => [
'line' => 6,
'character' => 0
],
'end' => [
'line' => 21,
'character' => 1
]
]
], json_decode(json_encode($result), true));
}
public function testDefinitionForClassOnStaticPropertyFetch()
{
// $obj = new TestClass();
// Get definition for TestClass
$result = $this->textDocument->definition(new TextDocumentIdentifier('references'), new Position(8, 10));
$this->assertEquals([
'uri' => 'symbols',
'range' => [
'start' => [
'line' => 6,
'character' => 0
],
'end' => [
'line' => 21,
'character' => 1
]
]
], json_decode(json_encode($result), true));
}
public function testDefinitionForClassOnConstFetch()
{
// $obj = new TestClass();
// Get definition for TestClass
$result = $this->textDocument->definition(new TextDocumentIdentifier('references'), new Position(9, 10));
$this->assertEquals([
'uri' => 'symbols',
'range' => [
'start' => [
'line' => 6,
'character' => 0
],
'end' => [
'line' => 21,
'character' => 1
]
]
], json_decode(json_encode($result), true));
}
public function testDefinitionForClassLikeUseStatement()
{
// use TestNamespace\TestClass;