Skip to content

Commit

Permalink
factor AbstractDetectorForParameterArray2 out of ManualMessageDetector
Browse files Browse the repository at this point in the history
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
  • Loading branch information
vorburger committed Mar 14, 2018
1 parent 55693e4 commit d1a2c62
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 47 deletions.
Original file line number Diff line number Diff line change
@@ -1,77 +1,44 @@
package jp.skypencil.findbugs.slf4j;

import javax.annotation.Nullable;

import jp.skypencil.findbugs.slf4j.parameter.AbstractDetectorForParameterArray;
import jp.skypencil.findbugs.slf4j.parameter.AbstractDetectorForParameterArray2;
import jp.skypencil.findbugs.slf4j.parameter.ArrayData;
import jp.skypencil.findbugs.slf4j.parameter.ArrayDataHandler.Strategy;

import com.google.common.base.Objects;

import edu.umd.cs.findbugs.BugInstance;
import edu.umd.cs.findbugs.BugReporter;
import edu.umd.cs.findbugs.OpcodeStack.CustomUserValue;
import edu.umd.cs.findbugs.OpcodeStack.Item;

@CustomUserValue
public final class ManualMessageDetector extends AbstractDetectorForParameterArray {
public final class ManualMessageDetector extends AbstractDetectorForParameterArray2 {

@Item.SpecialKind
private final int isMessage = Item.defineNewSpecialKind("message generated by throwable object");

public ManualMessageDetector(BugReporter bugReporter) {
super(bugReporter);
super(bugReporter, "SLF4J_MANUALLY_PROVIDED_MESSAGE");
}

@Override
protected Strategy createArrayCheckStrategy() {
return new Strategy() {
@Override
public void store(Item storedItem, ArrayData arrayData, int index) {
if (arrayData == null) {
return;
}

if (storedItem.getSpecialKind() == isMessage) {
arrayData.mark(true);
}

// Let developer logs exception message, only when argument does not have throwable instance
// https://github.com/KengoTODA/findbugs-slf4j/issues/31
if (index == arrayData.getSize() - 1
&& !getThrowableHandler().checkThrowable(storedItem)) {
arrayData.mark(false);
}
}
};
protected int getIsOfInterestKind() {
return isMessage;
}

@Override
public void afterOpcode(int seen) {
boolean isInvokingGetMessage = isInvokingGetMessage(seen);
super.afterOpcode(seen);

if (isInvokingGetMessage && !stack.isTop()) {
stack.getStackItem(0).setSpecialKind(isMessage);
}
protected boolean isReallyOfInterest(Item storedItem, ArrayData arrayData, int index) {
// Let developer logs exception message, only when argument does not have throwable instance
// https://github.com/KengoTODA/findbugs-slf4j/issues/31
return !(index == arrayData.getSize() - 1
&& !getThrowableHandler().checkThrowable(storedItem));
}

private boolean isInvokingGetMessage(int seen) {

@Override
protected boolean isWhatWeWantToDetect(int seen) {
return seen == INVOKEVIRTUAL
&& !stack.isTop()
&& getThrowableHandler().checkThrowable(getStack().getStackItem(0))
&& (Objects.equal("getMessage", getNameConstantOperand()) ||
Objects.equal("getLocalizedMessage", getNameConstantOperand()));
}

@Override
protected void onLog(@Nullable String format, @Nullable ArrayData arrayData) {
if (arrayData == null || !arrayData.isMarked()) {
return;
}
BugInstance bugInstance = new BugInstance(this,
"SLF4J_MANUALLY_PROVIDED_MESSAGE", NORMAL_PRIORITY)
.addSourceLine(this).addClassAndMethod(this)
.addCalledMethod(this);
getBugReporter().reportBug(bugInstance);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package jp.skypencil.findbugs.slf4j.parameter;

import edu.umd.cs.findbugs.BugInstance;
import edu.umd.cs.findbugs.BugReporter;
import edu.umd.cs.findbugs.OpcodeStack.Item;
import javax.annotation.Nullable;
import jp.skypencil.findbugs.slf4j.parameter.ArrayDataHandler.Strategy;

public abstract class AbstractDetectorForParameterArray2 extends AbstractDetectorForParameterArray {

private final String bugPatternName;

public AbstractDetectorForParameterArray2(BugReporter bugReporter, String bugPatternName) {
super(bugReporter);
this.bugPatternName = bugPatternName;
}

@Override
protected final Strategy createArrayCheckStrategy() {
return (storedItem, arrayData, index) -> {
if (arrayData == null) {
return;
}

if (storedItem.getSpecialKind() == getIsOfInterestKind()) {
arrayData.mark(true);
}

if (!isReallyOfInterest(storedItem, arrayData, index)) {
arrayData.mark(false);
}
};
}

protected boolean isReallyOfInterest(Item storedItem, ArrayData arrayData, int index) {
return true;
}

@Override
public final void afterOpcode(int seen) {
boolean isInvokingGetMessage = isWhatWeWantToDetect(seen);
super.afterOpcode(seen);

if (isInvokingGetMessage && !stack.isTop()) {
stack.getStackItem(0).setSpecialKind(getIsOfInterestKind());
}
}

@Override
protected final void onLog(@Nullable String format, @Nullable ArrayData arrayData) {
if (arrayData == null || !arrayData.isMarked()) {
return;
}
BugInstance bugInstance = new BugInstance(this,
bugPatternName, NORMAL_PRIORITY)
.addSourceLine(this).addClassAndMethod(this)
.addCalledMethod(this);
getBugReporter().reportBug(bugInstance);
}

abstract protected boolean isWhatWeWantToDetect(int seen);

abstract protected int getIsOfInterestKind();

}

0 comments on commit d1a2c62

Please sign in to comment.