Skip to content

Commit c7d25c7

Browse files
d0x2ffelixfbecker
authored andcommitted
fix(definitionresolver): infinite loop when indexing self referencing classes (felixfbecker#670)
1 parent 71390c9 commit c7d25c7

File tree

2 files changed

+27
-1
lines changed

2 files changed

+27
-1
lines changed

fixtures/self_referencing_class.php

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
namespace RecursiveTest;
3+
4+
class A extends A {}
5+
6+
class B extends C {}
7+
class C extends B {}
8+
9+
class D extends E {}
10+
class E extends F {}
11+
class F extends D {}
12+
13+
$a = new A;
14+
$a->undef_prop = 1;
15+
16+
$b = new B;
17+
$b->undef_prop = 1;
18+
19+
$d = new D;
20+
$d->undef_prop = 1;

src/DefinitionResolver.php

+7-1
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,7 @@ private function resolveMemberAccessExpressionNodeToFqn(Node\Expression\MemberAc
438438

439439
// Find the right class that implements the member
440440
$implementorFqns = [$classFqn];
441+
$visitedFqns = [];
441442

442443
while ($implementorFqn = array_shift($implementorFqns)) {
443444
// If the member FQN exists, return it
@@ -450,10 +451,15 @@ private function resolveMemberAccessExpressionNodeToFqn(Node\Expression\MemberAc
450451
if ($implementorDef === null) {
451452
break;
452453
}
454+
// Note the FQN as visited
455+
$visitedFqns[] = $implementorFqn;
453456
// Repeat for parent class
454457
if ($implementorDef->extends) {
455458
foreach ($implementorDef->extends as $extends) {
456-
$implementorFqns[] = $extends;
459+
// Don't add the parent FQN if it's already been visited
460+
if (!\in_array($extends, $visitedFqns)) {
461+
$implementorFqns[] = $extends;
462+
}
457463
}
458464
}
459465
}

0 commit comments

Comments
 (0)