diff --git a/src/NodeVisitor/ReferencesCollector.php b/src/NodeVisitor/ReferencesCollector.php index e02904c..749f635 100644 --- a/src/NodeVisitor/ReferencesCollector.php +++ b/src/NodeVisitor/ReferencesCollector.php @@ -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); - } } } diff --git a/src/PhpDocument.php b/src/PhpDocument.php index 9a716de..fe9a1a2 100644 --- a/src/PhpDocument.php +++ b/src/PhpDocument.php @@ -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) { diff --git a/tests/Server/TextDocument/Definition/GlobalTest.php b/tests/Server/TextDocument/Definition/GlobalTest.php index aacdceb..23013ea 100644 --- a/tests/Server/TextDocument/Definition/GlobalTest.php +++ b/tests/Server/TextDocument/Definition/GlobalTest.php @@ -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 diff --git a/tests/Server/TextDocument/Definition/NamespacedTest.php b/tests/Server/TextDocument/Definition/NamespacedTest.php index 1d5f1c9..4d9dc2a 100644 --- a/tests/Server/TextDocument/Definition/NamespacedTest.php +++ b/tests/Server/TextDocument/Definition/NamespacedTest.php @@ -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;