Add support for inherited members (#218)
in completion, definition, references, hover etcpull/219/head v4.1.0
parent
cc9d5e987b
commit
a4a13e6528
|
@ -1,4 +1,4 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
$obj = new TestClass;
|
$obj = new ChildClass;
|
||||||
$obj->
|
$obj->
|
||||||
|
|
|
@ -38,3 +38,6 @@ if ($abc instanceof TestInterface) {
|
||||||
// Nested expression
|
// Nested expression
|
||||||
$obj->testProperty->testMethod();
|
$obj->testProperty->testMethod();
|
||||||
TestClass::$staticTestProperty[123]->testProperty;
|
TestClass::$staticTestProperty[123]->testProperty;
|
||||||
|
|
||||||
|
$child = new ChildClass;
|
||||||
|
echo $child->testMethod();
|
||||||
|
|
|
@ -96,3 +96,5 @@ new class {
|
||||||
$testVariable = 123;
|
$testVariable = 123;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ChildClass extends TestClass {}
|
||||||
|
|
|
@ -38,3 +38,6 @@ if ($abc instanceof TestInterface) {
|
||||||
// Nested expressions
|
// Nested expressions
|
||||||
$obj->testProperty->testMethod();
|
$obj->testProperty->testMethod();
|
||||||
TestClass::$staticTestProperty[123]->testProperty;
|
TestClass::$staticTestProperty[123]->testProperty;
|
||||||
|
|
||||||
|
$child = new ChildClass;
|
||||||
|
echo $child->testMethod();
|
||||||
|
|
|
@ -96,3 +96,5 @@ new class {
|
||||||
$testVariable = 123;
|
$testVariable = 123;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ChildClass extends TestClass {}
|
||||||
|
|
|
@ -145,8 +145,10 @@ class CompletionProvider
|
||||||
$this->definitionResolver->resolveExpressionNodeToType($node->var)
|
$this->definitionResolver->resolveExpressionNodeToType($node->var)
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
// Static member reference
|
||||||
$prefixes = [$node->class instanceof Node\Name ? (string)$node->class : ''];
|
$prefixes = [$node->class instanceof Node\Name ? (string)$node->class : ''];
|
||||||
}
|
}
|
||||||
|
$prefixes = $this->expandParentFqns($prefixes);
|
||||||
// If we are just filtering by the class, add the appropiate operator to the prefix
|
// If we are just filtering by the class, add the appropiate operator to the prefix
|
||||||
// to filter the type of symbol
|
// to filter the type of symbol
|
||||||
foreach ($prefixes as &$prefix) {
|
foreach ($prefixes as &$prefix) {
|
||||||
|
@ -158,6 +160,7 @@ class CompletionProvider
|
||||||
$prefix .= '::$';
|
$prefix .= '::$';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
unset($prefix);
|
||||||
|
|
||||||
foreach ($this->index->getDefinitions() as $fqn => $def) {
|
foreach ($this->index->getDefinitions() as $fqn => $def) {
|
||||||
foreach ($prefixes as $prefix) {
|
foreach ($prefixes as $prefix) {
|
||||||
|
@ -287,6 +290,26 @@ class CompletionProvider
|
||||||
return $list;
|
return $list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the FQNs of all parent classes to an array of FQNs of classes
|
||||||
|
*
|
||||||
|
* @param string[] $fqns
|
||||||
|
* @return string[]
|
||||||
|
*/
|
||||||
|
private function expandParentFqns(array $fqns): array
|
||||||
|
{
|
||||||
|
$expanded = $fqns;
|
||||||
|
foreach ($fqns as $fqn) {
|
||||||
|
$def = $this->index->getDefinition($fqn);
|
||||||
|
if ($def) {
|
||||||
|
foreach ($this->expandParentFqns($def->extends) as $parent) {
|
||||||
|
$expanded[] = $parent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $expanded;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Will walk the AST upwards until a function-like node is met
|
* Will walk the AST upwards until a function-like node is met
|
||||||
* and at each level walk all previous siblings and their children to search for definitions
|
* and at each level walk all previous siblings and their children to search for definitions
|
||||||
|
|
|
@ -30,6 +30,13 @@ class Definition
|
||||||
*/
|
*/
|
||||||
public $fqn;
|
public $fqn;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For class or interfaces, the FQNs of extended classes and implemented interfaces
|
||||||
|
*
|
||||||
|
* @var string[]
|
||||||
|
*/
|
||||||
|
public $extends;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Only true for classes, interfaces, traits, functions and non-class constants
|
* Only true for classes, interfaces, traits, functions and non-class constants
|
||||||
* This is so methods and properties are not suggested in the global scope
|
* This is so methods and properties are not suggested in the global scope
|
||||||
|
|
|
@ -115,6 +115,17 @@ class DefinitionResolver
|
||||||
|| ($node instanceof Node\Stmt\PropertyProperty && $node->getAttribute('parentNode')->isStatic())
|
|| ($node instanceof Node\Stmt\PropertyProperty && $node->getAttribute('parentNode')->isStatic())
|
||||||
);
|
);
|
||||||
$def->fqn = $fqn;
|
$def->fqn = $fqn;
|
||||||
|
if ($node instanceof Node\Stmt\Class_) {
|
||||||
|
$def->extends = [];
|
||||||
|
if ($node->extends) {
|
||||||
|
$def->extends[] = (string)$node->extends;
|
||||||
|
}
|
||||||
|
} else if ($node instanceof Node\Stmt\Interface_) {
|
||||||
|
$def->extends = [];
|
||||||
|
foreach ($node->extends as $n) {
|
||||||
|
$def->extends[] = (string)$n;
|
||||||
|
}
|
||||||
|
}
|
||||||
$def->symbolInformation = SymbolInformation::fromNode($node, $fqn);
|
$def->symbolInformation = SymbolInformation::fromNode($node, $fqn);
|
||||||
$def->type = $this->getTypeFromNode($node);
|
$def->type = $this->getTypeFromNode($node);
|
||||||
$def->declarationLine = $this->getDeclarationLineFromNode($node);
|
$def->declarationLine = $this->getDeclarationLineFromNode($node);
|
||||||
|
@ -248,7 +259,31 @@ class DefinitionResolver
|
||||||
} else {
|
} else {
|
||||||
$classFqn = substr((string)$varType->getFqsen(), 1);
|
$classFqn = substr((string)$varType->getFqsen(), 1);
|
||||||
}
|
}
|
||||||
$name = $classFqn . '->' . (string)$node->name;
|
$memberSuffix = '->' . (string)$node->name;
|
||||||
|
if ($node instanceof Node\Expr\MethodCall) {
|
||||||
|
$memberSuffix .= '()';
|
||||||
|
}
|
||||||
|
// Find the right class that implements the member
|
||||||
|
$implementorFqns = [$classFqn];
|
||||||
|
while ($implementorFqn = array_shift($implementorFqns)) {
|
||||||
|
// If the member FQN exists, return it
|
||||||
|
if ($this->index->getDefinition($implementorFqn . $memberSuffix)) {
|
||||||
|
return $implementorFqn . $memberSuffix;
|
||||||
|
}
|
||||||
|
// Get Definition of implementor class
|
||||||
|
$implementorDef = $this->index->getDefinition($implementorFqn);
|
||||||
|
// If it doesn't exist, return the initial guess
|
||||||
|
if ($implementorDef === null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Repeat for parent class
|
||||||
|
if ($implementorDef->extends) {
|
||||||
|
foreach ($implementorDef->extends as $extends) {
|
||||||
|
$implementorFqns[] = $extends;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $classFqn . $memberSuffix;
|
||||||
} else if ($parent instanceof Node\Expr\FuncCall) {
|
} else if ($parent instanceof Node\Expr\FuncCall) {
|
||||||
if ($parent->name instanceof Node\Expr) {
|
if ($parent->name instanceof Node\Expr) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -290,6 +325,9 @@ class DefinitionResolver
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
if (!isset($name)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
if (
|
if (
|
||||||
$node instanceof Node\Expr\MethodCall
|
$node instanceof Node\Expr\MethodCall
|
||||||
|| $node instanceof Node\Expr\StaticCall
|
|| $node instanceof Node\Expr\StaticCall
|
||||||
|
@ -297,9 +335,6 @@ class DefinitionResolver
|
||||||
) {
|
) {
|
||||||
$name .= '()';
|
$name .= '()';
|
||||||
}
|
}
|
||||||
if (!isset($name)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return $name;
|
return $name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,8 @@ class DefinitionCollectorTest extends TestCase
|
||||||
'TestNamespace\\TestClass->testMethod()',
|
'TestNamespace\\TestClass->testMethod()',
|
||||||
'TestNamespace\\TestTrait',
|
'TestNamespace\\TestTrait',
|
||||||
'TestNamespace\\TestInterface',
|
'TestNamespace\\TestInterface',
|
||||||
'TestNamespace\\test_function()'
|
'TestNamespace\\test_function()',
|
||||||
|
'TestNamespace\\ChildClass'
|
||||||
], array_keys($defNodes));
|
], array_keys($defNodes));
|
||||||
$this->assertInstanceOf(Node\Const_::class, $defNodes['TestNamespace\\TEST_CONST']);
|
$this->assertInstanceOf(Node\Const_::class, $defNodes['TestNamespace\\TEST_CONST']);
|
||||||
$this->assertInstanceOf(Node\Stmt\Class_::class, $defNodes['TestNamespace\\TestClass']);
|
$this->assertInstanceOf(Node\Stmt\Class_::class, $defNodes['TestNamespace\\TestClass']);
|
||||||
|
@ -61,6 +62,7 @@ class DefinitionCollectorTest extends TestCase
|
||||||
$this->assertInstanceOf(Node\Stmt\Trait_::class, $defNodes['TestNamespace\\TestTrait']);
|
$this->assertInstanceOf(Node\Stmt\Trait_::class, $defNodes['TestNamespace\\TestTrait']);
|
||||||
$this->assertInstanceOf(Node\Stmt\Interface_::class, $defNodes['TestNamespace\\TestInterface']);
|
$this->assertInstanceOf(Node\Stmt\Interface_::class, $defNodes['TestNamespace\\TestInterface']);
|
||||||
$this->assertInstanceOf(Node\Stmt\Function_::class, $defNodes['TestNamespace\\test_function()']);
|
$this->assertInstanceOf(Node\Stmt\Function_::class, $defNodes['TestNamespace\\test_function()']);
|
||||||
|
$this->assertInstanceOf(Node\Stmt\Class_::class, $defNodes['TestNamespace\\ChildClass']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testDoesNotCollectReferences()
|
public function testDoesNotCollectReferences()
|
||||||
|
|
|
@ -71,6 +71,7 @@ abstract class ServerTestCase extends TestCase
|
||||||
// Global
|
// Global
|
||||||
'TEST_CONST' => new Location($globalSymbolsUri, new Range(new Position( 9, 6), new Position( 9, 22))),
|
'TEST_CONST' => new Location($globalSymbolsUri, new Range(new Position( 9, 6), new Position( 9, 22))),
|
||||||
'TestClass' => new Location($globalSymbolsUri, new Range(new Position(20, 0), new Position(61, 1))),
|
'TestClass' => new Location($globalSymbolsUri, new Range(new Position(20, 0), new Position(61, 1))),
|
||||||
|
'ChildClass' => new Location($globalSymbolsUri, new Range(new Position(99, 0), new Position(99, 37))),
|
||||||
'TestTrait' => new Location($globalSymbolsUri, new Range(new Position(63, 0), new Position(66, 1))),
|
'TestTrait' => new Location($globalSymbolsUri, new Range(new Position(63, 0), new Position(66, 1))),
|
||||||
'TestInterface' => new Location($globalSymbolsUri, new Range(new Position(68, 0), new Position(71, 1))),
|
'TestInterface' => new Location($globalSymbolsUri, new Range(new Position(68, 0), new Position(71, 1))),
|
||||||
'TestClass::TEST_CLASS_CONST' => new Location($globalSymbolsUri, new Range(new Position(27, 10), new Position(27, 32))),
|
'TestClass::TEST_CLASS_CONST' => new Location($globalSymbolsUri, new Range(new Position(27, 10), new Position(27, 32))),
|
||||||
|
@ -86,6 +87,7 @@ abstract class ServerTestCase extends TestCase
|
||||||
'SecondTestNamespace' => new Location($useUri, new Range(new Position( 2, 0), new Position( 2, 30))),
|
'SecondTestNamespace' => new Location($useUri, new Range(new Position( 2, 0), new Position( 2, 30))),
|
||||||
'TestNamespace\\TEST_CONST' => new Location($symbolsUri, new Range(new Position( 9, 6), new Position( 9, 22))),
|
'TestNamespace\\TEST_CONST' => new Location($symbolsUri, new Range(new Position( 9, 6), new Position( 9, 22))),
|
||||||
'TestNamespace\\TestClass' => new Location($symbolsUri, new Range(new Position(20, 0), new Position(61, 1))),
|
'TestNamespace\\TestClass' => new Location($symbolsUri, new Range(new Position(20, 0), new Position(61, 1))),
|
||||||
|
'TestNamespace\\ChildClass' => new Location($symbolsUri, new Range(new Position(99, 0), new Position(99, 37))),
|
||||||
'TestNamespace\\TestTrait' => new Location($symbolsUri, new Range(new Position(63, 0), new Position(66, 1))),
|
'TestNamespace\\TestTrait' => new Location($symbolsUri, new Range(new Position(63, 0), new Position(66, 1))),
|
||||||
'TestNamespace\\TestInterface' => new Location($symbolsUri, new Range(new Position(68, 0), new Position(71, 1))),
|
'TestNamespace\\TestInterface' => new Location($symbolsUri, new Range(new Position(68, 0), new Position(71, 1))),
|
||||||
'TestNamespace\\TestClass::TEST_CLASS_CONST' => new Location($symbolsUri, new Range(new Position(27, 10), new Position(27, 32))),
|
'TestNamespace\\TestClass::TEST_CLASS_CONST' => new Location($symbolsUri, new Range(new Position(27, 10), new Position(27, 32))),
|
||||||
|
@ -104,14 +106,18 @@ abstract class ServerTestCase extends TestCase
|
||||||
0 => new Location($referencesUri, new Range(new Position(29, 5), new Position(29, 15)))
|
0 => new Location($referencesUri, new Range(new Position(29, 5), new Position(29, 15)))
|
||||||
],
|
],
|
||||||
'TestNamespace\\TestClass' => [
|
'TestNamespace\\TestClass' => [
|
||||||
0 => new Location($referencesUri, new Range(new Position( 4, 11), new Position( 4, 20))), // $obj = new TestClass();
|
0 => new Location($symbolsUri , new Range(new Position(99, 25), new Position(99, 34))), // class ChildClass extends TestClass {}
|
||||||
1 => new Location($referencesUri, new Range(new Position( 7, 0), new Position( 7, 9))), // TestClass::staticTestMethod();
|
1 => new Location($referencesUri, new Range(new Position( 4, 11), new Position( 4, 20))), // $obj = new TestClass();
|
||||||
2 => new Location($referencesUri, new Range(new Position( 8, 5), new Position( 8, 14))), // echo TestClass::$staticTestProperty;
|
2 => new Location($referencesUri, new Range(new Position( 7, 0), new Position( 7, 9))), // TestClass::staticTestMethod();
|
||||||
3 => new Location($referencesUri, new Range(new Position( 9, 5), new Position( 9, 14))), // TestClass::TEST_CLASS_CONST;
|
3 => new Location($referencesUri, new Range(new Position( 8, 5), new Position( 8, 14))), // echo TestClass::$staticTestProperty;
|
||||||
4 => new Location($referencesUri, new Range(new Position(21, 18), new Position(21, 27))), // function whatever(TestClass $param)
|
4 => new Location($referencesUri, new Range(new Position( 9, 5), new Position( 9, 14))), // TestClass::TEST_CLASS_CONST;
|
||||||
5 => new Location($referencesUri, new Range(new Position(21, 37), new Position(21, 46))), // function whatever(TestClass $param): TestClass
|
5 => new Location($referencesUri, new Range(new Position(21, 18), new Position(21, 27))), // function whatever(TestClass $param)
|
||||||
6 => new Location($referencesUri, new Range(new Position(39, 0), new Position(39, 9))), // TestClass::$staticTestProperty[123]->testProperty;
|
6 => new Location($referencesUri, new Range(new Position(21, 37), new Position(21, 46))), // function whatever(TestClass $param): TestClass
|
||||||
7 => new Location($useUri, new Range(new Position( 4, 4), new Position( 4, 27))), // use TestNamespace\TestClass;
|
7 => new Location($referencesUri, new Range(new Position(39, 0), new Position(39, 9))), // TestClass::$staticTestProperty[123]->testProperty;
|
||||||
|
8 => new Location($useUri, new Range(new Position( 4, 4), new Position( 4, 27))), // use TestNamespace\TestClass;
|
||||||
|
],
|
||||||
|
'TestNamespace\\TestChild' => [
|
||||||
|
0 => new Location($referencesUri, new Range(new Position(42, 5), new Position(42, 25))), // echo $child->testProperty;
|
||||||
],
|
],
|
||||||
'TestNamespace\\TestInterface' => [
|
'TestNamespace\\TestInterface' => [
|
||||||
0 => new Location($symbolsUri, new Range(new Position(20, 27), new Position(20, 40))), // class TestClass implements TestInterface
|
0 => new Location($symbolsUri, new Range(new Position(20, 27), new Position(20, 40))), // class TestClass implements TestInterface
|
||||||
|
@ -137,7 +143,8 @@ abstract class ServerTestCase extends TestCase
|
||||||
],
|
],
|
||||||
'TestNamespace\\TestClass::testMethod()' => [
|
'TestNamespace\\TestClass::testMethod()' => [
|
||||||
0 => new Location($referencesUri, new Range(new Position( 5, 0), new Position( 5, 18))), // $obj->testMethod();
|
0 => new Location($referencesUri, new Range(new Position( 5, 0), new Position( 5, 18))), // $obj->testMethod();
|
||||||
1 => new Location($referencesUri, new Range(new Position(38, 0), new Position(38, 32))) // $obj->testProperty->testMethod();
|
1 => new Location($referencesUri, new Range(new Position(38, 0), new Position(38, 32))), // $obj->testProperty->testMethod();
|
||||||
|
2 => new Location($referencesUri, new Range(new Position(42, 5), new Position(42, 25))) // $child->testMethod();
|
||||||
],
|
],
|
||||||
'TestNamespace\\test_function()' => [
|
'TestNamespace\\test_function()' => [
|
||||||
0 => new Location($referencesUri, new Range(new Position(10, 0), new Position(10, 13))),
|
0 => new Location($referencesUri, new Range(new Position(10, 0), new Position(10, 13))),
|
||||||
|
@ -150,13 +157,17 @@ abstract class ServerTestCase extends TestCase
|
||||||
1 => new Location($globalReferencesUri, new Range(new Position(29, 5), new Position(29, 15)))
|
1 => new Location($globalReferencesUri, new Range(new Position(29, 5), new Position(29, 15)))
|
||||||
],
|
],
|
||||||
'TestClass' => [
|
'TestClass' => [
|
||||||
0 => new Location($globalReferencesUri, new Range(new Position( 4, 11), new Position( 4, 20))), // $obj = new TestClass();
|
0 => new Location($globalSymbolsUri, new Range(new Position(99, 25), new Position(99, 34))), // class ChildClass extends TestClass {}
|
||||||
1 => new Location($globalReferencesUri, new Range(new Position( 7, 0), new Position( 7, 9))), // TestClass::staticTestMethod();
|
1 => new Location($globalReferencesUri, new Range(new Position( 4, 11), new Position( 4, 20))), // $obj = new TestClass();
|
||||||
2 => new Location($globalReferencesUri, new Range(new Position( 8, 5), new Position( 8, 14))), // echo TestClass::$staticTestProperty;
|
2 => new Location($globalReferencesUri, new Range(new Position( 7, 0), new Position( 7, 9))), // TestClass::staticTestMethod();
|
||||||
3 => new Location($globalReferencesUri, new Range(new Position( 9, 5), new Position( 9, 14))), // TestClass::TEST_CLASS_CONST;
|
3 => new Location($globalReferencesUri, new Range(new Position( 8, 5), new Position( 8, 14))), // echo TestClass::$staticTestProperty;
|
||||||
4 => new Location($globalReferencesUri, new Range(new Position(21, 18), new Position(21, 27))), // function whatever(TestClass $param)
|
4 => new Location($globalReferencesUri, new Range(new Position( 9, 5), new Position( 9, 14))), // TestClass::TEST_CLASS_CONST;
|
||||||
5 => new Location($globalReferencesUri, new Range(new Position(21, 37), new Position(21, 46))), // function whatever(TestClass $param): TestClass
|
5 => new Location($globalReferencesUri, new Range(new Position(21, 18), new Position(21, 27))), // function whatever(TestClass $param)
|
||||||
6 => new Location($globalReferencesUri, new Range(new Position(39, 0), new Position(39, 9))), // TestClass::$staticTestProperty[123]->testProperty;
|
6 => new Location($globalReferencesUri, new Range(new Position(21, 37), new Position(21, 46))), // function whatever(TestClass $param): TestClass
|
||||||
|
7 => new Location($globalReferencesUri, new Range(new Position(39, 0), new Position(39, 9))), // TestClass::$staticTestProperty[123]->testProperty;
|
||||||
|
],
|
||||||
|
'TestChild' => [
|
||||||
|
0 => new Location($globalReferencesUri, new Range(new Position(42, 5), new Position(42, 25))), // echo $child->testProperty;
|
||||||
],
|
],
|
||||||
'TestInterface' => [
|
'TestInterface' => [
|
||||||
0 => new Location($globalSymbolsUri, new Range(new Position(20, 27), new Position(20, 40))), // class TestClass implements TestInterface
|
0 => new Location($globalSymbolsUri, new Range(new Position(20, 27), new Position(20, 40))), // class TestClass implements TestInterface
|
||||||
|
@ -182,7 +193,8 @@ abstract class ServerTestCase extends TestCase
|
||||||
],
|
],
|
||||||
'TestClass::testMethod()' => [
|
'TestClass::testMethod()' => [
|
||||||
0 => new Location($globalReferencesUri, new Range(new Position( 5, 0), new Position( 5, 18))), // $obj->testMethod();
|
0 => new Location($globalReferencesUri, new Range(new Position( 5, 0), new Position( 5, 18))), // $obj->testMethod();
|
||||||
1 => new Location($globalReferencesUri, new Range(new Position(38, 0), new Position(38, 32))) // $obj->testProperty->testMethod();
|
1 => new Location($globalReferencesUri, new Range(new Position(38, 0), new Position(38, 32))), // $obj->testProperty->testMethod();
|
||||||
|
2 => new Location($globalReferencesUri, new Range(new Position(42, 5), new Position(42, 25))) // $child->testMethod();
|
||||||
],
|
],
|
||||||
'test_function()' => [
|
'test_function()' => [
|
||||||
0 => new Location($globalReferencesUri, new Range(new Position(10, 0), new Position(10, 13))),
|
0 => new Location($globalReferencesUri, new Range(new Position(10, 0), new Position(10, 13))),
|
||||||
|
|
|
@ -165,6 +165,15 @@ class CompletionTest extends TestCase
|
||||||
null,
|
null,
|
||||||
'\TestClass'
|
'\TestClass'
|
||||||
),
|
),
|
||||||
|
new CompletionItem(
|
||||||
|
'ChildClass',
|
||||||
|
CompletionItemKind::CLASS_,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
'\ChildClass'
|
||||||
|
),
|
||||||
// Namespaced, `use`d TestClass definition (inserted as TestClass)
|
// Namespaced, `use`d TestClass definition (inserted as TestClass)
|
||||||
new CompletionItem(
|
new CompletionItem(
|
||||||
'TestClass',
|
'TestClass',
|
||||||
|
@ -175,6 +184,15 @@ class CompletionTest extends TestCase
|
||||||
null,
|
null,
|
||||||
'TestClass'
|
'TestClass'
|
||||||
),
|
),
|
||||||
|
new CompletionItem(
|
||||||
|
'ChildClass',
|
||||||
|
CompletionItemKind::CLASS_,
|
||||||
|
'TestNamespace',
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
'\TestNamespace\ChildClass'
|
||||||
|
),
|
||||||
], true), $items);
|
], true), $items);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -161,6 +161,18 @@ class GlobalTest extends ServerTestCase
|
||||||
$this->assertEquals($this->getDefinitionLocation('TestClass::testMethod()'), $result);
|
$this->assertEquals($this->getDefinitionLocation('TestClass::testMethod()'), $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testDefinitionForMethodOnChildClass()
|
||||||
|
{
|
||||||
|
// $child->testMethod();
|
||||||
|
// Get definition for testMethod
|
||||||
|
$reference = $this->getReferenceLocations('TestClass::testMethod()')[2];
|
||||||
|
$result = $this->textDocument->definition(
|
||||||
|
new TextDocumentIdentifier($reference->uri),
|
||||||
|
$reference->range->end
|
||||||
|
)->wait();
|
||||||
|
$this->assertEquals($this->getDefinitionLocation('TestClass::testMethod()'), $result);
|
||||||
|
}
|
||||||
|
|
||||||
public function testDefinitionForProperties()
|
public function testDefinitionForProperties()
|
||||||
{
|
{
|
||||||
// echo $obj->testProperty;
|
// echo $obj->testProperty;
|
||||||
|
|
|
@ -29,6 +29,7 @@ class DocumentSymbolTest extends ServerTestCase
|
||||||
new SymbolInformation('TestTrait', SymbolKind::CLASS_, $this->getDefinitionLocation('TestNamespace\\TestTrait'), 'TestNamespace'),
|
new SymbolInformation('TestTrait', SymbolKind::CLASS_, $this->getDefinitionLocation('TestNamespace\\TestTrait'), 'TestNamespace'),
|
||||||
new SymbolInformation('TestInterface', SymbolKind::INTERFACE, $this->getDefinitionLocation('TestNamespace\\TestInterface'), 'TestNamespace'),
|
new SymbolInformation('TestInterface', SymbolKind::INTERFACE, $this->getDefinitionLocation('TestNamespace\\TestInterface'), 'TestNamespace'),
|
||||||
new SymbolInformation('test_function', SymbolKind::FUNCTION, $this->getDefinitionLocation('TestNamespace\\test_function()'), 'TestNamespace'),
|
new SymbolInformation('test_function', SymbolKind::FUNCTION, $this->getDefinitionLocation('TestNamespace\\test_function()'), 'TestNamespace'),
|
||||||
|
new SymbolInformation('ChildClass', SymbolKind::CLASS_, $this->getDefinitionLocation('TestNamespace\\ChildClass'), 'TestNamespace'),
|
||||||
], $result);
|
], $result);
|
||||||
// @codingStandardsIgnoreEnd
|
// @codingStandardsIgnoreEnd
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,7 @@ class SymbolTest extends ServerTestCase
|
||||||
new SymbolInformation('TestTrait', SymbolKind::CLASS_, $this->getDefinitionLocation('TestNamespace\\TestTrait'), 'TestNamespace'),
|
new SymbolInformation('TestTrait', SymbolKind::CLASS_, $this->getDefinitionLocation('TestNamespace\\TestTrait'), 'TestNamespace'),
|
||||||
new SymbolInformation('TestInterface', SymbolKind::INTERFACE, $this->getDefinitionLocation('TestNamespace\\TestInterface'), 'TestNamespace'),
|
new SymbolInformation('TestInterface', SymbolKind::INTERFACE, $this->getDefinitionLocation('TestNamespace\\TestInterface'), 'TestNamespace'),
|
||||||
new SymbolInformation('test_function', SymbolKind::FUNCTION, $this->getDefinitionLocation('TestNamespace\\test_function()'), 'TestNamespace'),
|
new SymbolInformation('test_function', SymbolKind::FUNCTION, $this->getDefinitionLocation('TestNamespace\\test_function()'), 'TestNamespace'),
|
||||||
|
new SymbolInformation('ChildClass', SymbolKind::CLASS_, $this->getDefinitionLocation('TestNamespace\\ChildClass'), 'TestNamespace'),
|
||||||
new SymbolInformation('whatever', SymbolKind::FUNCTION, $this->getDefinitionLocation('TestNamespace\\whatever()'), 'TestNamespace'),
|
new SymbolInformation('whatever', SymbolKind::FUNCTION, $this->getDefinitionLocation('TestNamespace\\whatever()'), 'TestNamespace'),
|
||||||
// Global
|
// Global
|
||||||
new SymbolInformation('TEST_CONST', SymbolKind::CONSTANT, $this->getDefinitionLocation('TEST_CONST'), ''),
|
new SymbolInformation('TEST_CONST', SymbolKind::CONSTANT, $this->getDefinitionLocation('TEST_CONST'), ''),
|
||||||
|
@ -53,6 +54,7 @@ class SymbolTest extends ServerTestCase
|
||||||
new SymbolInformation('TestTrait', SymbolKind::CLASS_, $this->getDefinitionLocation('TestTrait'), ''),
|
new SymbolInformation('TestTrait', SymbolKind::CLASS_, $this->getDefinitionLocation('TestTrait'), ''),
|
||||||
new SymbolInformation('TestInterface', SymbolKind::INTERFACE, $this->getDefinitionLocation('TestInterface'), ''),
|
new SymbolInformation('TestInterface', SymbolKind::INTERFACE, $this->getDefinitionLocation('TestInterface'), ''),
|
||||||
new SymbolInformation('test_function', SymbolKind::FUNCTION, $this->getDefinitionLocation('test_function()'), ''),
|
new SymbolInformation('test_function', SymbolKind::FUNCTION, $this->getDefinitionLocation('test_function()'), ''),
|
||||||
|
new SymbolInformation('ChildClass', SymbolKind::CLASS_, $this->getDefinitionLocation('ChildClass'), ''),
|
||||||
new SymbolInformation('whatever', SymbolKind::FUNCTION, $this->getDefinitionLocation('whatever()'), ''),
|
new SymbolInformation('whatever', SymbolKind::FUNCTION, $this->getDefinitionLocation('whatever()'), ''),
|
||||||
|
|
||||||
new SymbolInformation('SecondTestNamespace', SymbolKind::NAMESPACE, $this->getDefinitionLocation('SecondTestNamespace'), '')
|
new SymbolInformation('SecondTestNamespace', SymbolKind::NAMESPACE, $this->getDefinitionLocation('SecondTestNamespace'), '')
|
||||||
|
|
Loading…
Reference in New Issue