Example usage for org.objectweb.asm Opcodes INVOKEVIRTUAL

List of usage examples for org.objectweb.asm Opcodes INVOKEVIRTUAL

Introduction

In this page you can find the example usage for org.objectweb.asm Opcodes INVOKEVIRTUAL.

Prototype

int INVOKEVIRTUAL

To view the source code for org.objectweb.asm Opcodes INVOKEVIRTUAL.

Click Source Link

Usage

From source file:com.github.malamut2.low.AllocationMethodAdapter.java

License:Apache License

private void pushClassNameOnStack() {
    super.visitInsn(Opcodes.DUP);
    // -> stack: ... class class
    super.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Class", "getName", "()Ljava/lang/String;", false);
    // -> stack: ... class classNameDotted
    super.visitLdcInsn('.');
    // -> stack: ... class classNameDotted '.'
    super.visitLdcInsn('/');
    // -> stack: ... class classNameDotted '.' '/'
    super.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/String", "replace", "(CC)Ljava/lang/String;",
            false);/* w w  w  .  j  av a 2 s .c om*/
    // -> stack: ... class className
}

From source file:com.github.malamut2.low.AllocationMethodAdapter.java

License:Apache License

/**
 * Reflection-based allocation (@see java.lang.reflect.Array#newInstance) is
 * triggered with a static method call (INVOKESTATIC), so we hook it here.
 * Class initialization is triggered with a constructor call (INVOKESPECIAL)
 * so we hook that here too as a proxy for the new bytecode which leaves an
 * uninitialized object on the stack that we're not allowed to touch.
 * {@link java.lang.Object#clone} is also a call to INVOKESPECIAL,
 * and is hooked here.  {@link java.lang.Class#newInstance} and
 * {@link java.lang.reflect.Constructor#newInstance} are both
 * INVOKEVIRTUAL calls, so they are hooked here, as well.
 *//*from   w ww  . jav a 2 s .c o  m*/
