From 2c28282512e8feb3fc69a1cae9bed527a86c9b0e Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Fri, 8 Oct 2010 15:17:16 +0400 Subject: [PATCH] SOE in case of mutually recursive inheritance --- .../impl/search/MethodDeepestSuperSearcher.java | 17 +++++++++-------- .../daemon/LightAdvHighlightingTest.java | 6 ++++++ .../src/com/intellij/codeInsight/ClassUtil.java | 3 ++- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/java/java-impl/src/com/intellij/psi/impl/search/MethodDeepestSuperSearcher.java b/java/java-impl/src/com/intellij/psi/impl/search/MethodDeepestSuperSearcher.java index 6140fec1cdb5..7ead9acfadaf 100644 --- a/java/java-impl/src/com/intellij/psi/impl/search/MethodDeepestSuperSearcher.java +++ b/java/java-impl/src/com/intellij/psi/impl/search/MethodDeepestSuperSearcher.java @@ -6,6 +6,7 @@ package com.intellij.psi.impl.search; import com.intellij.psi.PsiMethod; import com.intellij.util.Processor; import com.intellij.util.QueryExecutor; +import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; import java.util.LinkedHashSet; @@ -15,10 +16,9 @@ import java.util.Set; * @author peter */ public class MethodDeepestSuperSearcher implements QueryExecutor { - public boolean execute(@NotNull final PsiMethod method, @NotNull final Processor consumer) { final Set methods = new LinkedHashSet(); - findDeepestSuperOrSelfSignature(method, methods); + findDeepestSuperOrSelfSignature(method, methods, null); for (final PsiMethod psiMethod : methods) { if (psiMethod != method && !consumer.process(psiMethod)) { return false; @@ -27,17 +27,18 @@ public class MethodDeepestSuperSearcher implements QueryExecutor set) { + private static void findDeepestSuperOrSelfSignature(PsiMethod method, final Set set, Set guard) { + if (guard != null && !guard.add(method)) return; PsiMethod[] supers = method.findSuperMethods(); if (supers.length == 0) { set.add(method); - return; } - - for (PsiMethod superMethod : supers) { - findDeepestSuperOrSelfSignature(superMethod, set); + else { + for (PsiMethod superMethod : supers) { + if (guard == null) guard = new THashSet(); + findDeepestSuperOrSelfSignature(superMethod, set, guard); + } } } - } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingTest.java index 33621dc9e0ef..e2f566e72cad 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingTest.java @@ -302,4 +302,10 @@ public class LightAdvHighlightingTest extends LightDaemonAnalyzerTestCase { field.getInitializer().getType(); // SOE } + + public void testSOEForCyclicInheritance() throws IOException { + configureFromFileText("a.java", "class A extends B { String s = \"\"; void f() {}} class B extends A { void f() {} } "); + + doHighlighting(); + } } diff --git a/java/openapi/src/com/intellij/codeInsight/ClassUtil.java b/java/openapi/src/com/intellij/codeInsight/ClassUtil.java index e7b0fbf6849b..8abe35cb1ddd 100644 --- a/java/openapi/src/com/intellij/codeInsight/ClassUtil.java +++ b/java/openapi/src/com/intellij/codeInsight/ClassUtil.java @@ -89,10 +89,11 @@ public class ClassUtil { private static boolean add(PsiMethod method, Set alreadyImplemented) { boolean already = alreadyImplemented.add(method); + if (!already) return already; for (PsiMethod superSig : method.findSuperMethods()) { already &= add(superSig, alreadyImplemented); } return already; } -} \ No newline at end of file +}