From d397653008aaa8606f0ee2c5e51720f2efaa9deb Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Mon, 24 Jun 2013 21:15:11 +0400 Subject: [PATCH] unhandled exceptions: fix retained --- .../intellij/codeInsight/ExceptionUtil.java | 29 +++++++++- ...nhandledExceptionsMultipleInheritance.java | 55 +++++++++++++++++++ 2 files changed, 83 insertions(+), 1 deletion(-) diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java b/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java index c846eb5c8377..d96551cd3510 100644 --- a/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java +++ b/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java @@ -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 ex, List thrownEx) { + final List replacement = new ArrayList(); + for (Iterator 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 collectSubstituted(PsiSubstitutor substitutor, PsiClassType[] thrownExceptions) { final List ex = new ArrayList(); for (PsiClassType thrownException : thrownExceptions) { diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/NoUnhandledExceptionsMultipleInheritance.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/NoUnhandledExceptionsMultipleInheritance.java index 720e7c883d23..327bc825554d 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/NoUnhandledExceptionsMultipleInheritance.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/NoUnhandledExceptionsMultipleInheritance.java @@ -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 (IOException ignored) {} + } + + void foo(DC dc) { + try { + dc.close(); + } + catch (IOException ignored) {} + } +} \ No newline at end of file