TypeConstraint#withSupers: fixed SOE on circular hierarchy (IDEA-CR-31134)

This commit is contained in:
Tagir Valeev
2018-04-02 13:16:22 +07:00
parent 0080280e10
commit f566678742
4 changed files with 35 additions and 4 deletions

View File

@@ -20,6 +20,7 @@ import com.intellij.psi.LambdaUtil;
import com.intellij.psi.PsiIntersectionType;
import com.intellij.psi.PsiPrimitiveType;
import com.intellij.psi.PsiType;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.util.containers.ContainerUtil;
import one.util.streamex.EntryStream;
import one.util.streamex.StreamEx;
@@ -196,10 +197,11 @@ public final class TypeConstraint {
}
private static Set<DfaPsiType> withSuper(Set<DfaPsiType> instanceofValues) {
return StreamEx.of(instanceofValues)
.flatMap(type -> StreamEx.ofTree(type.getPsiType(), t -> StreamEx.of(t.getSuperTypes()))
.map(type.getFactory()::createDfaType))
.toSet();
Set<DfaPsiType> result = new HashSet<>(instanceofValues);
for (DfaPsiType type : instanceofValues) {
InheritanceUtil.processSuperTypes(type.getPsiType(), false, t -> result.add(type.getFactory().createDfaType(t)));
}
return result;
}
@NotNull

View File

@@ -0,0 +1,14 @@
class Test {
interface B1 extends B2 {
void baseMethod();
}
interface B2 extends B3 {}
interface B3 extends B1 {}
long test(Object obj) {
if (obj instanceof B1 || obj instanceof B2 || obj instanceof B3) {
obj.baseMe<caret>
}
return -1;
}
}

View File

@@ -0,0 +1,14 @@
class Test {
interface B1 extends B2 {
void baseMethod();
}
interface B2 extends B3 {}
interface B3 extends B1 {}
long test(Object obj) {
if (obj instanceof B1 || obj instanceof B2 || obj instanceof B3) {
((B1) obj).baseMethod();
}
return -1;
}
}

View File

@@ -64,6 +64,7 @@ class NormalCompletionDfaTest extends NormalCompletionTestCase {
void testInstanceOfDisjunction() { doTest() }
void testInstanceOfDisjunction2() { doTest() }
void testInstanceOfDisjunctionDeep() { doTest() }
void testInstanceOfDisjunctionCircular() { doTest() }
void testComplexInstanceOfDfa() {
configureByTestName()
myFixture.assertPreferredCompletionItems 0, 'methodFromX', 'methodFromX2', 'methodFromY', 'methodFromY2'