Search in sources :

Example 16 with Method

use of org.apache.bcel.classfile.Method in project fb-contrib by mebigfatguy.

the class WeakExceptionMessaging method visitCode.

/**
 * overrides the visitor to prescreen the method to look for throws calls and only forward onto bytecode scanning if there
 *
 * @param obj
 *            the context object of the currently parsed code block
 */
@Override
public void visitCode(Code obj) {
    Method method = getMethod();
    if (!method.isSynthetic() && prescreen(method)) {
        stack.resetForMethodEntry(this);
        super.visitCode(obj);
    }
}
Also used : Method(org.apache.bcel.classfile.Method)

Example 17 with Method

use of org.apache.bcel.classfile.Method in project fb-contrib by mebigfatguy.

the class WiringIssues method visitCode.

@Override
public void visitCode(Code obj) {
    Method m = getMethod();
    for (AnnotationEntry annotation : m.getAnnotationEntries()) {
        String type = annotation.getAnnotationType();
        if (type.startsWith("Lorg/junit/") || type.startsWith("Lorg/testng/")) {
            return;
        }
    }
    stack.resetForMethodEntry(this);
    super.visitCode(obj);
}
Also used : AnnotationEntry(org.apache.bcel.classfile.AnnotationEntry) Method(org.apache.bcel.classfile.Method) ToString(com.mebigfatguy.fbcontrib.utils.ToString)

Example 18 with Method

use of org.apache.bcel.classfile.Method in project fb-contrib by mebigfatguy.

the class CollectStatistics method visitCode.

@Override
public void visitCode(Code obj) {
    numMethodCalls = 0;
    modifiesState = false;
    byte[] code = obj.getCode();
    if (code == null) {
        return;
    }
    stack.resetForMethodEntry(this);
    curMethod = null;
    super.visitCode(obj);
    String clsName = getClassName();
    Method method = getMethod();
    int accessFlags = method.getAccessFlags();
    MethodInfo mi = Statistics.getStatistics().addMethodStatistics(clsName, getMethodName(), getMethodSig(), accessFlags, obj.getLength(), numMethodCalls);
    if ((clsName.indexOf(Values.INNER_CLASS_SEPARATOR) >= 0) || ((accessFlags & (Const.ACC_ABSTRACT | Const.ACC_INTERFACE | Const.ACC_ANNOTATION)) != 0)) {
        mi.addCallingAccess(Const.ACC_PUBLIC);
    } else if ((accessFlags & Const.ACC_PRIVATE) == 0) {
        if (isAssociationedWithAnnotations(method)) {
            mi.addCallingAccess(Const.ACC_PUBLIC);
        } else {
            String methodSig = getMethodName() + getMethodSig();
            for (String sig : COMMON_METHOD_SIG_PREFIXES) {
                if (methodSig.startsWith(sig)) {
                    mi.addCallingAccess(Const.ACC_PUBLIC);
                    break;
                }
            }
        }
    }
    mi.setModifiesState(modifiesState);
}
Also used : Method(org.apache.bcel.classfile.Method) QMethod(com.mebigfatguy.fbcontrib.utils.QMethod)

Example 19 with Method

use of org.apache.bcel.classfile.Method in project fb-contrib by mebigfatguy.

the class RegisterUtilsTest method shouldGetParameterRegisters.

@Test(dataProvider = "parameterRegisters")
public void shouldGetParameterRegisters(int accessFlags, String signature, int[] expected) {
    Method method = new Method();
    method.setAccessFlags(accessFlags);
    Constant[] cnst = new Constant[] { new ConstantUtf8(signature) };
    ConstantPool cp = new ConstantPool(cnst) {

        @Override
        protected Object clone() throws CloneNotSupportedException {
            throw new CloneNotSupportedException();
        }
    };
    method.setConstantPool(cp);
    method.setSignatureIndex(0);
    int[] regs = RegisterUtils.getParameterRegisters(method);
    assertEquals(regs, expected);
}
Also used : Constant(org.apache.bcel.classfile.Constant) ConstantPool(org.apache.bcel.classfile.ConstantPool) Method(org.apache.bcel.classfile.Method) BeforeMethod(org.testng.annotations.BeforeMethod) ConstantUtf8(org.apache.bcel.classfile.ConstantUtf8) Test(org.testng.annotations.Test)

