private static int compareHandle(Handle h1, Handle h2) { int d = h1.getTag() - h2.getTag(); if (d == 0) { d = h1.getOwner().compareTo(h2.getOwner()); if (d == 0) { d = h1.getName().compareTo(h2.getName()); if (d == 0) { d = h1.getDesc().compareTo(h2.getDesc()); } } } return d; }
void addConstant(final Object constant) { if (constant instanceof Type) { addType((Type) constant); } else if (constant instanceof Handle) { Handle handle = (Handle) constant; addInternalType(handle.getOwner()); addMethodTypes(handle.getDesc()); } }
void addConstant(final Object cst) { if (cst instanceof Type) { addType((Type) cst); } else if (cst instanceof Handle) { Handle h = (Handle) cst; addInternalName(h.getOwner()); addMethodDesc(h.getDesc()); } }
@Override public void visitLdcInsn(Object cst) { if (cst instanceof Handle) { Handle handle = (Handle) cst; cst = new Handle( handle.getTag(), handle.getOwner(), handle.getName(), getMethodDescriptor(handle.getDesc())); } super.visitLdcInsn(cst); }
private String getLambdaAccessMethodDesc(Handle implMethod) { if (implMethod.getTag() == H_INVOKESTATIC) { // static method call -> keep as-is return implMethod.getDesc(); } else if (implMethod.getTag() == H_NEWINVOKESPECIAL) { // constructor call -> change to a a factory method return Types.changeReturnType( Type.getObjectType(implMethod.getOwner()), implMethod.getDesc()); } else { // instance method call -> change to a static method return Types.prependArgumentType(Type.getObjectType(className), implMethod.getDesc()); } }
Handle getLambdaAccessMethod(Handle implMethod) { if (!implMethod.getOwner().equals(className)) { return implMethod; } if (Flags.hasFlag(classAccess, ACC_INTERFACE)) { // the method will be relocated to a companion class return implMethod; } // TODO: do not generate an access method if the impl method is not private (probably not // implementable with a single pass) String name = "access$lambda$" + lambdaAccessToImplMethods.size(); String desc = getLambdaAccessMethodDesc(implMethod); Handle accessMethod = new Handle(H_INVOKESTATIC, className, name, desc); lambdaAccessToImplMethods.put(accessMethod, implMethod); return accessMethod; }
@Override public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) { if (bsm.getOwner().equals(LambdaNaming.LAMBDA_METAFACTORY)) { backportLambda(name, Type.getType(desc), bsm, bsmArgs); } else { super.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs); } }