IDEA-82370 (ExceptionFromCatchWhichDoesntWrap should skip exceptions that does not have "Throwable" in constructor)

This commit is contained in:
Bas Leijdekkers
2012-03-16 12:11:47 +01:00
parent 5b4aa71946
commit 1617dc3eb8
5 changed files with 56 additions and 12 deletions
@@ -1584,6 +1584,7 @@ double.negation.display.name=Double negation
double.negation.problem.descriptor=Double negation in <code>#ref</code> #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 <code>#ref</code> implements 'java.lang.Comparable' but does not override 'equals()' #loc
unqualified.field.access.display.name=Instance field access not qualified with 'this'
@@ -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()) {
@@ -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.
<p>
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 <b>getMessage()</b>,
as an argument.
<p>
Use the second checkbox below to have this inspection ignore throw statements which throw exceptions which do not have a
constructor which accepts a <b>Throwable</b> cause.
<p>
<small>Powered by InspectionGadgets</small>
</body>
</html>
@@ -59,4 +59,14 @@ public class ExceptionFromCatchWhichDoesntWrap {
throw exception;
}
}
private void NoWrappingAllowed() {
try {
} catch (RuntimeException e) {
throw new MyException();
}
}
class MyException extends RuntimeException {}
}
@@ -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);
}
}