@Override
public void visitMethodInsn(int opcode, String owner, String name, String signature, boolean itf) {
    if (opcode == Opcodes.INVOKESTATIC &&
    // Array does its own native allocation.  Grr.
            owner.equals("java/lang/reflect/Array") && name.equals("newInstance")) {
        if (signature.equals("(Ljava/lang/Class;I)Ljava/lang/Object;")) {

            Label beginScopeLabel = new Label();
            Label endScopeLabel = new Label();
            super.visitLabel(beginScopeLabel);

            // stack: ... class count
            int countIndex = newLocal("I", beginScopeLabel, endScopeLabel);
            super.visitVarInsn(Opcodes.ISTORE, countIndex);
            // -> stack: ... class
            pushClassNameOnStack();
            // -> stack: ... class className
            int typeNameIndex = newLocal("Ljava/lang/String;", beginScopeLabel, endScopeLabel);
            super.visitVarInsn(Opcodes.ASTORE, typeNameIndex);
            // -> stack: ... class
            super.visitVarInsn(Opcodes.ILOAD, countIndex);
            // -> stack: ... class count
            super.visitMethodInsn(opcode, owner, name, signature, itf);
            // -> stack: ... newobj
            super.visitInsn(Opcodes.DUP);
            // -> stack: ... newobj newobj
            super.visitVarInsn(Opcodes.ILOAD, countIndex);
            // -> stack: ... newobj newobj count
            super.visitInsn(Opcodes.SWAP);
            // -> stack: ... newobj count newobj
            super.visitVarInsn(Opcodes.ALOAD, typeNameIndex);
            super.visitLabel(endScopeLabel);
            // -> stack: ... newobj count newobj className
            super.visitInsn(Opcodes.SWAP);
            // -> stack: ... newobj count className newobj
            super.visitMethodInsn(Opcodes.INVOKESTATIC, recorderClass, recorderMethod, RECORDER_SIGNATURE,
                    false);
            // -> stack: ... newobj
            return;
        } else if (signature.equals("(Ljava/lang/Class;[I)Ljava/lang/Object;")) {
            Label beginScopeLabel = new Label();
            Label endScopeLabel = new Label();
            super.visitLabel(beginScopeLabel);

            int dimsArrayIndex = newLocal("[I", beginScopeLabel, endScopeLabel);
            // stack: ... class dimsArray
            pushProductOfIntArrayOnStack();
            // -> stack: ... class dimsArray product
            int productIndex = newLocal("I", beginScopeLabel, endScopeLabel);
            super.visitVarInsn(Opcodes.ISTORE, productIndex);
            // -> stack: ... class dimsArray

            super.visitVarInsn(Opcodes.ASTORE, dimsArrayIndex);
            // -> stack: ... class
            pushClassNameOnStack();
            // -> stack: ... class className
            int typeNameIndex = newLocal("Ljava/lang/String;", beginScopeLabel, endScopeLabel);
            super.visitVarInsn(Opcodes.ASTORE, typeNameIndex);
            // -> stack: ... class
            super.visitVarInsn(Opcodes.ALOAD, dimsArrayIndex);
            // -> stack: ... class dimsArray
            super.visitMethodInsn(opcode, owner, name, signature, itf);
            // -> stack: ... newobj

            super.visitInsn(Opcodes.DUP);
            // -> stack: ... newobj newobj
            super.visitVarInsn(Opcodes.ILOAD, productIndex);
            // -> stack: ... newobj newobj product
            super.visitInsn(Opcodes.SWAP);
            // -> stack: ... newobj product newobj
            super.visitVarInsn(Opcodes.ALOAD, typeNameIndex);
            super.visitLabel(endScopeLabel);
            // -> stack: ... newobj product newobj className
            super.visitInsn(Opcodes.SWAP);
            // -> stack: ... newobj product className newobj
            super.visitMethodInsn(Opcodes.INVOKESTATIC, recorderClass, recorderMethod, RECORDER_SIGNATURE,
                    false);
            // -> stack: ... newobj
            return;
        }
    }

    if (opcode == Opcodes.INVOKEVIRTUAL) {
        if ("clone".equals(name) && owner.startsWith("[")) {
            super.visitMethodInsn(opcode, owner, name, signature, itf);

            int i = 0;
            while (i < owner.length()) {
                if (owner.charAt(i) != '[') {
                    break;
                }
                i++;
            }
            if (i > 1) {
                // -> stack: ... newobj
                super.visitTypeInsn(Opcodes.CHECKCAST, owner);
                // -> stack: ... arrayref
                calculateArrayLengthAndDispatch(owner.substring(i), i);
            } else {
                // -> stack: ... newobj
                super.visitInsn(Opcodes.DUP);
                // -> stack: ... newobj newobj
                super.visitTypeInsn(Opcodes.CHECKCAST, owner);
                // -> stack: ... newobj arrayref
                super.visitInsn(Opcodes.ARRAYLENGTH);
                // -> stack: ... newobj length
                super.visitInsn(Opcodes.SWAP);
                // -> stack: ... length newobj
                invokeRecordAllocation(owner.substring(i));
            }
            return;
        }
    }

    if (opcode == Opcodes.INVOKESPECIAL) {
        if (!"clone".equals(name) || !"java/lang/Object".equals(owner)) {
            if ("<init>".equals(name) && outstandingAllocs > 0) {
                // Tricky because superclass initializers mean there can be more calls
                // to <init> than calls to NEW; hence outstandingAllocs.
                --outstandingAllocs;

                // Most of the time (i.e. in bytecode generated by javac) it is the case
                // that following an <init> call the top of the stack has a reference ot
                // the newly-initialized object.  But nothing in the JVM Spec requires
                // this, so we need to play games with the stack to make an explicit
                // extra copy (and then discard it).

                dupStackElementBeforeSignatureArgs(signature);
                super.visitMethodInsn(opcode, owner, name, signature, itf);
                super.visitLdcInsn(-1);
                super.visitInsn(Opcodes.SWAP);
                invokeRecordAllocation(owner);
                super.visitInsn(Opcodes.POP);
                return;
            }
        }
    }

    super.visitMethodInsn(opcode, owner, name, signature, itf);

}

From source file:com.github.rgcjonas.kuemmelgtr.core.Compiler.java

License:Open Source License

