mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Fix precise type calculation for degenerate case
This commit is contained in:
+27
-23
@@ -106,36 +106,40 @@ public class PsiCatchSectionImpl extends CompositePsiElement implements PsiCatch
|
||||
|
||||
final PsiType declaredType = parameter.getType();
|
||||
|
||||
// When the thrown expression is a ... exception parameter Ej (parameter) of a catch clause Cj (this) ...
|
||||
final LanguageLevel level = PsiUtil.getLanguageLevel(parameter);
|
||||
if (level.isAtLeast(LanguageLevel.JDK_1_7) && isCatchParameterEffectivelyFinal(parameter, getCatchBlock())) {
|
||||
// When the thrown expression is an ... exception parameter Ej (parameter) of a catch clause Cj (this) ...
|
||||
if (PsiUtil.getLanguageLevel(parameter).isAtLeast(LanguageLevel.JDK_1_7) &&
|
||||
isCatchParameterEffectivelyFinal(parameter, getCatchBlock())) {
|
||||
final PsiCodeBlock tryBlock = getTryStatement().getTryBlock();
|
||||
if (tryBlock != null) {
|
||||
// ... and the try block of the try statement which declares Cj (tryBlock) can throw T ...
|
||||
final List<PsiClassType> thrownTypes = ExceptionUtil.getThrownExceptions(tryBlock);
|
||||
// ... and for all exception parameters Ei declared by any catch clauses Ci, 1 <= i < j,
|
||||
// declared to the left of Cj for the same try statement, T is not assignable to Ei ...
|
||||
final PsiParameter[] parameters = getTryStatement().getCatchBlockParameters();
|
||||
final List<PsiType> uncaughtTypes = ContainerUtil.mapNotNull(thrownTypes, new NullableFunction<PsiClassType, PsiType>() {
|
||||
@Override
|
||||
public PsiType fun(final PsiClassType thrownType) {
|
||||
for (int i = 0; i < parameters.length && parameters[i] != parameter && thrownTypes.size() > 0; i++) {
|
||||
final PsiType catchType = parameters[i].getType();
|
||||
if (catchType.isAssignableFrom(thrownType)) return null;
|
||||
if (!thrownTypes.isEmpty()) {
|
||||
// ... and for all exception parameters Ei declared by any catch clauses Ci, 1 <= i < j,
|
||||
// declared to the left of Cj for the same try statement, T is not assignable to Ei ...
|
||||
final PsiParameter[] parameters = getTryStatement().getCatchBlockParameters();
|
||||
final List<PsiType> uncaughtTypes = ContainerUtil.mapNotNull(thrownTypes, new NullableFunction<PsiClassType, PsiType>() {
|
||||
@Override
|
||||
public PsiType fun(final PsiClassType thrownType) {
|
||||
for (int i = 0; i < parameters.length && parameters[i] != parameter; i++) {
|
||||
final PsiType catchType = parameters[i].getType();
|
||||
if (catchType.isAssignableFrom(thrownType)) return null;
|
||||
}
|
||||
return thrownType;
|
||||
}
|
||||
return thrownType;
|
||||
}
|
||||
});
|
||||
// ... and T is assignable to Ej ...
|
||||
boolean passed = true;
|
||||
for (PsiType type : uncaughtTypes) {
|
||||
if (!declaredType.isAssignableFrom(type)) {
|
||||
passed = false;
|
||||
break;
|
||||
});
|
||||
// ... and T is assignable to Ej ...
|
||||
if (!uncaughtTypes.isEmpty()) {
|
||||
boolean passed = true;
|
||||
for (PsiType type : uncaughtTypes) {
|
||||
if (!declaredType.isAssignableFrom(type)) {
|
||||
passed = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// ... the throw statement throws precisely the set of exception types T.
|
||||
if (passed) return uncaughtTypes;
|
||||
}
|
||||
}
|
||||
// ... the throw statement throws precisely the set of exception types T.
|
||||
if (passed) return uncaughtTypes;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+10
@@ -155,4 +155,14 @@ class C {
|
||||
<error descr="Unhandled exception: C.E">throw x;</error>
|
||||
}
|
||||
}
|
||||
|
||||
void m11() throws E1 {
|
||||
try {
|
||||
System.out.println();
|
||||
}
|
||||
catch (Exception e) {
|
||||
// test for precise types calculation fix
|
||||
<error descr="Unhandled exception: java.lang.Exception">throw e;</error>
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user