public void generate(ClassEmitter ce, Context context, List methods) {
    for (Iterator it = methods.iterator(); it.hasNext(); ) {
      MethodInfo method = (MethodInfo) it.next();
      Signature impl = context.getImplSignature(method);
      ce.declare_field(Constants.PRIVATE_FINAL_STATIC, impl.getName(), METHOD, null);

      CodeEmitter e = context.beginMethod(ce, method);
      Block handler = e.begin_block();
      context.emitCallback(e, context.getIndex(method));
      e.load_this();
      e.getfield(impl.getName());
      e.create_arg_array();
      e.invoke_interface(INVOCATION_HANDLER, INVOKE);
      e.unbox(method.getSignature().getReturnType());
      e.return_value();
      handler.end();
      EmitUtils.wrap_undeclared_throwable(
          e, handler, method.getExceptionTypes(), UNDECLARED_THROWABLE_EXCEPTION);
      e.end_method();
    }
  }
Exemple #2
0
    public void generateClass(ClassVisitor v) {
      ClassEmitter ce = new ClassEmitter(v);

      Method newInstance = ReflectUtils.findNewInstance(keyInterface);
      if (!newInstance.getReturnType().equals(Object.class)) {
        throw new IllegalArgumentException("newInstance method must return Object");
      }

      Type[] parameterTypes = TypeUtils.getTypes(newInstance.getParameterTypes());
      ce.begin_class(
          Constants.V1_2,
          Constants.ACC_PUBLIC,
          getClassName(),
          KEY_FACTORY,
          new Type[] {Type.getType(keyInterface)},
          Constants.SOURCE_FILE);
      EmitUtils.null_constructor(ce);
      EmitUtils.factory_method(ce, ReflectUtils.getSignature(newInstance));

      int seed = 0;
      CodeEmitter e =
          ce.begin_method(Constants.ACC_PUBLIC, TypeUtils.parseConstructor(parameterTypes), null);
      e.load_this();
      e.super_invoke_constructor();
      e.load_this();
      for (int i = 0; i < parameterTypes.length; i++) {
        seed += parameterTypes[i].hashCode();
        ce.declare_field(
            Constants.ACC_PRIVATE | Constants.ACC_FINAL, getFieldName(i), parameterTypes[i], null);
        e.dup();
        e.load_arg(i);
        e.putfield(getFieldName(i));
      }
      e.return_value();
      e.end_method();

      // hash code
      e = ce.begin_method(Constants.ACC_PUBLIC, HASH_CODE, null);
      int hc = (constant != 0) ? constant : PRIMES[(int) (Math.abs(seed) % PRIMES.length)];
      int hm = (multiplier != 0) ? multiplier : PRIMES[(int) (Math.abs(seed * 13) % PRIMES.length)];
      e.push(hc);
      for (int i = 0; i < parameterTypes.length; i++) {
        e.load_this();
        e.getfield(getFieldName(i));
        EmitUtils.hash_code(e, parameterTypes[i], hm, customizer);
      }
      e.return_value();
      e.end_method();

      // equals
      e = ce.begin_method(Constants.ACC_PUBLIC, EQUALS, null);
      Label fail = e.make_label();
      e.load_arg(0);
      e.instance_of_this();
      e.if_jump(e.EQ, fail);
      for (int i = 0; i < parameterTypes.length; i++) {
        e.load_this();
        e.getfield(getFieldName(i));
        e.load_arg(0);
        e.checkcast_this();
        e.getfield(getFieldName(i));
        EmitUtils.not_equals(e, parameterTypes[i], fail, customizer);
      }
      e.push(1);
      e.return_value();
      e.mark(fail);
      e.push(0);
      e.return_value();
      e.end_method();

      // toString
      e = ce.begin_method(Constants.ACC_PUBLIC, TO_STRING, null);
      e.new_instance(Constants.TYPE_STRING_BUFFER);
      e.dup();
      e.invoke_constructor(Constants.TYPE_STRING_BUFFER);
      for (int i = 0; i < parameterTypes.length; i++) {
        if (i > 0) {
          e.push(", ");
          e.invoke_virtual(Constants.TYPE_STRING_BUFFER, APPEND_STRING);
        }
        e.load_this();
        e.getfield(getFieldName(i));
        EmitUtils.append_string(e, parameterTypes[i], EmitUtils.DEFAULT_DELIMITERS, customizer);
      }
      e.invoke_virtual(Constants.TYPE_STRING_BUFFER, TO_STRING);
      e.return_value();
      e.end_method();

      ce.end_class();
    }
    public void generateClass(ClassVisitor v) throws NoSuchMethodException {
      Method proxy = ReflectUtils.findInterfaceMethod(iface);
      final Method method = targetClass.getMethod(methodName, proxy.getParameterTypes());
      if (!proxy.getReturnType().isAssignableFrom(method.getReturnType())) {
        throw new IllegalArgumentException("incompatible return types");
      }

      MethodInfo methodInfo = ReflectUtils.getMethodInfo(method);

      boolean isStatic = TypeUtils.isStatic(methodInfo.getModifiers());
      if ((target == null) ^ isStatic) {
        throw new IllegalArgumentException(
            "Static method " + (isStatic ? "not " : "") + "expected");
      }

      ClassEmitter ce = new ClassEmitter(v);
      CodeEmitter e;
      ce.begin_class(
          Constants.V1_2,
          Constants.ACC_PUBLIC,
          getClassName(),
          METHOD_DELEGATE,
          new Type[] {Type.getType(iface)},
          Constants.SOURCE_FILE);
      ce.declare_field(Constants.PRIVATE_FINAL_STATIC, "eqMethod", Constants.TYPE_STRING, null);
      EmitUtils.null_constructor(ce);

      // generate proxied method
      MethodInfo proxied = ReflectUtils.getMethodInfo(iface.getDeclaredMethods()[0]);
      int modifiers = Constants.ACC_PUBLIC;
      if ((proxied.getModifiers() & Constants.ACC_VARARGS) == Constants.ACC_VARARGS) {
        modifiers |= Constants.ACC_VARARGS;
      }
      e = EmitUtils.begin_method(ce, proxied, modifiers);
      e.load_this();
      e.super_getfield("target", Constants.TYPE_OBJECT);
      e.checkcast(methodInfo.getClassInfo().getType());
      e.load_args();
      e.invoke(methodInfo);
      e.return_value();
      e.end_method();

      // newInstance
      e = ce.begin_method(Constants.ACC_PUBLIC, NEW_INSTANCE, null);
      e.new_instance_this();
      e.dup();
      e.dup2();
      e.invoke_constructor_this();
      e.getfield("eqMethod");
      e.super_putfield("eqMethod", Constants.TYPE_STRING);
      e.load_arg(0);
      e.super_putfield("target", Constants.TYPE_OBJECT);
      e.return_value();
      e.end_method();

      // static initializer
      e = ce.begin_static();
      e.push(methodInfo.getSignature().toString());
      e.putfield("eqMethod");
      e.return_value();
      e.end_method();

      ce.end_class();
    }