private static void compileCommon(TokenSource<RPNToken> source, MethodVisitor method, String variable)
        throws ParsingError {
    method.visitCode();// ww w .  java  2s .c  o m

    // we now can compile our token stream
    int currentStackSize = 0; // we keep track of the current stack size to throw errors if we encounter an invalid instruction
    RPNToken t;
    while ((t = source.nextToken()) != null) {
        if (t instanceof RPNToken.Operand) {
            // we push it onto the stack
            method.visitLdcInsn(((RPNToken.Operand) t).getValue());
            currentStackSize++;
        } else if (t instanceof RPNToken.Operator) {
            RPNToken.Operator op = (RPNToken.Operator) t;

            if (currentStackSize < op.getNumOperands())
                throw new ParsingError(t.getSrcLine(), t.getSrcColumn(), "Missing operand(s)");

            switch (op.getName()) {
            case "_add":
                method.visitInsn(Opcodes.DADD);
                currentStackSize--;
                break;
            case "_mult":
                method.visitInsn(Opcodes.DMUL);
                currentStackSize--;
                break;
            case "_sub":
                method.visitInsn(Opcodes.DSUB);
                currentStackSize--;
                break;
            case "_div":
                method.visitInsn(Opcodes.DDIV);
                currentStackSize--;
                break;
            case "_pow":
                method.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Math", "pow", "(DD)D");
                currentStackSize--;
                break;
            default:
                //HACK: support every function in java/lang/Math. Will be way more performant than any lookup-and-evaluate
                //TODO: implement more functions inline
                if (currentStackSize < 1)
                    throw new ParsingError(t.getSrcLine(), t.getSrcColumn(), "Missing operand");
                try {
                    Method meth = Math.class.getDeclaredMethod(op.getName(), double.class); // just check if it's available and hope it returns a double
                    if (meth.getReturnType() != double.class)
                        throw new NoSuchMethodException(); // we don't want to blow up at runtime, do we?

                    method.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Math", op.getName(), "(D)D");
                } catch (NoSuchMethodException e) {
                    // we do not give up. The method may be available at runtime.
                    method.visitVarInsn(Opcodes.ALOAD, 0);
                    method.visitInsn(Opcodes.DUP_X2); // swap the this pointer and double
                    method.visitInsn(Opcodes.POP);
                    method.visitLdcInsn(op.getName());
                    method.visitLdcInsn((int) op.getSrcLine());
                    method.visitLdcInsn((int) op.getSrcColumn());
                    method.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
                            CompiledClassBase.class.getName().replace('.', '/'), "resolveAndEvaluateFunction",
                            "(DLjava/lang/String;II)D");
                }
            }
        } else if (t instanceof RPNToken.VariableRecall) {
            // maybe, maybe the variable is an argument we can load
            if (variable != null && ((RPNToken.VariableRecall) t).getName().equalsIgnoreCase(variable)) {
                method.visitVarInsn(Opcodes.DLOAD, 1);
            } else {
                // we let our parent class do the hard work
                method.visitVarInsn(Opcodes.ALOAD, 0);
                method.visitLdcInsn(((RPNToken.VariableRecall) t).getName());
                method.visitLdcInsn(t.getSrcLine());
                method.visitLdcInsn(t.getSrcColumn());
                method.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
                        CompiledClassBase.class.getName().replace('.', '/'), "getVariable",
                        "(Ljava/lang/String;II)D");
            }
            currentStackSize++;
        } else if (t instanceof RPNToken.VariableAssignment) {
            // also defer to our parent class
            // we do not give up. The method may be available at runtime.
            method.visitVarInsn(Opcodes.ALOAD, 0);
            method.visitInsn(Opcodes.DUP_X2); // swap the this pointer and double
            method.visitInsn(Opcodes.POP);
            method.visitLdcInsn(((RPNToken.VariableAssignment) t).getVariableName());
            method.visitLdcInsn(t.getSrcLine());
            method.visitLdcInsn(t.getSrcColumn());
            method.visitMethodInsn(Opcodes.INVOKEVIRTUAL, CompiledClassBase.class.getName().replace('.', '/'),
                    "setVariable", "(DLjava/lang/String;II)D");
        } else {
            throw new ParsingError(t.getSrcLine(), t.getSrcColumn(), "Unknown instruction: " + t);
        }
    }

    if (currentStackSize != 1)
        throw new ParsingError(0, 0, "Expected stack to be one value, found " + currentStackSize);

    method.visitInsn(Opcodes.DRETURN);

    method.visitMaxs(0, 0);
    method.visitEnd();
}

From source file:com.github.wreulicke.bean.validation.ASMMethodParameterValidationInjector.java

License:Open Source License