Example 20 with Method

use of org.apache.bcel.classfile.Method in project fb-contrib by mebigfatguy.

the class OptionalIssues method sawOpcode.

/**
 * implements the visitor to look for reference compares of Optional, Optional use when more specific Optionals should be used, and use of orElse when
 * orElseGet would be more appropriate
 *
 * @param seen
 *            the opcode of the currently parsed instruction
 */
@Override
public void sawOpcode(int seen) {
    FQMethod curCalledMethod = null;
    Boolean sawPlainOptional = null;
    try {
        switch(seen) {
            case Const.IFNULL:
            case Const.IFNONNULL:
                if (stack.getStackDepth() > 0) {
                    OpcodeStack.Item itm = stack.getStackItem(0);
                    if ("Ljava/util/Optional;".equals(itm.getSignature())) {
                        bugReporter.reportBug(new BugInstance(this, BugType.OI_OPTIONAL_ISSUES_CHECKING_REFERENCE.name(), NORMAL_PRIORITY).addClass(this).addMethod(this).addSourceLine(this));
                    }
                }
                break;
            case Const.INVOKEDYNAMIC:
                // smells like a hack. Not sure how to do this better
                ConstantInvokeDynamic id = (ConstantInvokeDynamic) getConstantRefOperand();
                ConstantPool cp = getConstantPool();
                ConstantNameAndType nameAndType = (ConstantNameAndType) cp.getConstant(id.getNameAndTypeIndex());
                ConstantUtf8 typeConstant = (ConstantUtf8) cp.getConstant(nameAndType.getSignatureIndex());
                curCalledMethod = new FQMethod(getClassName(), "lambda$" + id.getBootstrapMethodAttrIndex(), typeConstant.getBytes());
                break;
            case Const.INVOKESTATIC:
            case Const.INVOKEINTERFACE:
            case Const.INVOKESPECIAL:
                String clsName = getClassConstantOperand();
                String methodName = getNameConstantOperand();
                curCalledMethod = new FQMethod(clsName, methodName, getSigConstantOperand());
                if ("java/util/Optional".equals(clsName) && "of".equals(methodName)) {
                    if (stack.getStackDepth() > 0) {
                        OpcodeStack.Item itm = stack.getStackItem(0);
                        String itmSig = itm.getSignature();
                        if (BOXED_OPTIONAL_TYPES.contains(itmSig)) {
                            bugReporter.reportBug(new BugInstance(this, BugType.OI_OPTIONAL_ISSUES_PRIMITIVE_VARIANT_PREFERRED.name(), LOW_PRIORITY).addClass(this).addMethod(this).addSourceLine(this));
                        }
                    }
                }
                break;
            case Const.INVOKEVIRTUAL:
                curCalledMethod = new FQMethod(getClassConstantOperand(), getNameConstantOperand(), getSigConstantOperand());
                if (OR_ELSE_METHODS.contains(curCalledMethod)) {
                    if (stack.getStackDepth() > 0) {
                        OpcodeStack.Item itm = stack.getStackItem(0);
                        if ((itm.getRegisterNumber() < 0) && (itm.getReturnValueOf() != null) && !isTrivialStackOps()) {
                            bugReporter.reportBug(new BugInstance(this, BugType.OI_OPTIONAL_ISSUES_USES_IMMEDIATE_EXECUTION.name(), NORMAL_PRIORITY).addClass(this).addMethod(this).addSourceLine(this));
                        }
                    }
                    if (OPTIONAL_OR_ELSE_METHOD.equals(curCalledMethod)) {
                        sawPlainOptional = Boolean.TRUE;
                    }
                } else if (OR_ELSE_GET_METHODS.contains(curCalledMethod)) {
                    if (!activeStackOps.isEmpty()) {
                        ActiveStackOp op = activeStackOps.getLast();
                        FQMethod method = op.getMethod();
                        if (method == null) {
                            bugReporter.reportBug(new BugInstance(this, BugType.OI_OPTIONAL_ISSUES_USES_ORELSEGET_WITH_NULL.name(), LOW_PRIORITY).addClass(this).addMethod(this).addSourceLine(this));
                        } else {
                            Method getMethod = getLambdaMethod(method.getMethodName());
                            if (getMethod != null) {
                                byte[] byteCode = getMethod.getCode().getCode();
                                if (byteCode.length <= 4) {
                                    // we are looking for ALOAD, GETFIELD, or LDC followed by ARETURN, that should fit in 4 bytes
                                    if (!hasInvoke(byteCode)) {
                                        bugReporter.reportBug(new BugInstance(this, BugType.OI_OPTIONAL_ISSUES_USES_DELAYED_EXECUTION.name(), LOW_PRIORITY).addClass(this).addMethod(this).addSourceLine(this));
                                    }
                                }
                            }
                        }
                    }
                    if (OPTIONAL_OR_ELSE_GET_METHOD.equals(curCalledMethod)) {
                        sawPlainOptional = Boolean.TRUE;
                    }
                } else if (OPTIONAL_GET_METHOD.equals(curCalledMethod)) {
                    sawPlainOptional = Boolean.TRUE;
                }
                break;
        }
    } finally {
        stack.sawOpcode(this, seen);
        int stackDepth = stack.getStackDepth();
        if (stackDepth == 0) {
            activeStackOps.clear();
        } else {
            activeStackOps.addLast(new ActiveStackOp(seen, curCalledMethod));
            while (activeStackOps.size() > stackDepth) {
                activeStackOps.removeFirst();
            }
            if (sawPlainOptional != null) {
                OpcodeStack.Item itm = stack.getStackItem(0);
                itm.setUserValue(sawPlainOptional);
            }
        }
    }
}
Also used : OpcodeStack(edu.umd.cs.findbugs.OpcodeStack) BugInstance(edu.umd.cs.findbugs.BugInstance) ToString(com.mebigfatguy.fbcontrib.utils.ToString) Method(org.apache.bcel.classfile.Method) FQMethod(com.mebigfatguy.fbcontrib.utils.FQMethod) ConstantUtf8(org.apache.bcel.classfile.ConstantUtf8) ConstantNameAndType(org.apache.bcel.classfile.ConstantNameAndType) ConstantPool(org.apache.bcel.classfile.ConstantPool) FQMethod(com.mebigfatguy.fbcontrib.utils.FQMethod) ConstantInvokeDynamic(org.apache.bcel.classfile.ConstantInvokeDynamic)

