// Copyright © 2013-2014 Esko Luontola <www.orfjackal.net>
// This software is released under the Apache License 2.0.
// The license text is at http://www.apache.org/licenses/LICENSE-2.0

package net.orfjackal.retrolambda.interfaces;

import org.objectweb.asm.*;

import static org.objectweb.asm.Opcodes.ASM5;

public class UpdateRelocatedMethodInvocations extends ClassVisitor {

    private final MethodRelocations methodRelocations;

    public UpdateRelocatedMethodInvocations(ClassVisitor next, MethodRelocations methodRelocations) {
        super(ASM5, next);
        this.methodRelocations = methodRelocations;
    }

    @Override
    public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
        return new UpdateMethodCalls(super.visitMethod(access, name, desc, signature, exceptions));
    }

    private class UpdateMethodCalls extends MethodVisitor {

        public UpdateMethodCalls(MethodVisitor next) {
            super(Opcodes.ASM5, next);
        }

        @Override
        public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
            MethodRef ref = methodRelocations.getMethodCallTarget(new MethodRef(owner, name, desc));
            super.visitMethodInsn(opcode, ref.owner, ref.name, ref.desc, itf);
        }
    }
}

@@ -1168,84 +1168,627 @@
 Ref 
-ref = methodRelocations.getMethodCallTarget(new MethodRef(owner, name, desc)
+method = new MethodRef(owner, name, desc);%0A%0A            // change Interface.super.defaultMethod() calls to static calls on the companion class%0A            // TODO: move this inside getMethodCallTarget (also opcode, so must first change MethodRef to Handle)%0A            if (opcode == Opcodes.INVOKESPECIAL) %7B%0A                MethodRef impl = methodRelocations.getMethodDefaultImplementation(method);%0A                if (impl != null) %7B%0A                    opcode = Opcodes.INVOKESTATIC;%0A                    method = impl;%0A                %7D%0A            %7D%0A%0A            method = methodRelocations.getMethodCallTarget(method
 );%0A 
@@ -1832,19 +1832,22 @@
 de, 
-ref
+method
 .owner, 
 ref.
@@ -1846,21 +1846,27 @@
 er, 
-ref
+method
 .name, 
-ref
+method
 .des

Change Interface.super.defaultMethod() calls to static calls on the companion class