Skip to content

Commit a5684b9

Browse files
committed
SONARJAVA-1528 do not raise issue if raw exceptions are thrown by method invocation + rely on semantic
1 parent e3a3e02 commit a5684b9

6 files changed

Lines changed: 54 additions & 41 deletions

File tree

its/ruling/src/test/resources/fluent-http/squid-S00112.json

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,6 @@
55
'net.code-story:http:src/main/java/net/codestory/http/filters/PayloadSupplier.java':[
66
24,
77
],
8-
'net.code-story:http:src/main/java/net/codestory/http/filters/auth/CookieAuthFilter.java':[
9-
81,
10-
96,
11-
],
128
'net.code-story:http:src/main/java/net/codestory/http/misc/PreCompile.java':[
139
67,
1410
],
@@ -31,12 +27,8 @@
3127
22,
3228
],
3329
'net.code-story:http:src/main/java/net/codestory/http/routes/Route.java':[
34-
24,
3530
33,
3631
],
37-
'net.code-story:http:src/main/java/net/codestory/http/routes/RouteCollection.java':[
38-
519,
39-
],
4032
'net.code-story:http:src/main/java/net/codestory/http/routes/StaticRoute.java':[
4133
79,
4234
],

its/ruling/src/test/resources/guava/squid-S00112.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
],
66
'com.google.guava:guava:src/com/google/common/cache/CacheLoader.java':[
77
69,
8-
93,
98
121,
109
],
1110
'com.google.guava:guava:src/com/google/common/cache/Striped64.java':[

its/ruling/src/test/resources/jboss-ejb3-tutorial/squid-S00112.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,6 @@
3939
],
4040
'jboss-ejb3-tutorial:extended_pc/src/org/jboss/tutorial/extended/client/Client.java':[
4141
41,
42-
46,
43-
66,
4442
],
4543
'jboss-ejb3-tutorial:interceptor/src/org/jboss/tutorial/interceptor/bean/AccountsCancelInterceptor.java':[
4644
63,

its/ruling/src/test/resources/jdk6/squid-S00112.json

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,6 @@
2222
'jdk6:java/awt/im/spi/InputMethodDescriptor.java':[
2323
105,
2424
],
25-
'jdk6:java/beans/DefaultPersistenceDelegate.java':[
26-
203,
27-
],
2825
'jdk6:java/beans/Encoder.java':[
2926
89,
3027
],
@@ -34,17 +31,13 @@
3431
459,
3532
466,
3633
],
37-
'jdk6:java/beans/Expression.java':[
38-
96,
39-
],
4034
'jdk6:java/beans/MetaData.java':[
4135
685,
4236
],
4337
'jdk6:java/beans/PropertyDescriptor.java':[
4438
399,
4539
],
4640
'jdk6:java/beans/Statement.java':[
47-
127,
4841
131,
4942
151,
5043
246,
@@ -62,14 +55,6 @@
6255
55,
6356
80,
6457
],
65-
'jdk6:java/lang/ClassLoader.java':[
66-
1356,
67-
],
68-
'jdk6:java/lang/StringCoding.java':[
69-
89,
70-
149,
71-
249,
72-
],
7358
'jdk6:java/lang/ref/Finalizer.java':[
7459
21,
7560
],
@@ -119,9 +104,6 @@
119104
'jdk6:java/rmi/server/RemoteCall.java':[
120105
104,
121106
],
122-
'jdk6:java/rmi/server/RemoteObjectInvocationHandler.java':[
123-
171,
124-
],
125107
'jdk6:java/rmi/server/RemoteRef.java':[
126108
61,
127109
114,

java-checks/src/main/java/org/sonar/java/checks/RawExceptionCheck.java

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
package org.sonar.java.checks;
2121

2222
import com.google.common.collect.ImmutableSet;
23+
2324
import org.apache.commons.lang.BooleanUtils;
2425
import org.sonar.api.server.rule.RulesDefinition;
2526
import org.sonar.check.Priority;
@@ -28,8 +29,10 @@
2829
import org.sonar.java.tag.Tag;
2930
import org.sonar.plugins.java.api.JavaFileScanner;
3031
import org.sonar.plugins.java.api.JavaFileScannerContext;
32+
import org.sonar.plugins.java.api.semantic.Symbol;
33+
import org.sonar.plugins.java.api.semantic.Type;
3134
import org.sonar.plugins.java.api.tree.BaseTreeVisitor;
32-
import org.sonar.plugins.java.api.tree.IdentifierTree;
35+
import org.sonar.plugins.java.api.tree.MethodInvocationTree;
3336
import org.sonar.plugins.java.api.tree.MethodTree;
3437
import org.sonar.plugins.java.api.tree.NewClassTree;
3538
import org.sonar.plugins.java.api.tree.ThrowStatementTree;
@@ -39,6 +42,7 @@
3942
import org.sonar.squidbridge.annotations.SqaleConstantRemediation;
4043
import org.sonar.squidbridge.annotations.SqaleSubCharacteristic;
4144

45+
import java.util.HashSet;
4246
import java.util.Set;
4347

4448
@Rule(
@@ -51,9 +55,10 @@
5155
@SqaleConstantRemediation("20min")
5256
public class RawExceptionCheck extends BaseTreeVisitor implements JavaFileScanner {
5357

54-
private static final Set<String> RAW_EXCEPTIONS = ImmutableSet.of("Throwable", "Error", "Exception", "RuntimeException");
58+
private static final Set<String> RAW_EXCEPTIONS = ImmutableSet.of("java.lang.Throwable", "java.lang.Error", "java.lang.Exception", "java.lang.RuntimeException");
5559

5660
private JavaFileScannerContext context;
61+
private Set<Type> exceptionsThrownByMethodInvocations = new HashSet<>();
5762

5863
@Override
5964
public void scanFile(JavaFileScannerContext context) {
@@ -63,34 +68,58 @@ public void scanFile(JavaFileScannerContext context) {
6368

6469
@Override
6570
public void visitMethod(MethodTree tree) {
66-
if ((tree.is(Tree.Kind.CONSTRUCTOR) || isNotOverriden(tree)) && !((MethodTreeImpl) tree).isMainMethod()) {
71+
super.visitMethod(tree);
72+
if ((tree.is(Tree.Kind.CONSTRUCTOR) || isNotOverriden(tree)) && isNotMainMethod(tree)) {
6773
for (TypeTree throwClause : tree.throwsClauses()) {
68-
checkExceptionAndRaiseIssue(throwClause);
74+
Type exceptionType = throwClause.symbolType();
75+
if (isRawException(exceptionType) && !exceptionsThrownByMethodInvocations.contains(exceptionType)) {
76+
reportIssue(throwClause);
77+
}
6978
}
7079
}
71-
super.visitMethod(tree);
80+
exceptionsThrownByMethodInvocations.clear();
7281
}
7382

7483
@Override
7584
public void visitThrowStatement(ThrowStatementTree tree) {
7685
if (tree.expression().is(Tree.Kind.NEW_CLASS)) {
77-
checkExceptionAndRaiseIssue(((NewClassTree) tree.expression()).identifier());
86+
TypeTree exception = ((NewClassTree) tree.expression()).identifier();
87+
if (isRawException(exception.symbolType())) {
88+
reportIssue(exception);
89+
}
7890
}
7991
super.visitThrowStatement(tree);
8092
}
8193

82-
private void checkExceptionAndRaiseIssue(Tree tree) {
83-
if (isRawException(tree)) {
84-
context.reportIssue(this, tree, "Define and throw a dedicated exception instead of using a generic one.");
94+
private void reportIssue(Tree tree) {
95+
context.reportIssue(this, tree, "Define and throw a dedicated exception instead of using a generic one.");
96+
}
97+
98+
@Override
99+
public void visitMethodInvocation(MethodInvocationTree tree) {
100+
if (tree.symbol().isMethodSymbol()) {
101+
for (Type thrownType : ((Symbol.MethodSymbol) tree.symbol()).thrownTypes()) {
102+
exceptionsThrownByMethodInvocations.add(thrownType);
103+
}
85104
}
105+
super.visitMethodInvocation(tree);
86106
}
87107

88-
private static boolean isRawException(Tree tree) {
89-
return tree.is(Tree.Kind.IDENTIFIER) && RAW_EXCEPTIONS.contains(((IdentifierTree) tree).name());
108+
private static boolean isRawException(Type type) {
109+
for (String rawException : RAW_EXCEPTIONS) {
110+
if (type.is(rawException)) {
111+
return true;
112+
}
113+
}
114+
return false;
90115
}
91116

92117
private static boolean isNotOverriden(MethodTree tree) {
93118
return BooleanUtils.isFalse(((MethodTreeImpl) tree).isOverriding());
94119
}
95120

121+
private static boolean isNotMainMethod(MethodTree tree) {
122+
return !((MethodTreeImpl) tree).isMainMethod();
123+
}
124+
96125
}

java-checks/src/test/files/checks/RawException.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,16 @@ public class Example {
44
throw new Throwable(); // Noncompliant
55
}
66

7+
public void method_throwing_throwable() throws Throwable { // Compliant
8+
throwingExceptionMethod1();
9+
}
10+
11+
private void throwingExceptionMethod1() throws Throwable { // Noncompliant [[sc=50;ec=59]]
12+
}
13+
14+
private void throwingExceptionMethod2() throws java.lang.Throwable { // Noncompliant [[sc=50;ec=69]]
15+
}
16+
717
public void throws_Error() {
818
throw new Error(); // Noncompliant [[sc=15;ec=20]]
919
}
@@ -16,13 +26,16 @@ public void throws_RuntimeException() {
1626
throw new RuntimeException(); // Noncompliant
1727
}
1828

19-
public void throws_custom() {
29+
public void throws_custom() throws MyOtherException { // Compliant
2030
throw new MyException(); // OK
2131
}
2232

2333
class MyException extends RuntimeException { // Compliant
2434
}
2535

36+
class MyOtherException extends Exception { // Compliant
37+
}
38+
2639
public void throws_value() {
2740
throw create(); // OK
2841
}

0 commit comments

Comments
 (0)