package me.august.lumen.compile.analyze.method; import me.august.lumen.compile.codegen.BuildContext; import me.august.lumen.compile.codegen.MethodCodeGen; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; public abstract class MethodReference implements MethodCodeGen { private String owner; private String name; private Type descriptor; private boolean itf; private boolean shouldPop; public MethodReference(String owner, String name, Type descriptor, boolean itf, boolean shouldPop) { this.owner = owner; this.name = name; this.descriptor = descriptor; this.itf = itf; this.shouldPop = shouldPop; } protected abstract int getOpcode(); public MethodReference(String owner, String name, Type descriptor) { this(owner, name, descriptor, false, false); } @Override public void generate(MethodVisitor visitor, BuildContext context) { visitor.visitMethodInsn(getOpcode(), owner, name, descriptor.getDescriptor(), itf); if (shouldPop) { visitor.visitInsn(Opcodes.POP); } } public Type getReturnType() { return descriptor.getReturnType(); } public static class Instance extends MethodReference { public Instance(String owner, String name, Type descriptor) { super(owner, name, descriptor); } public Instance(String owner, String name, Type descriptor, boolean itf, boolean shouldPop) { super(owner, name, descriptor, itf, shouldPop); } @Override protected int getOpcode() { return Opcodes.INVOKEVIRTUAL; } } public static class Static extends MethodReference { public Static(String owner, String name, Type descriptor, boolean itf, boolean shouldPop) { super(owner, name, descriptor, itf, shouldPop); } public Static(String owner, String name, Type descriptor) { super(owner, name, descriptor); } @Override protected int getOpcode() { return Opcodes.INVOKESTATIC; } } }