Skip to content

Commit cfa372b

Browse files
committed
factor AbstractDetectorForParameterArray2 out of ManualMessageDetector
so that in the next commit the upcoming ManualGetStackTraceDetector for a SLF4J_GET_STACK_TRACE (issue KengoTODA#70) does not have to copy/paste 3/4 of the ManualMessageDetector
1 parent 6baa7c2 commit cfa372b

File tree

2 files changed

+94
-9
lines changed

2 files changed

+94
-9
lines changed

bug-pattern/src/main/java/jp/skypencil/findbugs/slf4j/ManualMessageDetector.java

+29-9
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,29 @@
11
package jp.skypencil.findbugs.slf4j;
22

3-
import static org.apache.bcel.Const.INVOKEVIRTUAL;
4-
53
import com.google.common.base.Objects;
4+
import jp.skypencil.findbugs.slf4j.parameter.AbstractDetectorForParameterArray2;
5+
import jp.skypencil.findbugs.slf4j.parameter.ArrayData;
66
import edu.umd.cs.findbugs.BugInstance;
77
import edu.umd.cs.findbugs.BugReporter;
88
import edu.umd.cs.findbugs.OpcodeStack.CustomUserValue;
99
import edu.umd.cs.findbugs.OpcodeStack.Item;
1010
import javax.annotation.Nullable;
1111
import jp.skypencil.findbugs.slf4j.parameter.AbstractDetectorForParameterArray;
12-
import jp.skypencil.findbugs.slf4j.parameter.ArrayData;
1312
import jp.skypencil.findbugs.slf4j.parameter.ArrayDataHandler.Strategy;
1413

1514
@CustomUserValue
1615
public final class ManualMessageDetector extends AbstractDetectorForParameterArray {
16+
1717
@Item.SpecialKind
1818
private final int isMessage = Item.defineSpecialKind("message generated by throwable object");
1919

2020
public ManualMessageDetector(BugReporter bugReporter) {
21-
super(bugReporter);
21+
super(bugReporter, "SLF4J_MANUALLY_PROVIDED_MESSAGE");
2222
}
2323

2424
@Override
2525
protected Strategy createArrayCheckStrategy() {
26-
return new Strategy() {
27-
@Override
28-
public void store(Item storedItem, ArrayData arrayData, int index) {
26+
return (storedItem, arrayData, index) -> {
2927
if (arrayData == null) {
3028
return;
3129
}
@@ -39,8 +37,7 @@ public void store(Item storedItem, ArrayData arrayData, int index) {
3937
if (index == arrayData.getSize() - 1 && !getThrowableHandler().checkThrowable(storedItem)) {
4038
arrayData.mark(false);
4139
}
42-
}
43-
};
40+
};
4441
}
4542

4643
@Override
@@ -53,6 +50,20 @@ public void afterOpcode(int seen) {
5350
}
5451
}
5552

53+
54+
@Override
55+
protected int getIsOfInterestKind() {
56+
return isMessage;
57+
}
58+
59+
@Override
60+
protected boolean isReallyOfInterest(Item storedItem, ArrayData arrayData, int index) {
61+
// Let developer logs exception message, only when argument does not have throwable instance
62+
// https://github.com/KengoTODA/findbugs-slf4j/issues/31
63+
return !(index == arrayData.getSize() - 1
64+
&& !getThrowableHandler().checkThrowable(storedItem));
65+
}
66+
5667
private boolean isInvokingGetMessage(int seen) {
5768
return seen == INVOKEVIRTUAL
5869
&& !stack.isTop()
@@ -73,4 +84,13 @@ protected void onLog(@Nullable String format, @Nullable ArrayData arrayData) {
7384
.addCalledMethod(this);
7485
getBugReporter().reportBug(bugInstance);
7586
}
87+
88+
@Override
89+
protected boolean isWhatWeWantToDetect(int seen) {
90+
return seen == INVOKEVIRTUAL && !stack.isTop()
91+
&& getThrowableHandler().checkThrowable(getStack().getStackItem(0))
92+
&& (Objects.equal("getMessage", getNameConstantOperand())
93+
|| Objects.equal("getLocalizedMessage", getNameConstantOperand()));
94+
}
95+
7696
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package jp.skypencil.findbugs.slf4j.parameter;
2+
3+
import edu.umd.cs.findbugs.BugInstance;
4+
import edu.umd.cs.findbugs.BugReporter;
5+
import edu.umd.cs.findbugs.OpcodeStack.Item;
6+
import javax.annotation.Nullable;
7+
import jp.skypencil.findbugs.slf4j.parameter.ArrayDataHandler.Strategy;
8+
9+
public abstract class AbstractDetectorForParameterArray2 extends AbstractDetectorForParameterArray {
10+
11+
private final String bugPatternName;
12+
13+
public AbstractDetectorForParameterArray2(BugReporter bugReporter, String bugPatternName) {
14+
super(bugReporter);
15+
this.bugPatternName = bugPatternName;
16+
}
17+
18+
@Override
19+
protected final Strategy createArrayCheckStrategy() {
20+
return (storedItem, arrayData, index) -> {
21+
if (arrayData == null) {
22+
return;
23+
}
24+
25+
if (storedItem.getSpecialKind() == getIsOfInterestKind()) {
26+
arrayData.mark(true);
27+
}
28+
29+
if (!isReallyOfInterest(storedItem, arrayData, index)) {
30+
arrayData.mark(false);
31+
}
32+
};
33+
}
34+
35+
protected boolean isReallyOfInterest(Item storedItem, ArrayData arrayData, int index) {
36+
return true;
37+
}
38+
39+
@Override
40+
public final void afterOpcode(int seen) {
41+
boolean isInvokingGetMessage = isWhatWeWantToDetect(seen);
42+
super.afterOpcode(seen);
43+
44+
if (isInvokingGetMessage && !stack.isTop()) {
45+
stack.getStackItem(0).setSpecialKind(getIsOfInterestKind());
46+
}
47+
}
48+
49+
@Override
50+
protected final void onLog(@Nullable String format, @Nullable ArrayData arrayData) {
51+
if (arrayData == null || !arrayData.isMarked()) {
52+
return;
53+
}
54+
BugInstance bugInstance = new BugInstance(this,
55+
bugPatternName, NORMAL_PRIORITY)
56+
.addSourceLine(this).addClassAndMethod(this)
57+
.addCalledMethod(this);
58+
getBugReporter().reportBug(bugInstance);
59+
}
60+
61+
abstract protected boolean isWhatWeWantToDetect(int seen);
62+
63+
abstract protected int getIsOfInterestKind();
64+
65+
}

0 commit comments

Comments
 (0)