Example usage for org.objectweb.asm.tree FieldInsnNode getOpcode

List of usage examples for org.objectweb.asm.tree FieldInsnNode getOpcode

Introduction

In this page you can find the example usage for org.objectweb.asm.tree FieldInsnNode getOpcode.

Prototype

public int getOpcode() 

Source Link

Document

Returns the opcode of this instruction.

Usage

From source file:org.evosuite.instrumentation.mutation.ReplaceVariable.java

License:Open Source License

/**
 * <p>/*from  w  w  w. jav a  2 s  .c  o  m*/
 * copy
 * </p>
 *
 * @param orig
 *            a {@link org.objectweb.asm.tree.InsnList} object.
 * @return a {@link org.objectweb.asm.tree.InsnList} object.
 */
public static InsnList copy(InsnList orig) {
    Iterator<?> it = orig.iterator();
    InsnList copy = new InsnList();
    while (it.hasNext()) {
        AbstractInsnNode node = (AbstractInsnNode) it.next();

        if (node instanceof VarInsnNode) {
            VarInsnNode vn = (VarInsnNode) node;
            copy.add(new VarInsnNode(vn.getOpcode(), vn.var));
        } else if (node instanceof FieldInsnNode) {
            FieldInsnNode fn = (FieldInsnNode) node;
            copy.add(new FieldInsnNode(fn.getOpcode(), fn.owner, fn.name, fn.desc));
        } else if (node instanceof InsnNode) {
            if (node.getOpcode() != Opcodes.POP)
                copy.add(new InsnNode(node.getOpcode()));
        } else if (node instanceof LdcInsnNode) {
            copy.add(new LdcInsnNode(((LdcInsnNode) node).cst));
        } else {
            throw new RuntimeException("Unexpected node type: " + node.getClass());
        }
    }
    return copy;
}

From source file:org.evosuite.instrumentation.testability.transformer.BooleanCallsTransformer.java

License:Open Source License

@Override
protected AbstractInsnNode transformFieldInsnNode(MethodNode mn, FieldInsnNode fieldNode) {

    // TODO: If the field owner is not transformed, then convert this to a proper Boolean
    fieldNode.desc = this.booleanTestabilityTransformation.transformFieldDescriptor(fieldNode.owner,
            fieldNode.name, fieldNode.desc);

    // If after transformation the field is still Boolean, we need to convert 
    if (Type.getType(fieldNode.desc).equals(Type.BOOLEAN_TYPE)) {
        if (fieldNode.getOpcode() == Opcodes.PUTFIELD || fieldNode.getOpcode() == Opcodes.PUTSTATIC) {
            MethodInsnNode n = new MethodInsnNode(Opcodes.INVOKESTATIC,
                    Type.getInternalName(BooleanHelper.class), "intToBoolean",
                    Type.getMethodDescriptor(Type.BOOLEAN_TYPE, new Type[] { Type.INT_TYPE }));
            TransformationStatistics.transformBackToBooleanField();
            mn.instructions.insertBefore(fieldNode, n);
        } else {/*from w  w  w  . ja v a  2  s. c  o  m*/
            MethodInsnNode n = new MethodInsnNode(Opcodes.INVOKESTATIC,
                    Type.getInternalName(BooleanHelper.class), "booleanToInt",
                    Type.getMethodDescriptor(Type.INT_TYPE, new Type[] { Type.BOOLEAN_TYPE }));
            mn.instructions.insert(fieldNode, n);
            TransformationStatistics.transformBackToBooleanField();
            return n;
        }
    }
    return fieldNode;
}

From source file:org.evosuite.instrumentation.testability.transformer.BooleanDefinitionTransformer.java

License:Open Source License

@Override
protected AbstractInsnNode transformFieldInsnNode(MethodNode mn, FieldInsnNode fieldNode) {
    // This handles the else branch for field assignments
    if (DescriptorMapping.getInstance().isTransformedOrBooleanField(
            this.booleanTestabilityTransformation.className, fieldNode.name, fieldNode.desc)) {
        if (fieldNode.getNext() instanceof FieldInsnNode) {
            FieldInsnNode other = (FieldInsnNode) fieldNode.getNext();
            if (fieldNode.owner.equals(other.owner) && fieldNode.name.equals(other.name)
                    && fieldNode.desc.equals(other.desc)) {
                if (fieldNode.getOpcode() == Opcodes.GETFIELD && other.getOpcode() == Opcodes.PUTFIELD) {
                    this.booleanTestabilityTransformation.insertGetBefore(other, mn.instructions);
                } else if (fieldNode.getOpcode() == Opcodes.GETSTATIC
                        && other.getOpcode() == Opcodes.PUTSTATIC) {
                    this.booleanTestabilityTransformation.insertGetBefore(other, mn.instructions);
                }//from  www .ja v  a 2  s.c  o  m
            }
        }
    }
    return fieldNode;
}

