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

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

package jp.skypencil.findbugs.slf4j;

import static org.apache.bcel.Repository.lookupClass;

import org.apache.bcel.Constants;
import org.apache.bcel.classfile.JavaClass;

import edu.umd.cs.findbugs.OpcodeStack;
import edu.umd.cs.findbugs.OpcodeStack.Item;
import edu.umd.cs.findbugs.bcel.OpcodeStackDetector;

class ThrowableHandler {
    private static final String IS_THROWABLE = "IS_THROWABLE";
    private final JavaClass throwable;

    ThrowableHandler() {
        try {
            this.throwable = lookupClass("java/lang/Throwable");
        } catch (ClassNotFoundException e) {
            throw new AssertionError(e);
        }
    }

    void sawOpcode(OpcodeStackDetector detector, int seen) {
        if (detector.atCatchBlock()) {
            // the head of stack should be a Throwable instance
            detector.getStack().getStackItem(0).setUserValue(IS_THROWABLE);
        }
    }

    /**
     * Call this method after #afterOpcode of detector.
     */
    void afterOpcode(OpcodeStackDetector detector, int seen) {
        try {
            OpcodeStack stack = detector.getStack();
            if (seen == Constants.NEW && lookupClass(detector.getClassConstantOperand()).instanceOf(throwable)) {
                Item createdThrowable = stack.getStackItem(0);
                createdThrowable.setUserValue(IS_THROWABLE);
            } else if (seen == Constants.INVOKEINTERFACE || seen == Constants.INVOKEVIRTUAL) {
                String signature = detector.getMethodDescriptorOperand().getSignature();
                String returnType = signature.substring(1 + signature.lastIndexOf(')'));
                if (!returnType.startsWith("L")) {
                    // primitive value should be non-throwable
                    return;
                }

                returnType = returnType.substring(1, returnType.length() - 1).replaceAll("/", ".");
                JavaClass returnClass = lookupClass(returnType);
                if (returnClass.instanceOf(throwable)) {
                    Item returnedThrowable = stack.getStackItem(0);
                    returnedThrowable.setUserValue(IS_THROWABLE);
                }
            }
        } catch (ClassNotFoundException e) {
            throw new IllegalStateException("class not found", e);
        }
    }

    /**
     * @return true if given Item is throwable
     */
    boolean checkThrowable(Item stackItem) {
        return IS_THROWABLE.equals(stackItem.getUserValue());
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy