IG: new "Class directly extends 'java.lang.Throwable'" inspection

This commit is contained in:
Bas Leijdekkers
2015-05-13 16:47:48 +02:00
parent fa290059d9
commit fc3dfbc7d5
6 changed files with 138 additions and 1 deletions
@@ -860,6 +860,9 @@
level="WARNING" implementationClass="com.siyeh.ig.encapsulation.UseOfAnotherObjectsPrivateFieldInspection"/>
<!--group.names.error.handling-->
<localInspection groupPath="Java" language="JAVA" shortName="ExtendsThrowable" bundle="com.siyeh.InspectionGadgetsBundle"
key="extends.throwable.display.name" groupBundle="messages.InspectionsBundle" groupKey="group.names.error.handling"
enabledByDefault="false" level="WARNING" implementationClass="com.siyeh.ig.errorhandling.ExtendsThrowableInspection"/>
<localInspection groupPath="Java" language="JAVA" suppressId="ProhibitedExceptionCaught" shortName="BadExceptionCaught" bundle="com.siyeh.InspectionGadgetsBundle"
key="bad.exception.caught.display.name" groupBundle="messages.InspectionsBundle" groupKey="group.names.error.handling"
enabledByDefault="false" level="WARNING"
@@ -2157,4 +2157,7 @@ equals.replaceable.by.objects.call.problem.descriptor=<code>#ref</code> replacea
equals.replaceable.by.objects.call.quickfix=Replace with 'Objects.equals()' expression
array.objects.equals.display.name='Objects.equals()' called on arrays
array.objects.equals.problem.descriptor=<code>Objects.#ref()</code> on arrays should probably be 'Arrays.equals()' #loc
array.objects.deep.equals.problem.descriptor=<code>Objects.#ref()</code> on arrays should probably be 'Arrays.deepEquals()' #loc
array.objects.deep.equals.problem.descriptor=<code>Objects.#ref()</code> on arrays should probably be 'Arrays.deepEquals()' #loc
extends.throwable.display.name=Class directly extends 'java.lang.Throwable'
anonymous.extends.throwable.problem.descriptor=Anonymous class directly extends 'java.lang.Throwable' \#loc
extends.throwable.problem.descriptor=class <code>\#ref</code> directly extends 'java.lang.Throwable' \#loc
@@ -0,0 +1,73 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.siyeh.ig.errorhandling;
import com.intellij.psi.CommonClassNames;
import com.intellij.psi.PsiAnonymousClass;
import com.intellij.psi.PsiClass;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
/**
* @author Bas Leijdekkers
*/
public class ExtendsThrowableInspection extends BaseInspection {
@Nls
@NotNull
@Override
public String getDisplayName() {
return InspectionGadgetsBundle.message("extends.throwable.display.name");
}
@NotNull
@Override
protected String buildErrorString(Object... infos) {
final PsiClass aClass = (PsiClass)infos[0];
if (aClass instanceof PsiAnonymousClass) {
return InspectionGadgetsBundle.message("anonymous.extends.throwable.problem.descriptor");
} else {
return InspectionGadgetsBundle.message("extends.throwable.problem.descriptor");
}
}
@Override
public BaseInspectionVisitor buildVisitor() {
return new ExtendsThrowableVisitor();
}
private static class ExtendsThrowableVisitor extends BaseInspectionVisitor {
@Override
public void visitClass(@NotNull PsiClass aClass) {
if (aClass.isInterface() || aClass.isAnnotationType() || aClass.isEnum()) {
return;
}
final PsiClass superClass = aClass.getSuperClass();
if (superClass == null) {
return;
}
final String superclassName = superClass.getQualifiedName();
if (!CommonClassNames.JAVA_LANG_THROWABLE.equals(superclassName)) {
return;
}
registerClassError(aClass, aClass);
}
}
}
@@ -0,0 +1,12 @@
<html>
<body>
Reports any classes which directly extend <b>java.lang.Throwable</b>.
It is generally considered bad practice to extend <b>java.lang.Throwable</b> directly and
it is usually enough to extend either <b>java.lang.RuntimeException</b> or <b>java.lang.Exception</b> or in special
cases <b>java.lang.Error</b>.
<!-- tooltip end -->
<p>
<small>New in 15</small>
<p>
</body>
</html>
@@ -0,0 +1,9 @@
public class <warning descr="class 'ExtendsThrowable' directly extends 'java.lang.Throwable'">ExtendsThrowable</warning> extends Throwable {
void f() {
new <warning descr="Anonymous class directly extends 'java.lang.Throwable'">Throwable</warning>() {
void b() {}
};
}
}
class E1 extends Exception {}
@@ -0,0 +1,37 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.siyeh.ig.errorhandling;
import com.intellij.codeInspection.InspectionProfileEntry;
import com.siyeh.ig.LightInspectionTestCase;
import junit.framework.TestCase;
import org.jetbrains.annotations.Nullable;
/**
* @author Bas Leijdekkers
*/
public class ExtendsThrowableInspectionTest extends LightInspectionTestCase {
public void testExtendsThrowable() {
doTest();
}
@Nullable
@Override
protected InspectionProfileEntry getInspection() {
return new ExtendsThrowableInspection();
}
}