From source file:org.evosuite.instrumentation.testability.transformer.ImplicitElseTransformer.java

License:Open Source License

private void handleDependency(ControlDependency dependency, ControlDependenceGraph cdg, MethodNode mn,
        FieldInsnNode varNode, BytecodeInstruction parentLevel) {

    if (addedNodes.contains(dependency))
        return;//from   ww  w.j  a v  a 2 s  .c o m

    // Get the basic blocks reachable if the dependency would evaluate different
    Set<BasicBlock> blocks = cdg.getAlternativeBlocks(dependency);
    addedNodes.add(dependency);

    Set<ControlDependency> dependencies = dependency.getBranch().getInstruction().getControlDependencies();
    //if (dependencies.size() == 1) {
    //   ControlDependency dep = dependencies.iterator().next();
    for (ControlDependency dep : dependencies) {
        if (!addedNodes.contains(dep) && dep != dependency)
            handleDependency(dep, cdg, mn, varNode, dependency.getBranch().getInstruction());
    }

    // TODO: Need to check that there is an assignment in every alternative path through CDG

    boolean hasAssignment = false;
    for (BasicBlock block : blocks) {
        // If this block also assigns a value to the same variable
        for (BytecodeInstruction instruction : block) {
            if (instruction.getASMNode().getOpcode() == Opcodes.PUTFIELD
                    || instruction.getASMNode().getOpcode() == Opcodes.PUTSTATIC) {
                FieldInsnNode otherFieldNode = (FieldInsnNode) instruction.getASMNode();
                FieldInsnNode thisFieldNode = varNode;
                if (otherFieldNode.owner.equals(thisFieldNode.owner)
                        && otherFieldNode.name.equals(thisFieldNode.name)) {
                    hasAssignment = true;
                    break;
                }
            }
        }
        if (hasAssignment) {
            break;
        }
    }

    // The Flag assignment is is the dependency evaluates to the given value
    // We thus need to insert the tautoligical assignment either directly after the IF (if the value is true)
    // or before the jump target (if the value is false)

    if (!hasAssignment) {
        if (dependency.getBranch().getInstruction().isSwitch()) {
            BooleanTestabilityTransformation.logger.warn("Don't know how to handle Switches yet");
            return;
        }

        TransformationStatistics.transformedImplicitElse();

        JumpInsnNode jumpNode = (JumpInsnNode) dependency.getBranch().getInstruction().getASMNode();
        FieldInsnNode newLoad = new FieldInsnNode(
                varNode.getOpcode() == Opcodes.PUTSTATIC ? Opcodes.GETSTATIC : Opcodes.GETFIELD, varNode.owner,
                varNode.name, varNode.desc);
        FieldInsnNode newStore = new FieldInsnNode(varNode.getOpcode(), varNode.owner, varNode.name,
                varNode.desc);
        AbstractInsnNode newOwnerLoad1 = null;
        AbstractInsnNode newOwnerLoad2 = null;
        if (varNode.getOpcode() == Opcodes.PUTFIELD) {
            // Need to copy the bloody owner
            // Check for VarInsn
            //if (varNode.getPrevious().getOpcode() == Opcodes.ALOAD) {
            newOwnerLoad1 = new VarInsnNode(Opcodes.ALOAD, 0);
            newOwnerLoad2 = new VarInsnNode(Opcodes.ALOAD, 0);
            /*
            } else {
            // Else use helper function
            // Insert DUP and
            logger.info("Wargh");
            System.exit(0);
            fieldOwnerId++;
            InsnNode dupNode = new InsnNode(Opcodes.DUP);
            mn.instructions.insertBefore(varNode, new LdcInsnNode(
            fieldOwnerId));
            mn.instructions.insertBefore(varNode, dupNode);
            registerInstruction(mn, varNode, dupNode);
            MethodInsnNode storeOwner = new MethodInsnNode(
            Opcodes.INVOKESTATIC,
            "org/evosuite/instrumentation/BooleanHelper",
            "setFieldOwner", "(ILjava/lang/Object;)V");
            mn.instructions.insertBefore(varNode, storeOwner);
            registerInstruction(mn, varNode, storeOwner);
            newOwnerLoad1 = new MethodInsnNode(Opcodes.INVOKESTATIC,
            "org/evosuite/instrumentation/BooleanHelper",
            "getFieldOwner", "(I)Ljava/lang/Object;");
            newOwnerLoad2 = new MethodInsnNode(Opcodes.INVOKESTATIC,
            "org/evosuite/instrumentation/BooleanHelper",
            "getFieldOwner", "(I)Ljava/lang/Object;");
            }
            */
        }

        if (dependency.getBranchExpressionValue()) {
            BooleanTestabilityTransformation.logger.info("Inserting after if");
            // Insert directly after if
            mn.instructions.insert(jumpNode, newStore);
            mn.instructions.insert(jumpNode, newLoad);
            if (newOwnerLoad1 != null) {
                mn.instructions.insert(jumpNode, newOwnerLoad1);
                registerInstruction(mn, varNode, newOwnerLoad1);
            }
            if (newOwnerLoad2 != null) {
                mn.instructions.insert(jumpNode, newOwnerLoad2);
                registerInstruction(mn, varNode, newOwnerLoad2);
            }
            registerInstruction(mn, varNode, newStore);
            registerInstruction(mn, varNode, newLoad);

        } else {
            BooleanTestabilityTransformation.logger.info("Inserting as jump target");

            // Insert as jump target
            LabelNode target = jumpNode.label;
            LabelNode newTarget = new LabelNode(new Label());

            registerInstruction(mn, target, newStore);
            registerInstruction(mn, target, newLoad);

            InsnList assignment = new InsnList();
            assignment.add(new JumpInsnNode(Opcodes.GOTO, target));
            assignment.add(newTarget);
            if (newOwnerLoad1 != null) {
                assignment.add(newOwnerLoad1);
                registerInstruction(mn, target, newOwnerLoad1);
            }
            if (newOwnerLoad2 != null) {
                assignment.add(newOwnerLoad2);
                registerInstruction(mn, target, newOwnerLoad2);
            }
            assignment.add(newLoad);
            assignment.add(newStore);
            jumpNode.label = newTarget;

            mn.instructions.insertBefore(target, assignment);
        }
        addedInsns.add(newStore);
        addedInsns.add(newLoad);
    }

}