private void inject(MethodNode node, ClassNode clazzNode) {
    if (Modifier.isStatic(node.access) || Modifier.isAbstract(node.access) || Modifier.isAbstract(node.access)
            || "<init>".equals(node.name) || "<clinit>".equals(node.name)) {
        return;/*from  w w  w.j  a  v a2s.c  o m*/
    }

    InsnList list = new InsnList();
    int index = node.localVariables.size();
    list.add(new MethodInsnNode(INVOKESTATIC, "javax/validation/Validation", "buildDefaultValidatorFactory",
            "()Ljavax/validation/ValidatorFactory;", false));
    list.add(new MethodInsnNode(INVOKEINTERFACE, "javax/validation/ValidatorFactory", "getValidator",
            "()Ljavax/validation/Validator;", true));
    list.add(new MethodInsnNode(INVOKEINTERFACE, "javax/validation/Validator", "forExecutables",
            "()Ljavax/validation/executable/ExecutableValidator;", true));

    list.add(new VarInsnNode(Opcodes.ASTORE, index));
    list.add(new VarInsnNode(Opcodes.ALOAD, index));
    list.add(new VarInsnNode(Opcodes.ALOAD, 0));

    list.add(new LdcInsnNode(Type.getType("L" + clazzNode.name + ";")));
    list.add(new LdcInsnNode(node.name));

    @SuppressWarnings("unchecked")
    List<LocalVariableNode> variables = node.localVariables;
    Type[] args = Type.getArgumentTypes(node.desc);

    list.add(new LdcInsnNode(args.length));
    list.add(new TypeInsnNode(Opcodes.ANEWARRAY, "java/lang/Class"));

    for (int i = 0; i < args.length; i++) {
        int paramIndex = 1 + i;
        list.add(new InsnNode(Opcodes.DUP));
        list.add(new LdcInsnNode(i));
        list.add(new LdcInsnNode(Type.getType(variables.get(paramIndex).desc)));
        list.add(new InsnNode(Opcodes.AASTORE));
    }

    list.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Class", "getMethod",
            "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;", false));

    list.add(new LdcInsnNode(args.length));
    list.add(new TypeInsnNode(Opcodes.ANEWARRAY, "java/lang/Object"));
    for (int i = 0; i < args.length; i++) {
        int paramIndex = i + 1;
        list.add(new InsnNode(Opcodes.DUP));
        list.add(new LdcInsnNode(i));
        list.add(new VarInsnNode(Opcodes.ALOAD, paramIndex));
        list.add(new InsnNode(Opcodes.AASTORE));
    }
    list.add(new InsnNode(Opcodes.ICONST_0));
    list.add(new TypeInsnNode(Opcodes.ANEWARRAY, "java/lang/Class"));
    list.add(new MethodInsnNode(INVOKEINTERFACE, "javax/validation/executable/ExecutableValidator",
            "validateParameters",
            "(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;[Ljava/lang/Class;)Ljava/util/Set;",
            true));
    list.add(new MethodInsnNode(INVOKESTATIC, "com/github/wreulicke/bean/validation/Constraints",
            "throwIfNeeded", "(Ljava/util/Set;)V", false));
    node.instructions.insert(list);
}

From source file:com.google.code.jconts.instrument.gen.ComputationClassGenerator.java

License:Apache License

private void generateExecute(ClassVisitor cv) {
    final String name = info.computationClassName;
    final Type outerType = Type.getObjectType(info.owner);

    // Generate execute(Continuation<T> cont);
    MethodVisitor mv = cv.visitMethod(Opcodes.ACC_FINAL | Opcodes.ACC_PUBLIC, COMPUTATION_EXECUTE_NAME,
            COMPUTATION_EXECUTE_DESC, executeSignature(), null);
    mv.visitCode();/*from w  w w. java 2  s  .  co m*/
    Label start = new Label();
    Label end = new Label();
    mv.visitLabel(start);

    // Load outer this
    if (!info.isStatic()) {
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitFieldInsn(Opcodes.GETFIELD, name, "this$0", outerType.getDescriptor());
    }

    // Load state field
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitFieldInsn(Opcodes.GETFIELD, name, "state", stateDesc);

    // state.continuation = continuation
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitFieldInsn(Opcodes.GETFIELD, name, "state", stateDesc);
    mv.visitVarInsn(Opcodes.ALOAD, 1);
    mv.visitFieldInsn(Opcodes.PUTFIELD, info.stateClassName, CONTINUATION_FIELD, CONTINUATION_DESC);

    // Initial state (0)
    mv.visitIntInsn(Opcodes.BIPUSH, 0);
    mv.visitMethodInsn(info.isStatic() ? Opcodes.INVOKESTATIC : Opcodes.INVOKEVIRTUAL, info.owner,
            info.name + "$async",
            Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { info.stateType, Type.INT_TYPE }));

    mv.visitInsn(Opcodes.RETURN);
    mv.visitLabel(end);

    mv.visitLocalVariable("this", 'L' + name + ';', signature, start, end, 0);
    if (!info.isStatic()) {
        mv.visitLocalVariable("this$0", outerType.getDescriptor(), null, start, end, 1);
    }

    SignatureWriter sign = new SignatureWriter();
    contSignature(sign);
    mv.visitLocalVariable("continuation", CONTINUATION_DESC, sign.toString(), start, end, 1 + info.thisOffset);

    mv.visitMaxs(3 + info.thisOffset, 2 + info.thisOffset);
    mv.visitEnd();
}

