fix precise catch types calculation (IDEA-200795)

fixes false positive in "Redundant throws clause" inspection
fixes bad code is green: unhandled exception

GitOrigin-RevId: 232b2a0086422b5fd5cfb7b7d45c7cbbbb1bd296
This commit is contained in:
Bas Leijdekkers
2021-08-13 15:07:00 +00:00
committed by intellij-monorepo-bot
parent 5be896475f
commit 735a6e7874
2 changed files with 29 additions and 3 deletions
@@ -1,4 +1,4 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.psi.impl.source.tree.java;
import com.intellij.codeInsight.ExceptionUtil;
@@ -16,6 +16,7 @@ import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.*;
import com.intellij.util.ArrayUtil;
import com.intellij.util.NullableFunction;
import com.intellij.util.SmartList;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -112,7 +113,10 @@ public class PsiCatchSectionImpl extends CompositePsiElement implements PsiCatch
});
if (uncaughtTypes.isEmpty()) return Collections.emptyList(); // unreachable catch section
// ... and T is assignable to Ej ...
List<PsiType> types = new ArrayList<>();
List<PsiType> types = new SmartList<>();
final List<PsiType> disjunctions = (declaredType instanceof PsiDisjunctionType)
? ((PsiDisjunctionType)declaredType).getDisjunctions()
: Collections.emptyList();
for (PsiType type : uncaughtTypes) {
if (declaredType.isAssignableFrom(type) ||
// JLS 11.2.3 "Exception Checking":
@@ -123,9 +127,16 @@ public class PsiCatchSectionImpl extends CompositePsiElement implements PsiCatch
ExceptionUtil.isGeneralExceptionType(declaredType) && type instanceof PsiClassType && ExceptionUtil.isUncheckedException((PsiClassType)type)) {
types.add(type);
}
else {
for (PsiType disjunction : disjunctions) {
if (type.isAssignableFrom(disjunction)) {
types.add(disjunction);
}
}
}
}
// ... the throw statement throws precisely the set of exception types T.
if (!types.isEmpty()) return types;
if (!types.isEmpty()) return Collections.unmodifiableList(types);
}
return Collections.singletonList(declaredType);
@@ -262,4 +262,19 @@ class C {
throw e;
}
}
static class F extends Exception {}
private void x() throws E, F {
throw new E2();
}
private void m16() throws F {
try {
x();
}
catch (F | E1 e) {
System.out.println(e);
<error descr="Unhandled exception: C.E1">throw e;</error>
}
catch (E ignored) {}
}
}