From source file:org.evosuite.instrumentation.testability.transformer.ImplicitElseTransformer.java

License:Open Source License

@SuppressWarnings("unchecked")
@Override// w w w  .  ja  v  a 2 s .c  om
protected AbstractInsnNode transformFieldInsnNode(MethodNode mn, FieldInsnNode fieldNode) {

    if ((fieldNode.getOpcode() == Opcodes.PUTFIELD || fieldNode.getOpcode() == Opcodes.PUTSTATIC)
            && DescriptorMapping.getInstance().isTransformedOrBooleanField(fieldNode.owner, fieldNode.name,
                    fieldNode.desc)) {

        if (addedInsns.contains(fieldNode))
            return fieldNode;

        // Can only handle cases where the field owner is loaded directly before the field
        // TODO: We could pop the top of the stack and DUP the owner, but would need to take care
        // whether we need to pop one or two words
        if (fieldNode.getOpcode() == Opcodes.PUTFIELD) {
            AbstractInsnNode previous = fieldNode.getPrevious();
            while (previous instanceof LineNumberNode || previous instanceof FrameNode
                    || previous.getOpcode() == Opcodes.ICONST_0 || previous.getOpcode() == Opcodes.ICONST_1)
                previous = previous.getPrevious();
            if (previous.getOpcode() != Opcodes.ALOAD) {
                BooleanTestabilityTransformation.logger.info("Can't handle case of " + previous);
                return fieldNode;
            }
            VarInsnNode varNode = (VarInsnNode) previous;
            if (varNode.var != 0) {
                BooleanTestabilityTransformation.logger.info("Can't handle case of " + previous);
                return fieldNode;
            }
        }
        BooleanTestabilityTransformation.logger.info("Handling PUTFIELD case!");

        // Check if ICONST_0 or ICONST_1 are on the stack
        ControlDependenceGraph cdg = GraphPool.getInstance(this.booleanTestabilityTransformation.classLoader)
                .getCDG(this.booleanTestabilityTransformation.className.replace("/", "."), mn.name + mn.desc);
        int index = mn.instructions.indexOf(fieldNode);
        BooleanTestabilityTransformation.logger.info("Getting bytecode instruction for " + fieldNode.name + "/"
                + ((FieldInsnNode) mn.instructions.get(index)).name);
        InsnList nodes = mn.instructions;
        ListIterator<AbstractInsnNode> it = nodes.iterator();
        while (it.hasNext()) {
            BytecodeInstruction in = new BytecodeInstruction(this.booleanTestabilityTransformation.classLoader,
                    this.booleanTestabilityTransformation.className, mn.name, 0, 0, it.next());
            BooleanTestabilityTransformation.logger.info(in.toString());
        }
        BytecodeInstruction insn = BytecodeInstructionPool
                .getInstance(this.booleanTestabilityTransformation.classLoader)
                .getInstruction(this.booleanTestabilityTransformation.className.replace("/", "."),
                        mn.name + mn.desc, index);
        if (insn == null)
            insn = BytecodeInstructionPool.getInstance(this.booleanTestabilityTransformation.classLoader)
                    .getInstruction(this.booleanTestabilityTransformation.className.replace("/", "."),
                            mn.name + mn.desc, fieldNode);
        //varNode);
        if (insn == null) {
            // TODO: Find out why
            BooleanTestabilityTransformation.logger.info("ERROR: Could not find node");
            return fieldNode;
        }
        if (insn.getASMNode().getOpcode() != fieldNode.getOpcode()) {
            BooleanTestabilityTransformation.logger.info("Found wrong bytecode instruction at this index!");
            BytecodeInstructionPool.getInstance(this.booleanTestabilityTransformation.classLoader)
                    .getInstruction(this.booleanTestabilityTransformation.className, mn.name + mn.desc,
                            fieldNode);
        }
        if (insn.getBasicBlock() == null) {
            BooleanTestabilityTransformation.logger.info("ERROR: Problematic node found");
            return fieldNode;
        }
        Set<ControlDependency> dependencies = insn.getControlDependencies();
        BooleanTestabilityTransformation.logger.info("Found flag assignment: " + insn + ", checking "
                + dependencies.size() + " control dependencies");

        for (ControlDependency dep : dependencies) {
            if (!addedNodes.contains(dep))
                handleDependency(dep, cdg, mn, fieldNode, insn);
        }
    }
    return fieldNode;
}

