unhandled exceptions: fix retained

This commit is contained in:
Anna Kozlova
2013-06-24 21:15:11 +04:00
parent f942830e06
commit d397653008
2 changed files with 83 additions and 1 deletions

View File

@@ -420,7 +420,11 @@ public class ExceptionUtil {
for (CandidateInfo info : results) {
final PsiElement element = info.getElement();
if (element instanceof PsiMethod && MethodSignatureUtil.areSignaturesEqual(method, (PsiMethod)element)) {
ex.retainAll(collectSubstituted(info.getSubstitutor(), ((PsiMethod)element).getThrowsList().getReferencedTypes()));
final PsiClassType[] exceptions = ((PsiMethod)element).getThrowsList().getReferencedTypes();
if (exceptions.length == 0) {
return getUnhandledExceptions(methodCall, topElement, PsiSubstitutor.EMPTY, PsiClassType.EMPTY_ARRAY);
}
retainExceptions(ex, collectSubstituted(info.getSubstitutor(), exceptions));
}
}
return getUnhandledExceptions(methodCall, topElement, PsiSubstitutor.EMPTY, ex.toArray(new PsiClassType[ex.size()]));
@@ -435,6 +439,29 @@ public class ExceptionUtil {
return getUnhandledExceptions(method, methodCall, topElement, substitutor);
}
private static void retainExceptions(List<PsiClassType> ex, List<PsiClassType> thrownEx) {
final List<PsiClassType> replacement = new ArrayList<PsiClassType>();
for (Iterator<PsiClassType> iterator = ex.iterator(); iterator.hasNext(); ) {
PsiClassType classType = iterator.next();
boolean found = false;
for (PsiClassType psiClassType : thrownEx) {
if (psiClassType.isAssignableFrom(classType)) {
found = true;
break;
} else if (classType.isAssignableFrom(psiClassType)) {
replacement.add(psiClassType);
iterator.remove();
found = true;
break;
}
}
if (!found) {
iterator.remove();
}
}
ex.addAll(replacement);
}
private static List<PsiClassType> collectSubstituted(PsiSubstitutor substitutor, PsiClassType[] thrownExceptions) {
final List<PsiClassType> ex = new ArrayList<PsiClassType>();
for (PsiClassType thrownException : thrownExceptions) {

View File

@@ -20,3 +20,58 @@ class Main {
throwsNothing.f();
}
}
interface A {
void close() throws Exception;
}
interface B {
void close() throws IOException;
}
abstract class AB implements A, B {}
abstract class BA implements B, A {}
class ABUsage {
void foo(AB ab) {
try {
ab.close();
}
catch (IOException ignored) {}
}
void foo(BA ba) {
try {
ba.close();
}
catch (IOException ignored) {}
}
}
interface C {
void close();
}
interface D {
void close() throws IOException;
}
abstract class CD implements C, D {}
abstract class DC implements D, C {}
class CDUsage {
void foo(CD cd) {
try {
cd.close();
}
catch (<error descr="Exception 'java.io.IOException' is never thrown in the corresponding try block">IOException ignored</error>) {}
}
void foo(DC dc) {
try {
dc.close();
}
catch (<error descr="Exception 'java.io.IOException' is never thrown in the corresponding try block">IOException ignored</error>) {}
}
}