From source file:com.google.code.jconts.instrument.gen.ContinuationClassGenerator.java

License:Apache License

private void generateExecute(ClassVisitor cv, boolean execute) {
    final String name = info.continuationClassName;
    final Type outerType = Type.getObjectType(info.owner);

    // Generate invoke(T result);
    String signature = null;/*from  ww  w. jav  a  2 s . co m*/
    if (execute) {
        SignatureWriter sign = new SignatureWriter();
        sign.visitParameterType().visitTypeVariable("T");
        sign.visitReturnType().visitBaseType('V'); // void
        signature = sign.toString();
    }
    MethodVisitor mv = cv.visitMethod(Opcodes.ACC_FINAL | Opcodes.ACC_PUBLIC,
            execute ? CONTINUATION_INVOKE_NAME : CONTINUATION_SET_EXCEPTION_NAME,
            execute ? CONTINUATION_INVOKE_DESC : CONTINUATION_SET_EXCEPTION_DESC, signature, null);
    mv.visitCode();
    Label start = new Label();
    Label end = new Label();
    mv.visitLabel(start);

    // Load outer this
    if (!info.isStatic()) {
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitFieldInsn(Opcodes.GETFIELD, name, "this$0", outerType.getDescriptor());
    }

    // state.result = result or state.exception = throwable
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitFieldInsn(Opcodes.GETFIELD, name, "state", stateDesc);
    mv.visitVarInsn(Opcodes.ALOAD, 1);
    mv.visitFieldInsn(Opcodes.PUTFIELD, info.stateClassName, execute ? "result" : "exception",
            execute ? OBJECT_DESC : THROWABLE_DESC);

    // Load state field
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitFieldInsn(Opcodes.GETFIELD, name, "state", stateDesc);

    // Continue from this index or index+1 (for exception)
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitFieldInsn(Opcodes.GETFIELD, name, "index", "I");
    if (!execute) {
        mv.visitInsn(Opcodes.ICONST_1);
        mv.visitInsn(Opcodes.IADD);
    }

    mv.visitMethodInsn(info.isStatic() ? Opcodes.INVOKESTATIC : Opcodes.INVOKEVIRTUAL, info.owner,
            info.name + "$async",
            Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { info.stateType, Type.INT_TYPE }));

    mv.visitInsn(Opcodes.RETURN);
    mv.visitLabel(end);

    mv.visitLocalVariable("this", 'L' + name + ';', signature, start, end, 0);
    if (!info.isStatic()) {
        mv.visitLocalVariable("this$0", outerType.getDescriptor(), null, start, end, 1);
    }
    mv.visitLocalVariable("result", OBJECT_DESC, "TT;", start, end, 1 + info.thisOffset);

    mv.visitMaxs(3 + info.thisOffset + (execute ? 0 : 1), 2 + info.thisOffset);
    mv.visitEnd();
}

From source file:com.google.devtools.build.android.desugar.BytecodeTypeInference.java

License:Open Source License

@Override
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
    if (opcode == Opcodes.INVOKESPECIAL && "<init>".equals(name)) {
        int argumentSize = (Type.getArgumentsAndReturnSizes(desc) >> 2);
        InferredType receiverType = getTypeOfOperandFromTop(argumentSize - 1);
        if (receiverType.isUninitialized()) {
            InferredType realType = InferredType.createNonUninitializedType('L' + owner + ';');
            replaceUninitializedTypeInStack(receiverType, realType);
        }/*from  ww w .jav a  2s  . c  om*/
    }
    switch (opcode) {
    case Opcodes.INVOKESPECIAL:
    case Opcodes.INVOKEVIRTUAL:
    case Opcodes.INVOKESTATIC:
    case Opcodes.INVOKEINTERFACE:
        popDescriptor(desc);
        if (opcode != Opcodes.INVOKESTATIC) {
            pop(); // Pop receiver.
        }
        pushDescriptor(desc);
        break;
    default:
        throw new RuntimeException(String.format("Unhandled opcode %s, owner=%s, name=%s, desc=%s, itf=%s",
                opcode, owner, name, desc, itf));
    }
    super.visitMethodInsn(opcode, owner, name, desc, itf);
}

