From 1617dc3eb8e0456098bc29d02951bf23cb6b3f4c Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Fri, 16 Mar 2012 12:11:47 +0100 Subject: [PATCH] IDEA-82370 (ExceptionFromCatchWhichDoesntWrap should skip exceptions that does not have "Throwable" in constructor) --- .../siyeh/InspectionGadgetsBundle.properties | 1 + ...ionFromCatchWhichDoesntWrapInspection.java | 47 +++++++++++++++---- .../ExceptionFromCatchWhichDoesntWrap.html | 5 +- .../ExceptionFromCatchWhichDoesntWrap.java | 10 ++++ ...romCatchWhichDoesntWrapInspectionTest.java | 5 +- 5 files changed, 56 insertions(+), 12 deletions(-) diff --git a/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties b/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties index a4a8b6bb9792..62555bcfe923 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties +++ b/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties @@ -1584,6 +1584,7 @@ double.negation.display.name=Double negation double.negation.problem.descriptor=Double negation in #ref #loc double.negation.quickfix=Remove double negation exception.from.catch.which.doesntwrap.ignore.option=Ignore if result of exception method call is used +exception.from.catch.which.doesntwrap.ignore.cant.wrap.option=Ignore if thrown exception cannot wrap an exception comparable.implemented.but.equals.not.overridden.display.name=Comparable implemented but 'equals()' not overridden comparable.implemented.but.equals.not.overridden.problem.descriptor=Class #ref implements 'java.lang.Comparable' but does not override 'equals()' #loc unqualified.field.access.display.name=Instance field access not qualified with 'this' diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/ExceptionFromCatchWhichDoesntWrapInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/ExceptionFromCatchWhichDoesntWrapInspection.java index cbc1fc192c65..0170a4053027 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/ExceptionFromCatchWhichDoesntWrapInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/ExceptionFromCatchWhichDoesntWrapInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2012 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,7 +15,7 @@ */ package com.siyeh.ig.errorhandling; -import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel; +import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel; import com.intellij.psi.*; import com.intellij.psi.search.searches.ReferencesSearch; import com.intellij.psi.util.PsiTreeUtil; @@ -32,14 +32,14 @@ import javax.swing.*; import java.util.HashSet; import java.util.Set; -public class ExceptionFromCatchWhichDoesntWrapInspection - extends BaseInspection { +public class ExceptionFromCatchWhichDoesntWrapInspection extends BaseInspection { - /** - * @noinspection PublicField - */ + @SuppressWarnings("PublicField") public boolean ignoreGetMessage = false; + @SuppressWarnings("PublicField") + public boolean ignoreCantWrap = false; + @Override @NotNull public String getID() { @@ -61,8 +61,10 @@ public class ExceptionFromCatchWhichDoesntWrapInspection @Override @Nullable public JComponent createOptionsPanel() { - return new SingleCheckboxOptionsPanel(InspectionGadgetsBundle.message("exception.from.catch.which.doesntwrap.ignore.option"), this, - "ignoreGetMessage"); + final MultipleCheckboxOptionsPanel panel = new MultipleCheckboxOptionsPanel(this); + panel.addCheckbox(InspectionGadgetsBundle.message("exception.from.catch.which.doesntwrap.ignore.option"), "ignoreGetMessage"); + panel.addCheckbox(InspectionGadgetsBundle.message("exception.from.catch.which.doesntwrap.ignore.cant.wrap.option"), "ignoreCantWrap"); + return panel; } @Override @@ -91,6 +93,33 @@ public class ExceptionFromCatchWhichDoesntWrapInspection if (exception == null) { return; } + if (ignoreCantWrap) { + final PsiType thrownType = exception.getType(); + if (thrownType instanceof PsiClassType) { + final PsiClassType classType = (PsiClassType)thrownType; + final PsiClass exceptionClass = classType.resolve(); + if (exceptionClass != null) { + final PsiMethod[] constructors = exceptionClass.getConstructors(); + final PsiClassType throwableType = PsiType.getJavaLangThrowable(statement.getManager(), statement.getResolveScope()); + boolean canWrap = false; + outer: + for (PsiMethod constructor : constructors) { + final PsiParameterList parameterList = constructor.getParameterList(); + final PsiParameter[] parameters = parameterList.getParameters(); + for (PsiParameter constructorParameter : parameters) { + final PsiType type = constructorParameter.getType(); + if (throwableType.equals(type)) { + canWrap = true; + break outer; + } + } + } + if (!canWrap) { + return; + } + } + } + } final ReferenceFinder visitor = new ReferenceFinder(parameter); exception.accept(visitor); if (visitor.usesParameter()) { diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ExceptionFromCatchWhichDoesntWrap.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ExceptionFromCatchWhichDoesntWrap.html index c2cd745e7937..52c377f46978 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ExceptionFromCatchWhichDoesntWrap.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ExceptionFromCatchWhichDoesntWrap.html @@ -6,10 +6,13 @@ exception. It is considered good practice when throwing an exception in response to wrap the initial exception, so that valuable context information such as stack frames and line numbers are not lost.

-Use the checkbox below to indicate if the inspection should ignore exceptions which +Use the first checkbox below to indicate if the inspection should ignore exceptions which receive the result of a method call on the original exception, such as getMessage(), as an argument.

+Use the second checkbox below to have this inspection ignore throw statements which throw exceptions which do not have a +constructor which accepts a Throwable cause. +

Powered by InspectionGadgets \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/errorhandling/exception_from_catch/ExceptionFromCatchWhichDoesntWrap.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/errorhandling/exception_from_catch/ExceptionFromCatchWhichDoesntWrap.java index b25d660f817e..9d815f8533fc 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/errorhandling/exception_from_catch/ExceptionFromCatchWhichDoesntWrap.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/errorhandling/exception_from_catch/ExceptionFromCatchWhichDoesntWrap.java @@ -59,4 +59,14 @@ public class ExceptionFromCatchWhichDoesntWrap { throw exception; } } + + private void NoWrappingAllowed() { + try { + + } catch (RuntimeException e) { + throw new MyException(); + } + } + + class MyException extends RuntimeException {} } diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/errorhandling/ExceptionFromCatchWhichDoesntWrapInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/errorhandling/ExceptionFromCatchWhichDoesntWrapInspectionTest.java index 48a3b4a01f88..99c7816e8dd8 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/errorhandling/ExceptionFromCatchWhichDoesntWrapInspectionTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/errorhandling/ExceptionFromCatchWhichDoesntWrapInspectionTest.java @@ -6,7 +6,8 @@ public class ExceptionFromCatchWhichDoesntWrapInspectionTest extends IGInspectionTestCase { public void test() throws Exception { - doTest("com/siyeh/igtest/errorhandling/exception_from_catch", - new ExceptionFromCatchWhichDoesntWrapInspection()); + final ExceptionFromCatchWhichDoesntWrapInspection tool = new ExceptionFromCatchWhichDoesntWrapInspection(); + tool.ignoreCantWrap = true; + doTest("com/siyeh/igtest/errorhandling/exception_from_catch", tool); } }