diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/DetailExceptionsIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/DetailExceptionsIntention.java index 19bb95cac3a0..d42067dee512 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/DetailExceptionsIntention.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/DetailExceptionsIntention.java @@ -55,26 +55,37 @@ public class DetailExceptionsIntention extends Intention { newTryStatement.append(tryBlockText); ExceptionUtils.calculateExceptionsThrown(tryBlock, exceptionsThrown); final Comparator comparator = new HierarchicalTypeComparator(); - final List exceptionsAlreadyEmitted = new ArrayList<>(); final PsiCatchSection[] catchSections = tryStatement.getCatchSections(); for (PsiCatchSection catchSection : catchSections) { final PsiParameter parameter = catchSection.getParameter(); final PsiCodeBlock block = catchSection.getCatchBlock(); if (parameter != null && block != null) { final PsiType caughtType = parameter.getType(); - final List exceptionsToExpand = new ArrayList<>(10); - for (Object aExceptionsThrown : exceptionsThrown) { - final PsiType thrownType = (PsiType)aExceptionsThrown; - if (caughtType.isAssignableFrom(thrownType)) { - exceptionsToExpand.add(thrownType); + List exceptionsToExpand = new ArrayList<>(exceptionsThrown.size()); + for (PsiClassType aExceptionsThrown : exceptionsThrown) { + if (caughtType.isAssignableFrom(aExceptionsThrown)) { + exceptionsToExpand.add(aExceptionsThrown); } } - exceptionsToExpand.removeAll(exceptionsAlreadyEmitted); - Collections.sort(exceptionsToExpand, comparator); - for (PsiType thrownType : exceptionsToExpand) { + exceptionsThrown.removeAll(exceptionsToExpand); + + PsiClassType commonSuperType = null; + PsiClass commonSuper = ObscureThrownExceptionsIntention.findCommonSuperClass(exceptionsToExpand.toArray(PsiClassType.EMPTY_ARRAY)); + if (commonSuper != null) { + commonSuperType = JavaPsiFacade.getElementFactory(commonSuper.getProject()).createType(commonSuper); + if (commonSuperType.equals(caughtType)) { + commonSuperType = null; + } + } + + if (commonSuperType != null) { + exceptionsToExpand = Collections.singletonList(commonSuperType); + } else { + Collections.sort(exceptionsToExpand, comparator); + } + for (PsiClassType thrownType : exceptionsToExpand) { newTryStatement.append("catch(").append(thrownType.getCanonicalText()).append(' ').append(parameter.getName()).append(')'); newTryStatement.append(commentTracker.markUnchanged(block).getText()); - exceptionsAlreadyEmitted.add(thrownType); } } } diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/exceptions/detail/CommonSuperType.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/exceptions/detail/CommonSuperType.java new file mode 100644 index 000000000000..bcec4b5c033b --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/exceptions/detail/CommonSuperType.java @@ -0,0 +1,21 @@ +// Copyright 2000-2017 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. +public class Test { + + void m() { + try { + createModuleNode(null); + } catch (Exception e) { + e.printStackTrace(); + } + } + + protected Object createModuleNode(Object module) throws B1, B2, B3, B4 { + return null; + } + + class A extends Exception {} + class B1 extends A {} + class B2 extends A {} + class B3 extends A {} + class B4 extends A {} +} diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/exceptions/detail/CommonSuperType_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/exceptions/detail/CommonSuperType_after.java new file mode 100644 index 000000000000..ff66adb128ba --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/exceptions/detail/CommonSuperType_after.java @@ -0,0 +1,21 @@ +// Copyright 2000-2017 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. +public class Test { + + void m() { + try { + createModuleNode(null); + } catch (A e) { + e.printStackTrace(); + } + } + + protected Object createModuleNode(Object module) throws B1, B2, B3, B4 { + return null; + } + + class A extends Exception {} + class B1 extends A {} + class B2 extends A {} + class B3 extends A {} + class B4 extends A {} +} diff --git a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/exceptions/DetailExceptionsIntentionTest.java b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/exceptions/DetailExceptionsIntentionTest.java index 6270cf47ed18..35fd1499f010 100644 --- a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/exceptions/DetailExceptionsIntentionTest.java +++ b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/exceptions/DetailExceptionsIntentionTest.java @@ -16,6 +16,7 @@ public class DetailExceptionsIntentionTest extends IPPTestCase { public void testTryWithResources() { doTest(); } public void testPolyadicParentheses() { doTest(); } public void testCaretAtParameter() { doTest(); } + public void testCommonSuperType() { doTest(); } @Override protected String getIntentionName() {