diff --git a/fixtures/global_symbols.php b/fixtures/global_symbols.php index 915dcfe..9b08afc 100644 --- a/fixtures/global_symbols.php +++ b/fixtures/global_symbols.php @@ -57,7 +57,7 @@ class TestClass implements TestInterface */ public function testMethod($testParameter) { - $testVariable = 123; + $this->testProperty = $testParameter; } } diff --git a/fixtures/symbols.php b/fixtures/symbols.php index 4904e07..9a14c0e 100644 --- a/fixtures/symbols.php +++ b/fixtures/symbols.php @@ -57,7 +57,7 @@ class TestClass implements TestInterface */ public function testMethod($testParameter) { - $testVariable = 123; + $this->testProperty = $testParameter; } } diff --git a/src/PhpDocument.php b/src/PhpDocument.php index c208ae4..00face9 100644 --- a/src/PhpDocument.php +++ b/src/PhpDocument.php @@ -395,29 +395,47 @@ class PhpDocument return null; } // Need to resolve variable to a class - $varDef = $this->getVariableDefinition($node->var); - if (!isset($varDef)) { - return null; - } - if ($varDef instanceof Node\Param) { - if (!isset($varDef->type)) { - // Cannot resolve to class without a type hint - // TODO: parse docblock - return null; - } - $name = (string)$varDef->type; - } else if ($varDef instanceof Node\Expr\Assign) { - if ($varDef->expr instanceof Node\Expr\New_) { - if (!($varDef->expr->class instanceof Node\Name)) { - // Cannot get definition of dynamic calls - return null; + if ($node->var->name === 'this') { + // $this resolved to the class it is contained in + $n = $node; + while ($n = $n->getAttribute('parentNode')) { + if ($n instanceof Node\Stmt\Class_) { + if ($n->isAnonymous()) { + return null; + } + $name = (string)$n->namespacedName; + break; } - $name = (string)$varDef->expr->class; - } else { + } + if (!isset($name)) { return null; } } else { - return null; + // Other variables resolve to their definition + $varDef = $this->getVariableDefinition($node->var); + if (!isset($varDef)) { + return null; + } + if ($varDef instanceof Node\Param) { + if (!isset($varDef->type)) { + // Cannot resolve to class without a type hint + // TODO: parse docblock + return null; + } + $name = (string)$varDef->type; + } else if ($varDef instanceof Node\Expr\Assign) { + if ($varDef->expr instanceof Node\Expr\New_) { + if (!($varDef->expr->class instanceof Node\Name)) { + // Cannot get definition of dynamic calls + return null; + } + $name = (string)$varDef->expr->class; + } else { + return null; + } + } else { + return null; + } } $name .= '::' . (string)$node->name; } else if ($parent instanceof Node\Expr\FuncCall) { diff --git a/tests/Server/ServerTestCase.php b/tests/Server/ServerTestCase.php index 47981b9..00d5471 100644 --- a/tests/Server/ServerTestCase.php +++ b/tests/Server/ServerTestCase.php @@ -110,7 +110,8 @@ abstract class ServerTestCase extends TestCase 0 => new Location($referencesUri, new Range(new Position( 9, 5), new Position( 9, 32))) ], 'TestNamespace\\TestClass::testProperty' => [ - 0 => new Location($referencesUri, new Range(new Position( 6, 5), new Position( 6, 23))) + 0 => new Location($symbolsUri, new Range(new Position(59, 8), new Position(59, 27))), // $this->testProperty = $testParameter; + 1 => new Location($referencesUri, new Range(new Position( 6, 5), new Position( 6, 23))) ], 'TestNamespace\\TestClass::staticTestProperty' => [ 0 => new Location($referencesUri, new Range(new Position( 8, 5), new Position( 8, 35))) @@ -145,7 +146,8 @@ abstract class ServerTestCase extends TestCase 0 => new Location($globalReferencesUri, new Range(new Position( 9, 5), new Position( 9, 32))) ], 'TestClass::testProperty' => [ - 0 => new Location($globalReferencesUri, new Range(new Position( 6, 5), new Position( 6, 23))) + 0 => new Location($globalSymbolsUri, new Range(new Position(59, 8), new Position(59, 27))), // $this->testProperty = $testParameter; + 1 => new Location($globalReferencesUri, new Range(new Position( 6, 5), new Position( 6, 23))) ], 'TestClass::staticTestProperty' => [ 0 => new Location($globalReferencesUri, new Range(new Position( 8, 5), new Position( 8, 35))) diff --git a/tests/Server/TextDocument/Definition/GlobalTest.php b/tests/Server/TextDocument/Definition/GlobalTest.php index 5c854e2..e89c0eb 100644 --- a/tests/Server/TextDocument/Definition/GlobalTest.php +++ b/tests/Server/TextDocument/Definition/GlobalTest.php @@ -115,6 +115,15 @@ class GlobalTest extends ServerTestCase { // echo $obj->testProperty; // Get definition for testProperty + $reference = $this->getReferenceLocations('TestClass::testProperty')[1]; + $result = $this->textDocument->definition(new TextDocumentIdentifier($reference->uri), $reference->range->end); + $this->assertEquals($this->getDefinitionLocation('TestClass::testProperty'), $result); + } + + public function testDefinitionForPropertiesOnThis() + { + // $this->testProperty = $testParameter; + // Get definition for testProperty $reference = $this->getReferenceLocations('TestClass::testProperty')[0]; $result = $this->textDocument->definition(new TextDocumentIdentifier($reference->uri), $reference->range->end); $this->assertEquals($this->getDefinitionLocation('TestClass::testProperty'), $result);