public void addActionMethod(MetaMethod method) throws Exception { Type actionImplType = Type.getType(ClosureBackedAction.class); Type closureType = Type.getType(Closure.class); String methodDescriptor = Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {closureType}); // GENERATE public void <method>(Closure v) { <method>(new ClosureBackedAction(v)); } MethodVisitor methodVisitor = visitor.visitMethod( Opcodes.ACC_PUBLIC, method.getName(), methodDescriptor, null, new String[0]); methodVisitor.visitCode(); // GENERATE <method>(new ClosureBackedAction(v)); methodVisitor.visitVarInsn(Opcodes.ALOAD, 0); // GENERATE new ClosureBackedAction(v); methodVisitor.visitTypeInsn(Opcodes.NEW, actionImplType.getInternalName()); methodVisitor.visitInsn(Opcodes.DUP); methodVisitor.visitVarInsn(Opcodes.ALOAD, 1); String constuctorDescriptor = Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {closureType}); methodVisitor.visitMethodInsn( Opcodes.INVOKESPECIAL, actionImplType.getInternalName(), "<init>", constuctorDescriptor); methodDescriptor = Type.getMethodDescriptor( Type.getType(method.getReturnType()), new Type[] {Type.getType(method.getParameterTypes()[0].getTheClass())}); methodVisitor.visitMethodInsn( Opcodes.INVOKEVIRTUAL, generatedType.getInternalName(), method.getName(), methodDescriptor); methodVisitor.visitInsn(Opcodes.RETURN); methodVisitor.visitMaxs(0, 0); methodVisitor.visitEnd(); }
private void addConventionGetter(String getterName, String flagName, MetaBeanProperty property) throws Exception { // GENERATE public <type> <getter>() { return // (<type>)getConventionMapping().getConventionValue(super.<getter>(), '<prop>', <prop>Set); } MetaMethod getter = property.getGetter(); Type returnType = Type.getType(getter.getReturnType()); String methodDescriptor = Type.getMethodDescriptor(returnType, new Type[0]); MethodVisitor methodVisitor = visitor.visitMethod( Opcodes.ACC_PUBLIC, getterName, methodDescriptor, null, new String[0]); methodVisitor.visitCode(); methodVisitor.visitVarInsn(Opcodes.ALOAD, 0); methodVisitor.visitMethodInsn( Opcodes.INVOKEINTERFACE, conventionAwareType.getInternalName(), "getConventionMapping", Type.getMethodDescriptor(conventionMappingType, new Type[0])); methodVisitor.visitVarInsn(Opcodes.ALOAD, 0); methodVisitor.visitMethodInsn( Opcodes.INVOKESPECIAL, superclassType.getInternalName(), getterName, methodDescriptor); Type boxedType = null; if (getter.getReturnType().isPrimitive()) { // Box value boxedType = Type.getType(JavaReflectionUtil.getWrapperTypeForPrimitiveType(getter.getReturnType())); String valueOfMethodDescriptor = Type.getMethodDescriptor(boxedType, new Type[] {returnType}); methodVisitor.visitMethodInsn( Opcodes.INVOKESTATIC, boxedType.getInternalName(), "valueOf", valueOfMethodDescriptor); } methodVisitor.visitLdcInsn(property.getName()); methodVisitor.visitVarInsn(Opcodes.ALOAD, 0); methodVisitor.visitFieldInsn( Opcodes.GETFIELD, generatedType.getInternalName(), flagName, Type.BOOLEAN_TYPE.getDescriptor()); String getConventionValueDesc = Type.getMethodDescriptor( ConventionMapping.class.getMethod( "getConventionValue", Object.class, String.class, Boolean.TYPE)); methodVisitor.visitMethodInsn( Opcodes.INVOKEINTERFACE, conventionMappingType.getInternalName(), "getConventionValue", getConventionValueDesc); if (getter.getReturnType().isPrimitive()) { // Unbox value methodVisitor.visitTypeInsn(Opcodes.CHECKCAST, boxedType.getInternalName()); String valueMethodDescriptor = Type.getMethodDescriptor(returnType, new Type[0]); methodVisitor.visitMethodInsn( Opcodes.INVOKEVIRTUAL, boxedType.getInternalName(), getter.getReturnType().getName() + "Value", valueMethodDescriptor); } else { // Cast to return type methodVisitor.visitTypeInsn( Opcodes.CHECKCAST, getter.getReturnType().isArray() ? "[" + returnType.getElementType().getDescriptor() : returnType.getInternalName()); } methodVisitor.visitInsn(returnType.getOpcode(Opcodes.IRETURN)); methodVisitor.visitMaxs(0, 0); methodVisitor.visitEnd(); }