From source file:org.evosuite.setup.GetStaticGraphGenerator.java

License:Open Source License

/**
 * Descend into a static field read/*from   w w  w . j  a v  a2 s .  com*/
 * 
 */
private static void handleFieldInsnNode(GetStaticGraph staticUsageTree, ClassNode cn, MethodNode mn,
        FieldInsnNode insn, int depth) {

    // Skip field instructions that are not reads to static fields
    if (insn.getOpcode() != Opcodes.GETSTATIC) {
        return;
    }

    // Only collect relations for instrumentable classes
    String calleeClassName = insn.owner.replaceAll("/", ".");
    if (BytecodeInstrumentation.checkIfCanInstrument(calleeClassName)) {
        logger.debug("Handling field read: " + insn.name);
        if (!staticUsageTree.hasStaticFieldRead(cn.name, mn.name + mn.desc, insn.owner, insn.name)) {

            handleClassInitializer(staticUsageTree, cn, mn, insn.owner, depth);

            // Add static read from mn to insn to static usage graph
            staticUsageTree.addStaticFieldRead(cn.name, mn.name + mn.desc, insn.owner, insn.name);

            handle(staticUsageTree, insn.owner, insn.name + insn.desc, depth);
        }
    }

}

From source file:org.evosuite.setup.PutStaticMethodCollector.java

License:Open Source License