From source file:com.google.devtools.build.android.desugar.CoreLibrarySupportTest.java

License:Open Source License

@Test
public void testGetCoreInterfaceRewritingTarget_emulatedDefaultMethod() throws Exception {
    CoreLibrarySupport support = new CoreLibrarySupport(new CoreLibraryRewriter(""),
            Thread.currentThread().getContextClassLoader(), ImmutableList.of(),
            ImmutableList.of("java/util/Collection"), ImmutableList.of(), ImmutableList.of());
    assertThat(support.getCoreInterfaceRewritingTarget(Opcodes.INVOKEINTERFACE, "java/util/Collection",
            "removeIf", "(Ljava/util/function/Predicate;)Z", true)).isEqualTo(Collection.class);
    assertThat(support.getCoreInterfaceRewritingTarget(Opcodes.INVOKEVIRTUAL, "java/util/ArrayList", "removeIf",
            "(Ljava/util/function/Predicate;)Z", false)).isEqualTo(Collection.class);
    assertThat(support.getCoreInterfaceRewritingTarget(Opcodes.INVOKEINTERFACE,
            "com/google/HypotheticalListInterface", "removeIf", "(Ljava/util/function/Predicate;)Z", true))
                    .isNull();/*from w w w  . j  av a 2  s .  c o  m*/
}

From source file:com.google.devtools.build.android.desugar.CoreLibrarySupportTest.java

License:Open Source License

@Test
public void testGetCoreInterfaceRewritingTarget_emulatedImplementationMoved() throws Exception {
    CoreLibrarySupport support = new CoreLibrarySupport(new CoreLibraryRewriter(""),
            Thread.currentThread().getContextClassLoader(), ImmutableList.of("java/util/Moved"),
            ImmutableList.of("java/util/Map"),
            ImmutableList.of("java/util/LinkedHashMap#forEach->java/util/Moved"), ImmutableList.of());
    assertThat(support.getCoreInterfaceRewritingTarget(Opcodes.INVOKEINTERFACE, "java/util/Map", "forEach",
            "(Ljava/util/function/BiConsumer;)V", true)).isEqualTo(Map.class);
    assertThat(support.getCoreInterfaceRewritingTarget(Opcodes.INVOKESPECIAL, "java/util/Map", "forEach",
            "(Ljava/util/function/BiConsumer;)V", true)).isEqualTo(Map.class);
    assertThat(support.getCoreInterfaceRewritingTarget(Opcodes.INVOKEVIRTUAL, "java/util/LinkedHashMap",
            "forEach", "(Ljava/util/function/BiConsumer;)V", false)).isEqualTo(Map.class);
    assertThat(support.getCoreInterfaceRewritingTarget(Opcodes.INVOKESPECIAL, "java/util/LinkedHashMap",
            "forEach", "(Ljava/util/function/BiConsumer;)V", false)).isEqualTo(LinkedHashMap.class);
    assertThat(support.getCoreInterfaceRewritingTarget(Opcodes.INVOKESPECIAL, "java/util/HashMap", "forEach",
            "(Ljava/util/function/BiConsumer;)V", false)).isEqualTo(Map.class);
}

From source file:com.google.devtools.build.android.desugar.CoreLibrarySupportTest.java

License:Open Source License

@Test
public void testGetCoreInterfaceRewritingTarget_abstractMethod() throws Exception {
    CoreLibrarySupport support = new CoreLibrarySupport(new CoreLibraryRewriter(""),
            Thread.currentThread().getContextClassLoader(), ImmutableList.of(),
            ImmutableList.of("java/util/Collection"), ImmutableList.of(), ImmutableList.of());
    assertThat(support.getCoreInterfaceRewritingTarget(Opcodes.INVOKEINTERFACE, "java/util/Collection", "size",
            "()I", true)).isNull();
    assertThat(support.getCoreInterfaceRewritingTarget(Opcodes.INVOKEVIRTUAL, "java/util/ArrayList", "size",
            "()I", false)).isNull();
}