Java control flow: Fixed false positive for unreachable code in multi-catch clause (IDEA-138978)

This commit is contained in:
Pavel Dolgov
2016-07-25 19:19:45 +03:00
parent 672db6ca1f
commit 96a576963a
3 changed files with 38 additions and 1 deletions
@@ -21,10 +21,12 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Condition;
import com.intellij.psi.*;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.Stack;
import gnu.trove.THashMap;
import gnu.trove.TIntArrayList;
@@ -971,7 +973,7 @@ class ControlFlowAnalyzer extends JavaElementVisitor {
ProgressManager.checkCanceled();
PsiParameter parameter = myCatchParameters.get(i);
PsiType catchType = parameter.getType();
if (catchType.isAssignableFrom(throwType) || throwType.isAssignableFrom(catchType)) {
if (catchType.isAssignableFrom(throwType) || mightBeAssignableFromSubclass(throwType, catchType)) {
blocks.add(myCatchBlocks.get(i));
}
}
@@ -982,6 +984,18 @@ class ControlFlowAnalyzer extends JavaElementVisitor {
return blocks;
}
private static boolean mightBeAssignableFromSubclass(@NotNull final PsiClassType throwType, @NotNull PsiType catchType) {
if (catchType instanceof PsiDisjunctionType) {
return ContainerUtil.exists(((PsiDisjunctionType)catchType).getDisjunctions(), new Condition<PsiType>() {
@Override
public boolean value(PsiType catchDisjunction) {
return throwType.isAssignableFrom(catchDisjunction);
}
});
}
return throwType.isAssignableFrom(catchType);
}
@Override
public void visitAssertStatement(PsiAssertStatement statement) {
startElement(statement);
@@ -0,0 +1,22 @@
class MultiCatch {
public String get(boolean b) {
try {
return b ? get1() : get2();
} catch (EE1 | EE2 e) {
return null; // is reachable
} catch (E1 | E2 e) {
//
}
return null;
}
String get1() throws E1 { return "1"; }
String get2() throws E2 { return "2"; }
static class E extends Exception { }
static class E1 extends E { }
static class E2 extends E { }
static class EE1 extends E1 { }
static class EE2 extends E2 { }
}
@@ -180,6 +180,7 @@ public class LightAdvHighlightingJdk7Test extends LightDaemonAnalyzerTestCase {
public void testInaccessibleInferredTypeForVarargsArgument() { doTest(false, false);}
public void testRuntimeClassCast() { doTest(true, false);}
public void testTryWithResourcesWithMultipleCloseInterfaces() { doTest(false, false);}
public void testIDEA138978() { doTest(false, false); }
public void testJavaUtilCollections_NoVerify() throws Exception {
PsiClass collectionsClass = getJavaFacade().findClass("java.util.Collections", GlobalSearchScope.moduleWithLibrariesScope(getModule()));