@SuppressWarnings("unchecked")
public Set<MethodIdentifier> collectMethods() {

    Set<MethodIdentifier> methods = new LinkedHashSet<MethodIdentifier>();

    for (String calledClassName : getStaticFields.keySet()) {
        ClassNode classNode = DependencyAnalysis.getClassNode(calledClassName);
        List<MethodNode> classMethods = classNode.methods;
        for (MethodNode mn : classMethods) {
            if (mn.name.equals(CLINIT))
                continue;

            InsnList instructions = mn.instructions;
            Iterator<AbstractInsnNode> it = instructions.iterator();
            while (it.hasNext()) {
                AbstractInsnNode insn = it.next();
                if (insn instanceof FieldInsnNode) {
                    FieldInsnNode fieldInsn = (FieldInsnNode) insn;
                    if (fieldInsn.getOpcode() != Opcodes.PUTSTATIC) {
                        continue;
                    }//from   w  w  w .  ja  va2s .c o m
                    String calleeClassName = fieldInsn.owner.replaceAll("/", ".");
                    String calleeFieldName = fieldInsn.name;

                    if (contains(getStaticFields, calleeClassName, calleeFieldName)) {

                        MethodIdentifier methodIdentifier = new MethodIdentifier(calledClassName, mn.name,
                                mn.desc);
                        methods.add(methodIdentifier);

                    }
                }
            }

        }

    }
    return methods;
}

From source file:org.jooby.internal.apitool.BytecodeRouteParser.java

License:Apache License

private Object paramValue(final ClassLoader loader, final ClassNode owner, final MethodNode method,
        final AbstractInsnNode n) {
    if (n instanceof LdcInsnNode) {

        Object cst = ((LdcInsnNode) n).cst;
        if (cst instanceof Type) {
            boolean typePresent = new Insn<>(method, n).next().filter(is(MethodInsnNode.class)).findFirst()
                    .map(MethodInsnNode.class::cast).filter(mutantToSomething().or(getOrCreateKotlinClass()))
                    .isPresent();/*w  w  w.j a va 2  s .  com*/
            if (typePresent) {
                return null;
            }
            return loadType(loader, ((Type) cst).getClassName());
        }
        return cst;
    } else if (n instanceof InsnNode) {
        InsnNode insn = (InsnNode) n;
        switch (insn.getOpcode()) {
        case Opcodes.ICONST_0:
            return 0;
        case Opcodes.ICONST_1:
            return 1;
        case Opcodes.ICONST_2:
            return 2;
        case Opcodes.ICONST_3:
            return 3;
        case Opcodes.ICONST_4:
            return 4;
        case Opcodes.ICONST_5:
            return 5;
        case Opcodes.LCONST_0:
            return 0L;
        case Opcodes.LCONST_1:
            return 1L;
        case Opcodes.FCONST_0:
            return 0f;
        case Opcodes.FCONST_1:
            return 1f;
        case Opcodes.FCONST_2:
            return 2f;
        case Opcodes.DCONST_0:
            return 0d;
        case Opcodes.DCONST_1:
            return 1d;
        case Opcodes.ICONST_M1:
            return -1;
        case Opcodes.ACONST_NULL:
            return null;
        }
    } else if (n instanceof IntInsnNode) {
        IntInsnNode intinsn = (IntInsnNode) n;
        return intinsn.operand;
    } else if (n instanceof FieldInsnNode) {
        // toEnum
        FieldInsnNode finsn = (FieldInsnNode) n;
        if (finsn.getOpcode() == GETSTATIC) {
            java.lang.reflect.Type possibleEnum = loadType(loader, finsn.owner);
            if (MoreTypes.getRawType(possibleEnum).isEnum()) {
                return finsn.name;
            }
        }
    }
    return n;
}

From source file:org.lambdamatic.analyzer.ast.LambdaExpressionReader.java

License:Open Source License

/**
 * Reads the bytecode from the given {@link InsnCursor}'s <strong>current position</strong>, until
 * there is no further instruction to proceed. It is the responsability of the caller to set the
 * cursor position./* www.  j  ava  2s  .c  om*/
 * 
 * @param insnCursor the instruction cursor used to read the bytecode.
 * @param expressionStack the expression stack to put on or pop from.
 * @param localVariables the local variables
 * @return a {@link List} of {@link Statement} containing the {@link Statement}
 */
