emul/src/main/java/java/lang/reflect/Method.java
branchreflection
changeset 262 683719ffcfe7
parent 260 1d03cb35fbda
child 264 ed0c92c81ea4
     1.1 --- a/emul/src/main/java/java/lang/reflect/Method.java	Tue Dec 04 14:31:11 2012 +0100
     1.2 +++ b/emul/src/main/java/java/lang/reflect/Method.java	Tue Dec 04 15:32:18 2012 +0100
     1.3 @@ -26,6 +26,7 @@
     1.4  package java.lang.reflect;
     1.5  
     1.6  import java.lang.annotation.Annotation;
     1.7 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
     1.8  
     1.9  /**
    1.10   * A {@code Method} provides information about, and access to, a single method
    1.11 @@ -50,28 +51,14 @@
    1.12  public final
    1.13      class Method extends AccessibleObject implements GenericDeclaration,
    1.14                                                       Member {
    1.15 -    private Class<?>            clazz;
    1.16 -    private int                 slot;
    1.17 -    // This is guaranteed to be interned by the VM in the 1.4
    1.18 -    // reflection implementation
    1.19 -    private String              name;
    1.20 -    private Class<?>            returnType;
    1.21 -    private Class<?>[]          parameterTypes;
    1.22 -    private Class<?>[]          exceptionTypes;
    1.23 -    private int                 modifiers;
    1.24 -    // Generics and annotations support
    1.25 -    private transient String              signature;
    1.26 -    private byte[]              annotations;
    1.27 -    private byte[]              parameterAnnotations;
    1.28 -    private byte[]              annotationDefault;
    1.29 -    // For sharing of MethodAccessors. This branching structure is
    1.30 -    // currently only two levels deep (i.e., one root Method and
    1.31 -    // potentially many Method objects pointing to it.)
    1.32 -    private Method              root;
    1.33 +    private final Class<?> clazz;
    1.34 +    private final String name;
    1.35 +    private final Object data;
    1.36 +    private int modifiers;
    1.37  
    1.38     // Generics infrastructure
    1.39  
    1.40 -    private String getGenericSignature() {return signature;}
    1.41 +    private String getGenericSignature() {return null;}
    1.42  
    1.43      /**
    1.44       * Package-private constructor used by ReflectAccess to enable
    1.45 @@ -79,28 +66,11 @@
    1.46       * package via sun.reflect.LangReflectAccess.
    1.47       */
    1.48      Method(Class<?> declaringClass,
    1.49 -           String name,
    1.50 -           Class<?>[] parameterTypes,
    1.51 -           Class<?> returnType,
    1.52 -           Class<?>[] checkedExceptions,
    1.53 -           int modifiers,
    1.54 -           int slot,
    1.55 -           String signature,
    1.56 -           byte[] annotations,
    1.57 -           byte[] parameterAnnotations,
    1.58 -           byte[] annotationDefault)
    1.59 +           String name, Object data)
    1.60      {
    1.61          this.clazz = declaringClass;
    1.62          this.name = name;
    1.63 -        this.parameterTypes = parameterTypes;
    1.64 -        this.returnType = returnType;
    1.65 -        this.exceptionTypes = checkedExceptions;
    1.66 -        this.modifiers = modifiers;
    1.67 -        this.slot = slot;
    1.68 -        this.signature = signature;
    1.69 -        this.annotations = annotations;
    1.70 -        this.parameterAnnotations = parameterAnnotations;
    1.71 -        this.annotationDefault = annotationDefault;
    1.72 +        this.data = data;
    1.73      }
    1.74  
    1.75      /**
    1.76 @@ -109,18 +79,7 @@
    1.77       * "root" field points to this Method.
    1.78       */
    1.79      Method copy() {
    1.80 -        // This routine enables sharing of MethodAccessor objects
    1.81 -        // among Method objects which refer to the same underlying
    1.82 -        // method in the VM. (All of this contortion is only necessary
    1.83 -        // because of the "accessibility" bit in AccessibleObject,
    1.84 -        // which implicitly requires that new java.lang.reflect
    1.85 -        // objects be fabricated for each reflective call on Class
    1.86 -        // objects.)
    1.87 -        Method res = new Method(clazz, name, parameterTypes, returnType,
    1.88 -                                exceptionTypes, modifiers, slot, signature,
    1.89 -                                annotations, parameterAnnotations, annotationDefault);
    1.90 -        res.root = this;
    1.91 -        return res;
    1.92 +        return this;
    1.93      }
    1.94  
    1.95      /**
    1.96 @@ -176,7 +135,7 @@
    1.97       * @return the return type for the method this object represents
    1.98       */
    1.99      public Class<?> getReturnType() {
   1.100 -        return returnType;
   1.101 +        throw new UnsupportedOperationException();
   1.102      }
   1.103  
   1.104      /**
   1.105 @@ -218,7 +177,8 @@
   1.106       * represents
   1.107       */
   1.108      public Class<?>[] getParameterTypes() {
   1.109 -        return (Class<?>[]) parameterTypes.clone();
   1.110 +        throw new UnsupportedOperationException();
   1.111 +        //return (Class<?>[]) parameterTypes.clone();
   1.112      }
   1.113  
   1.114      /**
   1.115 @@ -264,7 +224,8 @@
   1.116       * method this object represents
   1.117       */
   1.118      public Class<?>[] getExceptionTypes() {
   1.119 -        return (Class<?>[]) exceptionTypes.clone();
   1.120 +        throw new UnsupportedOperationException();
   1.121 +        //return (Class<?>[]) exceptionTypes.clone();
   1.122      }
   1.123  
   1.124      /**
   1.125 @@ -302,21 +263,7 @@
   1.126      public boolean equals(Object obj) {
   1.127          if (obj != null && obj instanceof Method) {
   1.128              Method other = (Method)obj;
   1.129 -            if ((getDeclaringClass() == other.getDeclaringClass())
   1.130 -                && (getName() == other.getName())) {
   1.131 -                if (!returnType.equals(other.getReturnType()))
   1.132 -                    return false;
   1.133 -                /* Avoid unnecessary cloning */
   1.134 -                Class<?>[] params1 = parameterTypes;
   1.135 -                Class<?>[] params2 = other.parameterTypes;
   1.136 -                if (params1.length == params2.length) {
   1.137 -                    for (int i = 0; i < params1.length; i++) {
   1.138 -                        if (params1[i] != params2[i])
   1.139 -                            return false;
   1.140 -                    }
   1.141 -                    return true;
   1.142 -                }
   1.143 -            }
   1.144 +            return data == other.data;
   1.145          }
   1.146          return false;
   1.147      }
   1.148 @@ -362,6 +309,7 @@
   1.149              sb.append(Field.getTypeName(getReturnType())).append(' ');
   1.150              sb.append(Field.getTypeName(getDeclaringClass())).append('.');
   1.151              sb.append(getName()).append('(');
   1.152 +            /*
   1.153              Class<?>[] params = parameterTypes; // avoid clone
   1.154              for (int j = 0; j < params.length; j++) {
   1.155                  sb.append(Field.getTypeName(params[j]));
   1.156 @@ -378,6 +326,7 @@
   1.157                          sb.append(',');
   1.158                  }
   1.159              }
   1.160 +            */
   1.161              return sb.toString();
   1.162          } catch (Exception e) {
   1.163              return "<" + e + ">";
   1.164 @@ -537,6 +486,10 @@
   1.165       * @exception ExceptionInInitializerError if the initialization
   1.166       * provoked by this method fails.
   1.167       */
   1.168 +    @JavaScriptBody(args = { "method", "self", "args" }, body =
   1.169 +          "if (args.length > 0) throw 'unsupported now';"
   1.170 +        + "return method.fld_data(self);"
   1.171 +    )
   1.172      public Object invoke(Object obj, Object... args)
   1.173          throws IllegalAccessException, IllegalArgumentException,
   1.174             InvocationTargetException
   1.175 @@ -614,8 +567,6 @@
   1.176       * @since  1.5
   1.177       */
   1.178      public Object getDefaultValue() {
   1.179 -        if  (annotationDefault == null)
   1.180 -            return null;
   1.181          throw new UnsupportedOperationException();
   1.182      }
   1.183  
   1.184 @@ -636,10 +587,36 @@
   1.185       * @since 1.5
   1.186       */
   1.187      public Annotation[][] getParameterAnnotations() {
   1.188 -        int numParameters = parameterTypes.length;
   1.189 -        if (parameterAnnotations == null)
   1.190 -            return new Annotation[numParameters][0];
   1.191 -
   1.192          throw new UnsupportedOperationException();
   1.193      }
   1.194 +    
   1.195 +    //
   1.196 +    // bck2brwsr implementation
   1.197 +    //
   1.198 +
   1.199 +    @JavaScriptBody(args = { "clazz", "name", "params" },
   1.200 +        body = "if (params.length > 0) return null;\n"
   1.201 +        + "var c = clazz.cnstr.prototype;"
   1.202 +        + "var prefix = name + '__';\n"
   1.203 +        + "for (m in c) {\n"
   1.204 +        + "  if (m.indexOf(prefix) === 0) {"
   1.205 +        + "     return c[m];\n"
   1.206 +        + "  }"
   1.207 +        + "}\n"
   1.208 +        + "return null;"
   1.209 +    )
   1.210 +    private static native Object findMethodData(
   1.211 +        Class<?> clazz, String name, Class<?>... parameterTypes
   1.212 +    );
   1.213 +    
   1.214 +    // XXX should not be public
   1.215 +    public static Method findMethod(
   1.216 +        Class<?> clazz, String name, Class<?>... parameterTypes
   1.217 +    ) {
   1.218 +        Object data = findMethodData(clazz, name, parameterTypes);
   1.219 +        if (data == null) {
   1.220 +            return null;
   1.221 +        }
   1.222 +        return new Method(clazz, name, data);
   1.223 +    }
   1.224  }