Aggregations

Method (org.apache.bcel.classfile.Method)79 JavaClass (org.apache.bcel.classfile.JavaClass)28 BugInstance (edu.umd.cs.findbugs.BugInstance)20 ToString (com.mebigfatguy.fbcontrib.utils.ToString)12 StopOpcodeParsingException (com.mebigfatguy.fbcontrib.utils.StopOpcodeParsingException)11 FQMethod (com.mebigfatguy.fbcontrib.utils.FQMethod)7 HashMap (java.util.HashMap)7 HashSet (java.util.HashSet)7 Field (org.apache.bcel.classfile.Field)6 Type (org.apache.bcel.generic.Type)6 AnnotationEntry (org.apache.bcel.classfile.AnnotationEntry)5 ExceptionTable (org.apache.bcel.classfile.ExceptionTable)5 OpcodeStack (edu.umd.cs.findbugs.OpcodeStack)4 SourceLineAnnotation (edu.umd.cs.findbugs.SourceLineAnnotation)4 ArrayList (java.util.ArrayList)4 Map (java.util.Map)4 ConstantPoolGen (org.apache.bcel.generic.ConstantPoolGen)4 BugType (com.mebigfatguy.fbcontrib.utils.BugType)3 QMethod (com.mebigfatguy.fbcontrib.utils.QMethod)3 XMethod (edu.umd.cs.findbugs.ba.XMethod)3