diff --git a/fixtures/global_references.php b/fixtures/global_references.php index c76c9347..25c4a35d 100644 --- a/fixtures/global_references.php +++ b/fixtures/global_references.php @@ -41,3 +41,6 @@ function whatever(TestClass $param): TestClass { $child = new ChildClass; echo $child->testMethod(); + +ChildClass::staticTestMethod(); +ChildClass::$staticTestProperty[123]->testProperty; diff --git a/fixtures/references.php b/fixtures/references.php index b98a38ee..1fd0a0c5 100644 --- a/fixtures/references.php +++ b/fixtures/references.php @@ -41,3 +41,6 @@ function whatever(TestClass $param): TestClass { $child = new ChildClass; echo $child->testMethod(); + +ChildClass::staticTestMethod(); +ChildClass::$staticTestProperty[123]->testProperty; diff --git a/src/DefinitionResolver.php b/src/DefinitionResolver.php index adddf774..4e9f9251 100644 --- a/src/DefinitionResolver.php +++ b/src/DefinitionResolver.php @@ -499,6 +499,8 @@ private function resolveScopedPropertyAccessExpressionNodeToFqn(Node\Expression\ } elseif ($scoped->scopeResolutionQualifier instanceof Node\QualifiedName) { $className = $scoped->scopeResolutionQualifier->getResolvedName(); } + $origName = null; + $nameSuffix = null; if ($scoped->memberName instanceof Node\Expression\Variable) { if ($scoped->parent instanceof Node\Expression\CallExpression) { return null; @@ -507,13 +509,29 @@ private function resolveScopedPropertyAccessExpressionNodeToFqn(Node\Expression\ if (empty($memberName)) { return null; } - $name = (string)$className . '::$' . $memberName; + $nameSuffix = '::$' . $memberName; } else { - $name = (string)$className . '::' . $scoped->memberName->getText($scoped->getFileContents()); + $nameSuffix = '::' . $scoped->memberName->getText($scoped->getFileContents()); } if ($scoped->parent instanceof Node\Expression\CallExpression) { - $name .= '()'; + $nameSuffix .= '()'; } + do { + $name = (string)$className . $nameSuffix; + if ($origName === null) { + $origName = $name; + } + $definition = $this->index->getDefinition($name); + if (!!$definition) { + break; + } else { + $class = $this->index->getDefinition((string)$className); + if ($class === null || empty($class->extends)) { + return $origName; + } + $className = $class->extends[0]; + } + } while (true); return $name; } diff --git a/tests/Server/ServerTestCase.php b/tests/Server/ServerTestCase.php index 3331aefa..16aa47e5 100644 --- a/tests/Server/ServerTestCase.php +++ b/tests/Server/ServerTestCase.php @@ -155,10 +155,12 @@ public function setUp() ], 'TestNamespace\\TestClass::staticTestProperty' => [ 0 => new Location($referencesUri, new Range(new Position( 8, 16), new Position( 8, 35))), // echo TestClass::$staticTestProperty; - 1 => new Location($referencesUri, new Range(new Position(39, 11), new Position(39, 30))) // TestClass::$staticTestProperty[123]->testProperty; + 1 => new Location($referencesUri, new Range(new Position(39, 11), new Position(39, 30))), // TestClass::$staticTestProperty[123]->testProperty; + 2 => new Location($referencesUri, new Range(new Position(45, 12), new Position(45, 31))) // ChildClass::$staticTestProperty[123]->testProperty; ], 'TestNamespace\\TestClass::staticTestMethod()' => [ - 0 => new Location($referencesUri, new Range(new Position( 7, 0), new Position( 7, 27))) + 0 => new Location($referencesUri, new Range(new Position( 7, 0), new Position( 7, 27))), + 1 => new Location($referencesUri, new Range(new Position(44, 0), new Position(44, 28))) ], 'TestNamespace\\TestClass::testMethod()' => [ 0 => new Location($referencesUri, new Range(new Position( 5, 0), new Position( 5, 16))), // $obj->testMethod(); @@ -209,10 +211,12 @@ public function setUp() ], 'TestClass::staticTestProperty' => [ 0 => new Location($globalReferencesUri, new Range(new Position( 8, 16), new Position( 8, 35))), // echo TestClass::$staticTestProperty; - 1 => new Location($globalReferencesUri, new Range(new Position(39, 11), new Position(39, 30))) // TestClass::$staticTestProperty[123]->testProperty; + 1 => new Location($globalReferencesUri, new Range(new Position(39, 11), new Position(39, 30))), // TestClass::$staticTestProperty[123]->testProperty; + 2 => new Location($globalReferencesUri, new Range(new Position(45, 12), new Position(45, 31))) // ChildClass::$staticTestProperty[123]->testProperty; ], 'TestClass::staticTestMethod()' => [ - 0 => new Location($globalReferencesUri, new Range(new Position( 7, 0), new Position( 7, 27))) + 0 => new Location($globalReferencesUri, new Range(new Position( 7, 0), new Position( 7, 27))), + 1 => new Location($globalReferencesUri, new Range(new Position(44, 0), new Position(44, 28))) ], 'TestClass::testMethod()' => [ 0 => new Location($globalReferencesUri, new Range(new Position( 5, 0), new Position( 5, 16))), // $obj->testMethod();