private List<Statement> readStatements(final InsnCursor insnCursor, final Stack<Expression> expressionStack,
        final List<CapturedArgument> capturedArguments, final LocalVariables localVariables) {
    final List<Statement> statements = new ArrayList<>();
    while (insnCursor.hasCurrent()) {
        final AbstractInsnNode currentInstruction = insnCursor.getCurrent();
        switch (currentInstruction.getType()) {
        case AbstractInsnNode.VAR_INSN:
            final VarInsnNode varInstruction = (VarInsnNode) currentInstruction;
            switch (currentInstruction.getOpcode()) {
            // load a reference onto the stack from a local variable
            case Opcodes.ALOAD:
            case Opcodes.ILOAD:
                // load an int value from a local variable
                // Note: The 'var' operand is the index of a local variable
                // all captured arguments come before the local variable in the method signature,
                // which means that the local variables table is empty on the first slots which are
                // "allocated"
                // for the captured arguments.
                if (varInstruction.var < capturedArguments.size()) {
                    // if the variable index matches a captured argument
                    // note: not using actual captured argument but rather, use a _reference_ to it.
                    final Object capturedArgumentValue = capturedArguments.get(varInstruction.var).getValue();
                    final Class<?> capturedArgumentValueType = capturedArgumentValue != null
                            ? capturedArgumentValue.getClass()
                            : Object.class;
                    final CapturedArgumentRef capturedArgumentRef = new CapturedArgumentRef(varInstruction.var,
                            capturedArgumentValueType);
                    expressionStack.add(capturedArgumentRef);
                } else {
                    // the variable index matches a local variable
                    final LocalVariableNode var = localVariables.load(varInstruction.var);
                    expressionStack.add(new LocalVariable(var.index, var.name, readSignature(var.desc)));
                }
                break;
            case Opcodes.ASTORE:
                // store a reference into a local variable
                localVariables.store(varInstruction.var);
                break;
            default:
                throw new AnalyzeException(
                        "Unexpected Variable instruction code: " + varInstruction.getOpcode());
            }
            break;
        case AbstractInsnNode.LDC_INSN:
            // let's move this instruction on top of the stack until it
            // is used as an argument during a method call
            final LdcInsnNode ldcInsnNode = (LdcInsnNode) currentInstruction;
            final Expression constant = ExpressionFactory.getExpression(ldcInsnNode.cst);
            LOGGER.trace("Stacking constant {}", constant);
            expressionStack.add(constant);
            break;
        case AbstractInsnNode.FIELD_INSN:
            final FieldInsnNode fieldInsnNode = (FieldInsnNode) currentInstruction;
            switch (fieldInsnNode.getOpcode()) {
            case Opcodes.GETSTATIC:
                final Type ownerType = Type.getType(fieldInsnNode.desc);
                final FieldAccess staticFieldAccess = new FieldAccess(new ClassLiteral(getType(ownerType)),
                        fieldInsnNode.name);
                expressionStack.add(staticFieldAccess);
                break;

            case Opcodes.GETFIELD:
                final Expression fieldAccessParent = expressionStack.pop();
                final FieldAccess fieldAccess = new FieldAccess(fieldAccessParent, fieldInsnNode.name);
                expressionStack.add(fieldAccess);
                break;
            case Opcodes.PUTFIELD:
                final Expression fieldAssignationValue = expressionStack.pop();
                final Expression parentSource = expressionStack.pop();
                final FieldAccess source = new FieldAccess(parentSource, fieldInsnNode.name);
                final Assignment assignmentExpression = new Assignment(source, fieldAssignationValue);
                statements.add(new ExpressionStatement(assignmentExpression));
                break;
            default:
                throw new AnalyzeException("Unexpected field instruction type: " + fieldInsnNode.getOpcode());

            }
            break;
        case AbstractInsnNode.METHOD_INSN:
            final MethodInsnNode methodInsnNode = (MethodInsnNode) currentInstruction;
            final Type[] argumentTypes = Type.getArgumentTypes(methodInsnNode.desc);
            final List<Expression> args = new ArrayList<>();
            final List<Class<?>> parameterTypes = new ArrayList<>();
            Stream.of(argumentTypes).forEach(argumentType -> {
                final Expression arg = expressionStack.pop();
                final String argumentClassName = argumentType.getClassName();
                args.add(castOperand(arg, argumentClassName));
                try {
                    parameterTypes.add(ClassUtils.getClass(argumentClassName));
                } catch (Exception e) {
                    throw new AnalyzeException("Failed to find class '" + argumentClassName + "'", e);
                }
            });
            // arguments appear in reverse order in the bytecode
            Collections.reverse(args);
            switch (methodInsnNode.getOpcode()) {
            case Opcodes.INVOKEINTERFACE:
            case Opcodes.INVOKEVIRTUAL:
            case Opcodes.INVOKESPECIAL:
                // object instantiation
                if (methodInsnNode.name.equals("<init>")) {
                    final ObjectInstanciation objectVariable = (ObjectInstanciation) expressionStack.pop();
                    objectVariable.setInitArguments(args);
                } else {
                    final Expression sourceExpression = expressionStack.pop();
                    final Method javaMethod = ReflectionUtils.findJavaMethod(sourceExpression.getJavaType(),
                            methodInsnNode.name, parameterTypes);
                    final Class<?> returnType = findReturnType(insnCursor, javaMethod);
                    final MethodInvocation invokedMethod = new MethodInvocation(sourceExpression, javaMethod,
                            returnType, args);
                    expressionStack.add(invokedMethod);
                }
                break;
            case Opcodes.INVOKESTATIC:
                final Type type = Type.getObjectType(methodInsnNode.owner);
                try {
                    final Class<?> sourceClass = Class.forName(type.getClassName());
                    final Method javaMethod = ReflectionUtils.findJavaMethod(sourceClass, methodInsnNode.name,
                            parameterTypes);
                    final Class<?> returnType = findReturnType(insnCursor, javaMethod);
                    final MethodInvocation invokedStaticMethod = new MethodInvocation(
                            new ClassLiteral(sourceClass), javaMethod, returnType, args);
                    expressionStack.add(invokedStaticMethod);
                } catch (ClassNotFoundException e) {
                    throw new AnalyzeException("Failed to retrieve class for " + methodInsnNode.owner, e);
                }
                break;
            default:
                throw new AnalyzeException("Unexpected method invocation type: " + methodInsnNode.getOpcode());
            }
            break;
        case AbstractInsnNode.INVOKE_DYNAMIC_INSN:
            final InvokeDynamicInsnNode invokeDynamicInsnNode = (InvokeDynamicInsnNode) currentInstruction;
            final Handle handle = (Handle) invokeDynamicInsnNode.bsmArgs[1];
            final int argNumber = Type.getArgumentTypes(invokeDynamicInsnNode.desc).length;
            final List<CapturedArgumentRef> lambdaArgs = new ArrayList<>();
            for (int i = 0; i < argNumber; i++) {
                final Expression expr = expressionStack.pop();
                if (expr.getExpressionType() != ExpressionType.CAPTURED_ARGUMENT_REF) {
                    throw new AnalyzeException("Unexpected argument type when following InvokeDynamic call: "
                            + expr.getExpressionType());
                }
                lambdaArgs.add((CapturedArgumentRef) expr); // , expr.getValue()
            }
            Collections.reverse(lambdaArgs);
            final EmbeddedSerializedLambdaInfo lambdaInfo = new EmbeddedSerializedLambdaInfo(handle.getOwner(),
                    handle.getName(), handle.getDesc(), lambdaArgs, capturedArguments);
            final LambdaExpression lambdaExpression = LambdaExpressionAnalyzer.getInstance()
                    .analyzeExpression(lambdaInfo);
            expressionStack.add(lambdaExpression);
            break;
        case AbstractInsnNode.JUMP_INSN:
            statements.addAll(
                    readJumpInstruction(insnCursor, expressionStack, capturedArguments, localVariables));
            return statements;
        case AbstractInsnNode.INT_INSN:
            readIntInstruction((IntInsnNode) currentInstruction, expressionStack, localVariables);
            break;
        case AbstractInsnNode.INSN:
            final List<Statement> instructionStatement = readInstruction(insnCursor, expressionStack,
                    capturedArguments, localVariables);
            statements.addAll(instructionStatement);
            break;
        case AbstractInsnNode.TYPE_INSN:
            readTypeInstruction((TypeInsnNode) currentInstruction, expressionStack, localVariables);
            break;
        default:
            throw new AnalyzeException(
                    "This is embarrassing... We've reached an unexpected instruction operator: "
                            + currentInstruction.getType());
        }
        insnCursor.next();
    }
    return statements;
}

From source file:org.mutabilitydetector.checkers.CollectionTypeWrappedInUnmodifiableIdiomChecker.java

License:Apache License

public CollectionTypeWrappedInUnmodifiableIdiomChecker(FieldInsnNode fieldInsnNode, Type typeAssignedToField) {
    checkArgument(fieldInsnNode.getOpcode() == Opcodes.PUTFIELD,
            "Checking for unmodifiable wrap idiom requires PUTFIELD instruction");

    this.fieldInsnNode = fieldInsnNode;
    this.typeAssignedToField = typeAssignedToField;
}