Skip to content

Commit 87800f1

Browse files
authored
Merge pull request #1609 from adamwojs/issue_1599
Fixed #1599: Added protection against infinite recursion in PhpElementsUtil.getImplementedMethods
2 parents 02f3e6c + d5d423c commit 87800f1

File tree

2 files changed

+24
-5
lines changed

2 files changed

+24
-5
lines changed

src/main/java/fr/adrienbrault/idea/symfony2plugin/util/PhpElementsUtil.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -575,15 +575,17 @@ static private PsiElement getArrayKeyValueInsideSignaturePsi(Project project, St
575575
}
576576

577577
public static Method[] getImplementedMethods(@NotNull Method method) {
578-
ArrayList<Method> items = getImplementedMethods(method.getContainingClass(), method, new ArrayList<>());
578+
ArrayList<Method> items = getImplementedMethods(method.getContainingClass(), method, new ArrayList<>(), new HashSet<>());
579579
return items.toArray(new Method[items.size()]);
580580
}
581581

582-
private static ArrayList<Method> getImplementedMethods(@Nullable PhpClass phpClass, @NotNull Method method, ArrayList<Method> implementedMethods) {
583-
if (phpClass == null) {
582+
private static ArrayList<Method> getImplementedMethods(@Nullable PhpClass phpClass, @NotNull Method method, ArrayList<Method> implementedMethods, Set<PhpClass> visitedClasses) {
583+
if (phpClass == null || visitedClasses.contains(phpClass)) {
584584
return implementedMethods;
585585
}
586586

587+
visitedClasses.add(phpClass);
588+
587589
Method[] methods = phpClass.getOwnMethods();
588590
for (Method ownMethod : methods) {
589591
if (PhpLangUtil.equalsMethodNames(ownMethod.getName(), method.getName())) {
@@ -592,10 +594,10 @@ private static ArrayList<Method> getImplementedMethods(@Nullable PhpClass phpCla
592594
}
593595

594596
for(PhpClass interfaceClass: phpClass.getImplementedInterfaces()) {
595-
getImplementedMethods(interfaceClass, method, implementedMethods);
597+
getImplementedMethods(interfaceClass, method, implementedMethods, visitedClasses);
596598
}
597599

598-
getImplementedMethods(phpClass.getSuperClass(), method, implementedMethods);
600+
getImplementedMethods(phpClass.getSuperClass(), method, implementedMethods, visitedClasses);
599601

600602
return implementedMethods;
601603
}

src/test/java/fr/adrienbrault/idea/symfony2plugin/tests/util/PhpElementsUtilTest.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.intellij.psi.PsiElement;
44
import com.intellij.util.containers.ContainerUtil;
5+
import com.jetbrains.php.PhpIndex;
56
import com.jetbrains.php.lang.PhpFileType;
67
import com.jetbrains.php.lang.psi.PhpPsiElementFactory;
78
import com.jetbrains.php.lang.psi.elements.*;
@@ -307,4 +308,20 @@ public void testThatPhpThatStringValueCanBeResolvedViaChainResolve() {
307308
assertContainsElements(PhpElementsUtil.StringResolver.findStringValues(PhpPsiElementFactory.createPhpPsiFromText(getProject(), ParameterList.class, "<?php $var = 'test.html'; foo($var);").getFirstPsiChild()), "test.html");
308309
assertContainsElements(PhpElementsUtil.StringResolver.findStringValues(PhpPsiElementFactory.createPhpPsiFromText(getProject(), TernaryExpression.class, "<?php $var = 'test.html'; $x = true == true ? $var : 'test2.html';")), "test.html", "test2.html");
309310
}
311+
312+
public void testGetImplementedMethodsForRecursiveClassHierarchy() {
313+
myFixture.addFileToProject("First.php", "<?php class First extends Second { public function method() {} }");
314+
myFixture.addFileToProject("Second.php", "<?php class Second extends First { public function method() {} }");
315+
316+
var firstClass = PhpIndex.getInstance(getProject()).getClassByName("First");
317+
var secondClass = PhpIndex.getInstance(getProject()).getClassByName("Second");
318+
319+
var actualResult = PhpElementsUtil.getImplementedMethods(
320+
secondClass.findOwnMethodByName("method")
321+
);
322+
323+
assertSize(2, actualResult);
324+
assertEquals(secondClass.findOwnMethodByName("method"), actualResult[0]);
325+
assertEquals(firstClass.findOwnMethodByName("method"), actualResult[1]);
326+
}
310327
}

0 commit comments

Comments
 (0)