예제 #1
0
    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();
    }
예제 #2
0
    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();
    }