All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jp.skypencil.findbugs.slf4j.ManualMessageDetector Maven / Gradle / Ivy

There is a newer version: 1.5.0
Show newest version
package jp.skypencil.findbugs.slf4j;

import static org.apache.bcel.Const.INVOKEVIRTUAL;

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;
import javax.annotation.Nullable;
import jp.skypencil.findbugs.slf4j.parameter.AbstractDetectorForParameterArray;
import jp.skypencil.findbugs.slf4j.parameter.ArrayData;
import jp.skypencil.findbugs.slf4j.parameter.ArrayDataHandler.Strategy;

@CustomUserValue
public final class ManualMessageDetector extends AbstractDetectorForParameterArray {
  @Item.SpecialKind
  private final int isMessage = Item.defineSpecialKind("message generated by throwable object");

  public ManualMessageDetector(BugReporter bugReporter) {
    super(bugReporter);
  }

  @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);
        }
      }
    };
  }

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

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

  private boolean isInvokingGetMessage(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);
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy