From e19670c1414f4b391a30befc1b90f185d4ed4d22 Mon Sep 17 00:00:00 2001 From: Felix Becker Date: Thu, 20 Oct 2016 00:18:36 +0200 Subject: [PATCH] Resolve self, static, parent (#99) --- fixtures/global_symbols.php | 2 +- fixtures/symbols.php | 2 +- src/PhpDocument.php | 24 ++++++++++++++++++- tests/Server/ServerTestCase.php | 6 +++-- .../TextDocument/Definition/GlobalTest.php | 9 +++++++ 5 files changed, 38 insertions(+), 5 deletions(-) diff --git a/fixtures/global_symbols.php b/fixtures/global_symbols.php index 9b08afc..e39bb0c 100644 --- a/fixtures/global_symbols.php +++ b/fixtures/global_symbols.php @@ -46,7 +46,7 @@ class TestClass implements TestInterface */ public static function staticTestMethod() { - + echo self::TEST_CLASS_CONST; } /** diff --git a/fixtures/symbols.php b/fixtures/symbols.php index 9a14c0e..7fee2d2 100644 --- a/fixtures/symbols.php +++ b/fixtures/symbols.php @@ -46,7 +46,7 @@ class TestClass implements TestInterface */ public static function staticTestMethod() { - + echo self::TEST_CLASS_CONST; } /** diff --git a/src/PhpDocument.php b/src/PhpDocument.php index 00face9..9733b66 100644 --- a/src/PhpDocument.php +++ b/src/PhpDocument.php @@ -454,7 +454,29 @@ class PhpDocument // Cannot get definition of dynamic names return null; } - $name = (string)$node->class . '::' . $node->name; + $className = (string)$node->class; + if ($className === 'self' || $className === 'static' || $className === 'parent') { + // self and static are resolved to the containing class + $n = $node; + while ($n = $n->getAttribute('parentNode')) { + if ($n instanceof Node\Stmt\Class_) { + if ($n->isAnonymous()) { + return null; + } + if ($className === 'parent') { + // parent is resolved to the parent class + if (!isset($n->extends)) { + return null; + } + $className = (string)$n->extends; + } else { + $className = (string)$n->namespacedName; + } + break; + } + } + } + $name = (string)$className . '::' . $node->name; } else { return null; } diff --git a/tests/Server/ServerTestCase.php b/tests/Server/ServerTestCase.php index 00d5471..bb83534 100644 --- a/tests/Server/ServerTestCase.php +++ b/tests/Server/ServerTestCase.php @@ -107,7 +107,8 @@ abstract class ServerTestCase extends TestCase 0 => new Location($symbolsUri, new Range(new Position(20, 27), new Position(20, 40))) // class TestClass implements TestInterface ], 'TestNamespace\\TestClass::TEST_CLASS_CONST' => [ - 0 => new Location($referencesUri, new Range(new Position( 9, 5), new Position( 9, 32))) + 0 => new Location($symbolsUri, new Range(new Position(48, 13), new Position(48, 35))), // echo self::TEST_CLASS_CONSTANT + 1 => new Location($referencesUri, new Range(new Position( 9, 5), new Position( 9, 32))) ], 'TestNamespace\\TestClass::testProperty' => [ 0 => new Location($symbolsUri, new Range(new Position(59, 8), new Position(59, 27))), // $this->testProperty = $testParameter; @@ -143,7 +144,8 @@ abstract class ServerTestCase extends TestCase 0 => new Location($globalSymbolsUri, new Range(new Position(20, 27), new Position(20, 40))) // class TestClass implements TestInterface ], 'TestClass::TEST_CLASS_CONST' => [ - 0 => new Location($globalReferencesUri, new Range(new Position( 9, 5), new Position( 9, 32))) + 0 => new Location($globalSymbolsUri, new Range(new Position(48, 13), new Position(48, 35))), // echo self::TEST_CLASS_CONSTANT + 1 => new Location($globalReferencesUri, new Range(new Position( 9, 5), new Position( 9, 32))) ], 'TestClass::testProperty' => [ 0 => new Location($globalSymbolsUri, new Range(new Position(59, 8), new Position(59, 27))), // $this->testProperty = $testParameter; diff --git a/tests/Server/TextDocument/Definition/GlobalTest.php b/tests/Server/TextDocument/Definition/GlobalTest.php index e89c0eb..f58c35a 100644 --- a/tests/Server/TextDocument/Definition/GlobalTest.php +++ b/tests/Server/TextDocument/Definition/GlobalTest.php @@ -70,6 +70,15 @@ class GlobalTest extends ServerTestCase { // echo TestClass::TEST_CLASS_CONST; // Get definition for TEST_CLASS_CONST + $reference = $this->getReferenceLocations('TestClass::TEST_CLASS_CONST')[1]; + $result = $this->textDocument->definition(new TextDocumentIdentifier($reference->uri), $reference->range->end); + $this->assertEquals($this->getDefinitionLocation('TestClass::TEST_CLASS_CONST'), $result); + } + + public function testDefinitionForClassConstantsOnSelf() + { + // echo self::TEST_CLASS_CONST; + // Get definition for TEST_CLASS_CONST $reference = $this->getReferenceLocations('TestClass::TEST_CLASS_CONST')[0]; $result = $this->textDocument->definition(new TextDocumentIdentifier($reference->uri), $reference->range->end); $this->assertEquals($this->getDefinitionLocation('TestClass::TEST_CLASS_CONST'), $result);