Maintain a list of visited FQNs while following extends to avoid loops.
parent
f7db99d130
commit
2cb85bda1b
|
@ -1,4 +1,20 @@
|
||||||
<?php
|
<?php
|
||||||
class C extends C {}
|
namespace RecursiveTest;
|
||||||
$c = new C;
|
|
||||||
$c->undef_prop = 1;
|
class A extends A {}
|
||||||
|
|
||||||
|
class B extends C {}
|
||||||
|
class C extends B {}
|
||||||
|
|
||||||
|
class D extends E {}
|
||||||
|
class E extends F {}
|
||||||
|
class F extends D {}
|
||||||
|
|
||||||
|
$a = new A;
|
||||||
|
$a->undef_prop = 1;
|
||||||
|
|
||||||
|
$b = new B;
|
||||||
|
$b->undef_prop = 1;
|
||||||
|
|
||||||
|
$d = new D;
|
||||||
|
$d->undef_prop = 1;
|
||||||
|
|
|
@ -437,6 +437,7 @@ class DefinitionResolver
|
||||||
|
|
||||||
// Find the right class that implements the member
|
// Find the right class that implements the member
|
||||||
$implementorFqns = [$classFqn];
|
$implementorFqns = [$classFqn];
|
||||||
|
$visitedFqns = [];
|
||||||
|
|
||||||
while ($implementorFqn = array_shift($implementorFqns)) {
|
while ($implementorFqn = array_shift($implementorFqns)) {
|
||||||
// If the member FQN exists, return it
|
// If the member FQN exists, return it
|
||||||
|
@ -449,10 +450,13 @@ class DefinitionResolver
|
||||||
if ($implementorDef === null) {
|
if ($implementorDef === null) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// Note the FQN as visited
|
||||||
|
$visitedFqns[] = $implementorFqn;
|
||||||
// Repeat for parent class
|
// Repeat for parent class
|
||||||
if ($implementorDef->extends) {
|
if ($implementorDef->extends) {
|
||||||
foreach ($implementorDef->extends as $extends) {
|
foreach ($implementorDef->extends as $extends) {
|
||||||
if ($extends !== $implementorFqn) {
|
// Don't add the parent FQN if it's already been visited
|
||||||
|
if (!\in_array($extends, $visitedFqns)) {
|
||||||
$implementorFqns[] = $extends;
|
$implementorFqns[] = $extends;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue