@Override public void visitEnd() { for (Map.Entry<Handle, Handle> entry : lambdaAccessToImplMethods.entrySet()) { Handle accessMethod = entry.getKey(); Handle implMethod = entry.getValue(); Bytecode.generateDelegateMethod(cv, ACC_STATIC | ACC_SYNTHETIC, accessMethod, implMethod); } super.visitEnd(); }
/** * Visit every class/interface this proxy should implement, and generate the appropriate bytecode * for delegation if available. * * @param clazz an class for which to generate bytecode */ private void visitClass(final Class clazz) { Method[] methods = clazz.getDeclaredMethods(); for (Method method : methods) { Class<?>[] exceptionTypes = method.getExceptionTypes(); String[] exceptions = new String[exceptionTypes.length]; for (int i = 0; i < exceptions.length; i++) { exceptions[i] = BytecodeHelper.getClassInternalName(exceptionTypes[i]); } // for each method defined in the class, generate the appropriate delegation bytecode visitMethod( method.getModifiers(), method.getName(), BytecodeHelper.getMethodDescriptor(method.getReturnType(), method.getParameterTypes()), null, exceptions); } Constructor[] constructors = clazz.getDeclaredConstructors(); for (Constructor method : constructors) { Class<?>[] exceptionTypes = method.getExceptionTypes(); String[] exceptions = new String[exceptionTypes.length]; for (int i = 0; i < exceptions.length; i++) { exceptions[i] = BytecodeHelper.getClassInternalName(exceptionTypes[i]); } // for each method defined in the class, generate the appropriate delegation bytecode visitMethod( method.getModifiers(), "<init>", BytecodeHelper.getMethodDescriptor(Void.TYPE, method.getParameterTypes()), null, exceptions); } for (Class intf : clazz.getInterfaces()) { visitClass(intf); } Class superclass = clazz.getSuperclass(); if (superclass != null) visitClass(superclass); // Ultimately, methods can be available in the closure map which are not defined by the // superclass // nor the interfaces for (Map.Entry<String, Boolean> entry : delegatedClosures.entrySet()) { Boolean visited = entry.getValue(); if (!visited) { String name = entry.getKey(); if (!"*".equals(name)) { // generate a new method visitMethod(ACC_PUBLIC, name, "([Ljava/lang/Object;)Ljava/lang/Object;", null, null); } } } }