emul/mini/src/main/java/java/lang/reflect/Method.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Sat, 26 Jan 2013 08:47:05 +0100
changeset 592 5e13b1ac2886
parent 555 cde0c2d7794e
permissions -rw-r--r--
In order to support fields of the same name in subclasses we are now prefixing them with name of the class that defines them. To provide convenient way to access them from generated bytecode and also directly from JavaScript, there is a getter/setter function for each field. It starts with _ followed by the field name. If called with a parameter, it sets the field, with a parameter it just returns it.
     1 /*
     2  * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  */
    25 
    26 package java.lang.reflect;
    27 
    28 import java.lang.annotation.Annotation;
    29 import java.util.Enumeration;
    30 import org.apidesign.bck2brwsr.core.JavaScriptBody;
    31 import org.apidesign.bck2brwsr.emul.reflect.AnnotationImpl;
    32 import org.apidesign.bck2brwsr.emul.reflect.MethodImpl;
    33 
    34 /**
    35  * A {@code Method} provides information about, and access to, a single method
    36  * on a class or interface.  The reflected method may be a class method
    37  * or an instance method (including an abstract method).
    38  *
    39  * <p>A {@code Method} permits widening conversions to occur when matching the
    40  * actual parameters to invoke with the underlying method's formal
    41  * parameters, but it throws an {@code IllegalArgumentException} if a
    42  * narrowing conversion would occur.
    43  *
    44  * @see Member
    45  * @see java.lang.Class
    46  * @see java.lang.Class#getMethods()
    47  * @see java.lang.Class#getMethod(String, Class[])
    48  * @see java.lang.Class#getDeclaredMethods()
    49  * @see java.lang.Class#getDeclaredMethod(String, Class[])
    50  *
    51  * @author Kenneth Russell
    52  * @author Nakul Saraiya
    53  */
    54 public final
    55     class Method extends AccessibleObject implements GenericDeclaration,
    56                                                      Member {
    57     private final Class<?> clazz;
    58     private final String name;
    59     private final Object data;
    60     private final String sig;
    61 
    62    // Generics infrastructure
    63 
    64     private String getGenericSignature() {return null;}
    65 
    66     /**
    67      * Package-private constructor used by ReflectAccess to enable
    68      * instantiation of these objects in Java code from the java.lang
    69      * package via sun.reflect.LangReflectAccess.
    70      */
    71     Method(Class<?> declaringClass, String name, Object data, String sig)
    72     {
    73         this.clazz = declaringClass;
    74         this.name = name;
    75         this.data = data;
    76         this.sig = sig;
    77     }
    78 
    79     /**
    80      * Package-private routine (exposed to java.lang.Class via
    81      * ReflectAccess) which returns a copy of this Method. The copy's
    82      * "root" field points to this Method.
    83      */
    84     Method copy() {
    85         return this;
    86     }
    87 
    88     /**
    89      * Returns the {@code Class} object representing the class or interface
    90      * that declares the method represented by this {@code Method} object.
    91      */
    92     public Class<?> getDeclaringClass() {
    93         return clazz;
    94     }
    95 
    96     /**
    97      * Returns the name of the method represented by this {@code Method}
    98      * object, as a {@code String}.
    99      */
   100     public String getName() {
   101         return name;
   102     }
   103 
   104     /**
   105      * Returns the Java language modifiers for the method represented
   106      * by this {@code Method} object, as an integer. The {@code Modifier} class should
   107      * be used to decode the modifiers.
   108      *
   109      * @see Modifier
   110      */
   111     public int getModifiers() {
   112         return getAccess(data);
   113     }
   114     
   115     @JavaScriptBody(args = "self", body = "return self.access;")
   116     private static native int getAccess(Object self);
   117     
   118     /**
   119      * Returns an array of {@code TypeVariable} objects that represent the
   120      * type variables declared by the generic declaration represented by this
   121      * {@code GenericDeclaration} object, in declaration order.  Returns an
   122      * array of length 0 if the underlying generic declaration declares no type
   123      * variables.
   124      *
   125      * @return an array of {@code TypeVariable} objects that represent
   126      *     the type variables declared by this generic declaration
   127      * @throws GenericSignatureFormatError if the generic
   128      *     signature of this generic declaration does not conform to
   129      *     the format specified in
   130      *     <cite>The Java&trade; Virtual Machine Specification</cite>
   131      * @since 1.5
   132      */
   133     public TypeVariable<Method>[] getTypeParameters() {
   134         throw new UnsupportedOperationException();
   135     }
   136 
   137     /**
   138      * Returns a {@code Class} object that represents the formal return type
   139      * of the method represented by this {@code Method} object.
   140      *
   141      * @return the return type for the method this object represents
   142      */
   143     public Class<?> getReturnType() {
   144         return MethodImpl.signatureParser(sig).nextElement();
   145     }
   146 
   147     /**
   148      * Returns a {@code Type} object that represents the formal return
   149      * type of the method represented by this {@code Method} object.
   150      *
   151      * <p>If the return type is a parameterized type,
   152      * the {@code Type} object returned must accurately reflect
   153      * the actual type parameters used in the source code.
   154      *
   155      * <p>If the return type is a type variable or a parameterized type, it
   156      * is created. Otherwise, it is resolved.
   157      *
   158      * @return  a {@code Type} object that represents the formal return
   159      *     type of the underlying  method
   160      * @throws GenericSignatureFormatError
   161      *     if the generic method signature does not conform to the format
   162      *     specified in
   163      *     <cite>The Java&trade; Virtual Machine Specification</cite>
   164      * @throws TypeNotPresentException if the underlying method's
   165      *     return type refers to a non-existent type declaration
   166      * @throws MalformedParameterizedTypeException if the
   167      *     underlying method's return typed refers to a parameterized
   168      *     type that cannot be instantiated for any reason
   169      * @since 1.5
   170      */
   171     public Type getGenericReturnType() {
   172         throw new UnsupportedOperationException();
   173     }
   174 
   175 
   176     /**
   177      * Returns an array of {@code Class} objects that represent the formal
   178      * parameter types, in declaration order, of the method
   179      * represented by this {@code Method} object.  Returns an array of length
   180      * 0 if the underlying method takes no parameters.
   181      *
   182      * @return the parameter types for the method this object
   183      * represents
   184      */
   185     public Class<?>[] getParameterTypes() {
   186         Class[] arr = new Class[MethodImpl.signatureElements(sig) - 1];
   187         Enumeration<Class> en = MethodImpl.signatureParser(sig);
   188         en.nextElement(); // return type
   189         for (int i = 0; i < arr.length; i++) {
   190             arr[i] = en.nextElement();
   191         }
   192         return arr;
   193     }
   194 
   195     /**
   196      * Returns an array of {@code Type} objects that represent the formal
   197      * parameter types, in declaration order, of the method represented by
   198      * this {@code Method} object. Returns an array of length 0 if the
   199      * underlying method takes no parameters.
   200      *
   201      * <p>If a formal parameter type is a parameterized type,
   202      * the {@code Type} object returned for it must accurately reflect
   203      * the actual type parameters used in the source code.
   204      *
   205      * <p>If a formal parameter type is a type variable or a parameterized
   206      * type, it is created. Otherwise, it is resolved.
   207      *
   208      * @return an array of Types that represent the formal
   209      *     parameter types of the underlying method, in declaration order
   210      * @throws GenericSignatureFormatError
   211      *     if the generic method signature does not conform to the format
   212      *     specified in
   213      *     <cite>The Java&trade; Virtual Machine Specification</cite>
   214      * @throws TypeNotPresentException if any of the parameter
   215      *     types of the underlying method refers to a non-existent type
   216      *     declaration
   217      * @throws MalformedParameterizedTypeException if any of
   218      *     the underlying method's parameter types refer to a parameterized
   219      *     type that cannot be instantiated for any reason
   220      * @since 1.5
   221      */
   222     public Type[] getGenericParameterTypes() {
   223         throw new UnsupportedOperationException();
   224     }
   225 
   226 
   227     /**
   228      * Returns an array of {@code Class} objects that represent
   229      * the types of the exceptions declared to be thrown
   230      * by the underlying method
   231      * represented by this {@code Method} object.  Returns an array of length
   232      * 0 if the method declares no exceptions in its {@code throws} clause.
   233      *
   234      * @return the exception types declared as being thrown by the
   235      * method this object represents
   236      */
   237     public Class<?>[] getExceptionTypes() {
   238         throw new UnsupportedOperationException();
   239         //return (Class<?>[]) exceptionTypes.clone();
   240     }
   241 
   242     /**
   243      * Returns an array of {@code Type} objects that represent the
   244      * exceptions declared to be thrown by this {@code Method} object.
   245      * Returns an array of length 0 if the underlying method declares
   246      * no exceptions in its {@code throws} clause.
   247      *
   248      * <p>If an exception type is a type variable or a parameterized
   249      * type, it is created. Otherwise, it is resolved.
   250      *
   251      * @return an array of Types that represent the exception types
   252      *     thrown by the underlying method
   253      * @throws GenericSignatureFormatError
   254      *     if the generic method signature does not conform to the format
   255      *     specified in
   256      *     <cite>The Java&trade; Virtual Machine Specification</cite>
   257      * @throws TypeNotPresentException if the underlying method's
   258      *     {@code throws} clause refers to a non-existent type declaration
   259      * @throws MalformedParameterizedTypeException if
   260      *     the underlying method's {@code throws} clause refers to a
   261      *     parameterized type that cannot be instantiated for any reason
   262      * @since 1.5
   263      */
   264       public Type[] getGenericExceptionTypes() {
   265         throw new UnsupportedOperationException();
   266       }
   267 
   268     /**
   269      * Compares this {@code Method} against the specified object.  Returns
   270      * true if the objects are the same.  Two {@code Methods} are the same if
   271      * they were declared by the same class and have the same name
   272      * and formal parameter types and return type.
   273      */
   274     public boolean equals(Object obj) {
   275         if (obj != null && obj instanceof Method) {
   276             Method other = (Method)obj;
   277             return data == other.data;
   278         }
   279         return false;
   280     }
   281 
   282     /**
   283      * Returns a hashcode for this {@code Method}.  The hashcode is computed
   284      * as the exclusive-or of the hashcodes for the underlying
   285      * method's declaring class name and the method's name.
   286      */
   287     public int hashCode() {
   288         return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
   289     }
   290 
   291     /**
   292      * Returns a string describing this {@code Method}.  The string is
   293      * formatted as the method access modifiers, if any, followed by
   294      * the method return type, followed by a space, followed by the
   295      * class declaring the method, followed by a period, followed by
   296      * the method name, followed by a parenthesized, comma-separated
   297      * list of the method's formal parameter types. If the method
   298      * throws checked exceptions, the parameter list is followed by a
   299      * space, followed by the word throws followed by a
   300      * comma-separated list of the thrown exception types.
   301      * For example:
   302      * <pre>
   303      *    public boolean java.lang.Object.equals(java.lang.Object)
   304      * </pre>
   305      *
   306      * <p>The access modifiers are placed in canonical order as
   307      * specified by "The Java Language Specification".  This is
   308      * {@code public}, {@code protected} or {@code private} first,
   309      * and then other modifiers in the following order:
   310      * {@code abstract}, {@code static}, {@code final},
   311      * {@code synchronized}, {@code native}, {@code strictfp}.
   312      */
   313     public String toString() {
   314         try {
   315             StringBuilder sb = new StringBuilder();
   316             int mod = getModifiers() & Modifier.methodModifiers();
   317             if (mod != 0) {
   318                 sb.append(Modifier.toString(mod)).append(' ');
   319             }
   320             sb.append(Field.getTypeName(getReturnType())).append(' ');
   321             sb.append(Field.getTypeName(getDeclaringClass())).append('.');
   322             sb.append(getName()).append('(');
   323             Class<?>[] params = getParameterTypes(); // avoid clone
   324             for (int j = 0; j < params.length; j++) {
   325                 sb.append(Field.getTypeName(params[j]));
   326                 if (j < (params.length - 1))
   327                     sb.append(',');
   328             }
   329             sb.append(')');
   330             /*
   331             Class<?>[] exceptions = exceptionTypes; // avoid clone
   332             if (exceptions.length > 0) {
   333                 sb.append(" throws ");
   334                 for (int k = 0; k < exceptions.length; k++) {
   335                     sb.append(exceptions[k].getName());
   336                     if (k < (exceptions.length - 1))
   337                         sb.append(',');
   338                 }
   339             }
   340             */
   341             return sb.toString();
   342         } catch (Exception e) {
   343             return "<" + e + ">";
   344         }
   345     }
   346 
   347     /**
   348      * Returns a string describing this {@code Method}, including
   349      * type parameters.  The string is formatted as the method access
   350      * modifiers, if any, followed by an angle-bracketed
   351      * comma-separated list of the method's type parameters, if any,
   352      * followed by the method's generic return type, followed by a
   353      * space, followed by the class declaring the method, followed by
   354      * a period, followed by the method name, followed by a
   355      * parenthesized, comma-separated list of the method's generic
   356      * formal parameter types.
   357      *
   358      * If this method was declared to take a variable number of
   359      * arguments, instead of denoting the last parameter as
   360      * "<tt><i>Type</i>[]</tt>", it is denoted as
   361      * "<tt><i>Type</i>...</tt>".
   362      *
   363      * A space is used to separate access modifiers from one another
   364      * and from the type parameters or return type.  If there are no
   365      * type parameters, the type parameter list is elided; if the type
   366      * parameter list is present, a space separates the list from the
   367      * class name.  If the method is declared to throw exceptions, the
   368      * parameter list is followed by a space, followed by the word
   369      * throws followed by a comma-separated list of the generic thrown
   370      * exception types.  If there are no type parameters, the type
   371      * parameter list is elided.
   372      *
   373      * <p>The access modifiers are placed in canonical order as
   374      * specified by "The Java Language Specification".  This is
   375      * {@code public}, {@code protected} or {@code private} first,
   376      * and then other modifiers in the following order:
   377      * {@code abstract}, {@code static}, {@code final},
   378      * {@code synchronized}, {@code native}, {@code strictfp}.
   379      *
   380      * @return a string describing this {@code Method},
   381      * include type parameters
   382      *
   383      * @since 1.5
   384      */
   385     public String toGenericString() {
   386         try {
   387             StringBuilder sb = new StringBuilder();
   388             int mod = getModifiers() & Modifier.methodModifiers();
   389             if (mod != 0) {
   390                 sb.append(Modifier.toString(mod)).append(' ');
   391             }
   392             TypeVariable<?>[] typeparms = getTypeParameters();
   393             if (typeparms.length > 0) {
   394                 boolean first = true;
   395                 sb.append('<');
   396                 for(TypeVariable<?> typeparm: typeparms) {
   397                     if (!first)
   398                         sb.append(',');
   399                     // Class objects can't occur here; no need to test
   400                     // and call Class.getName().
   401                     sb.append(typeparm.toString());
   402                     first = false;
   403                 }
   404                 sb.append("> ");
   405             }
   406 
   407             Type genRetType = getGenericReturnType();
   408             sb.append( ((genRetType instanceof Class<?>)?
   409                         Field.getTypeName((Class<?>)genRetType):genRetType.toString()))
   410                     .append(' ');
   411 
   412             sb.append(Field.getTypeName(getDeclaringClass())).append('.');
   413             sb.append(getName()).append('(');
   414             Type[] params = getGenericParameterTypes();
   415             for (int j = 0; j < params.length; j++) {
   416                 String param = (params[j] instanceof Class)?
   417                     Field.getTypeName((Class)params[j]):
   418                     (params[j].toString());
   419                 if (isVarArgs() && (j == params.length - 1)) // replace T[] with T...
   420                     param = param.replaceFirst("\\[\\]$", "...");
   421                 sb.append(param);
   422                 if (j < (params.length - 1))
   423                     sb.append(',');
   424             }
   425             sb.append(')');
   426             Type[] exceptions = getGenericExceptionTypes();
   427             if (exceptions.length > 0) {
   428                 sb.append(" throws ");
   429                 for (int k = 0; k < exceptions.length; k++) {
   430                     sb.append((exceptions[k] instanceof Class)?
   431                               ((Class)exceptions[k]).getName():
   432                               exceptions[k].toString());
   433                     if (k < (exceptions.length - 1))
   434                         sb.append(',');
   435                 }
   436             }
   437             return sb.toString();
   438         } catch (Exception e) {
   439             return "<" + e + ">";
   440         }
   441     }
   442 
   443     /**
   444      * Invokes the underlying method represented by this {@code Method}
   445      * object, on the specified object with the specified parameters.
   446      * Individual parameters are automatically unwrapped to match
   447      * primitive formal parameters, and both primitive and reference
   448      * parameters are subject to method invocation conversions as
   449      * necessary.
   450      *
   451      * <p>If the underlying method is static, then the specified {@code obj}
   452      * argument is ignored. It may be null.
   453      *
   454      * <p>If the number of formal parameters required by the underlying method is
   455      * 0, the supplied {@code args} array may be of length 0 or null.
   456      *
   457      * <p>If the underlying method is an instance method, it is invoked
   458      * using dynamic method lookup as documented in The Java Language
   459      * Specification, Second Edition, section 15.12.4.4; in particular,
   460      * overriding based on the runtime type of the target object will occur.
   461      *
   462      * <p>If the underlying method is static, the class that declared
   463      * the method is initialized if it has not already been initialized.
   464      *
   465      * <p>If the method completes normally, the value it returns is
   466      * returned to the caller of invoke; if the value has a primitive
   467      * type, it is first appropriately wrapped in an object. However,
   468      * if the value has the type of an array of a primitive type, the
   469      * elements of the array are <i>not</i> wrapped in objects; in
   470      * other words, an array of primitive type is returned.  If the
   471      * underlying method return type is void, the invocation returns
   472      * null.
   473      *
   474      * @param obj  the object the underlying method is invoked from
   475      * @param args the arguments used for the method call
   476      * @return the result of dispatching the method represented by
   477      * this object on {@code obj} with parameters
   478      * {@code args}
   479      *
   480      * @exception IllegalAccessException    if this {@code Method} object
   481      *              is enforcing Java language access control and the underlying
   482      *              method is inaccessible.
   483      * @exception IllegalArgumentException  if the method is an
   484      *              instance method and the specified object argument
   485      *              is not an instance of the class or interface
   486      *              declaring the underlying method (or of a subclass
   487      *              or implementor thereof); if the number of actual
   488      *              and formal parameters differ; if an unwrapping
   489      *              conversion for primitive arguments fails; or if,
   490      *              after possible unwrapping, a parameter value
   491      *              cannot be converted to the corresponding formal
   492      *              parameter type by a method invocation conversion.
   493      * @exception InvocationTargetException if the underlying method
   494      *              throws an exception.
   495      * @exception NullPointerException      if the specified object is null
   496      *              and the method is an instance method.
   497      * @exception ExceptionInInitializerError if the initialization
   498      * provoked by this method fails.
   499      */
   500     public Object invoke(Object obj, Object... args)
   501         throws IllegalAccessException, IllegalArgumentException,
   502            InvocationTargetException
   503     {
   504         final boolean isStatic = (getModifiers() & Modifier.STATIC) == 0;
   505         if (isStatic && obj == null) {
   506             throw new NullPointerException();
   507         }
   508         Class[] types = getParameterTypes();
   509         if (types.length != args.length) {
   510             throw new IllegalArgumentException("Types len " + types.length + " args: " + args.length);
   511         } else {
   512             args = args.clone();
   513             for (int i = 0; i < types.length; i++) {
   514                 Class c = types[i];
   515                 if (c.isPrimitive()) {
   516                     args[i] = toPrimitive(c, args[i]);
   517                 }
   518             }
   519         }
   520         Object res = invoke0(isStatic, this, obj, args);
   521         if (getReturnType().isPrimitive()) {
   522             res = fromPrimitive(getReturnType(), res);
   523         }
   524         return res;
   525     }
   526     
   527     @JavaScriptBody(args = { "st", "method", "self", "args" }, body =
   528           "var p;\n"
   529         + "if (st) {\n"
   530         + "  p = new Array(1);\n"
   531         + "  p[0] = self;\n"
   532         + "  p = p.concat(args);\n"
   533         + "} else {\n"
   534         + "  p = args;\n"
   535         + "}\n"
   536         + "return method._data().apply(self, p);\n"
   537     )
   538     private static native Object invoke0(boolean isStatic, Method m, Object self, Object[] args);
   539 
   540     static Object fromPrimitive(Class<?> type, Object o) {
   541         if (type == Integer.TYPE) {
   542             return fromRaw(Integer.class, "valueOf__Ljava_lang_Integer_2I", o);
   543         }
   544         if (type == Long.TYPE) {
   545             return fromRaw(Long.class, "valueOf__Ljava_lang_Long_2J", o);
   546         }
   547         if (type == Double.TYPE) {
   548             return fromRaw(Double.class, "valueOf__Ljava_lang_Double_2D", o);
   549         }
   550         if (type == Float.TYPE) {
   551             return fromRaw(Float.class, "valueOf__Ljava_lang_Float_2F", o);
   552         }
   553         if (type == Byte.TYPE) {
   554             return fromRaw(Byte.class, "valueOf__Ljava_lang_Byte_2B", o);
   555         }
   556         if (type == Boolean.TYPE) {
   557             return fromRaw(Boolean.class, "valueOf__Ljava_lang_Boolean_2Z", o);
   558         }
   559         if (type == Short.TYPE) {
   560             return fromRaw(Short.class, "valueOf__Ljava_lang_Short_2S", o);
   561         }
   562         if (type == Character.TYPE) {
   563             return fromRaw(Character.class, "valueOf__Ljava_lang_Character_2C", o);
   564         }
   565         if (type.getName().equals("void")) {
   566             return null;
   567         }
   568         throw new IllegalStateException("Can't convert " + o);
   569     }
   570     
   571     @JavaScriptBody(args = { "cls", "m", "o" }, 
   572         body = "return cls.cnstr(false)[m](o);"
   573     )
   574     private static native Integer fromRaw(Class<?> cls, String m, Object o);
   575 
   576     private static Object toPrimitive(Class<?> type, Object o) {
   577         if (type == Integer.TYPE) {
   578             return toRaw("intValue__I", o);
   579         }
   580         if (type == Long.TYPE) {
   581             return toRaw("longValue__J", o);
   582         }
   583         if (type == Double.TYPE) {
   584             return toRaw("doubleValue__D", o);
   585         }
   586         if (type == Float.TYPE) {
   587             return toRaw("floatValue__F", o);
   588         }
   589         if (type == Byte.TYPE) {
   590             return toRaw("byteValue__B", o);
   591         }
   592         if (type == Boolean.TYPE) {
   593             return toRaw("booleanValue__Z", o);
   594         }
   595         if (type == Short.TYPE) {
   596             return toRaw("shortValue__S", o);
   597         }
   598         if (type == Character.TYPE) {
   599             return toRaw("charValue__C", o);
   600         }
   601         if (type.getName().equals("void")) {
   602             return o;
   603         }
   604         throw new IllegalStateException("Can't convert " + o);
   605     }
   606     
   607     @JavaScriptBody(args = { "m", "o" }, 
   608         body = "return o[m](o);"
   609     )
   610     private static native Object toRaw(String m, Object o);
   611     
   612     /**
   613      * Returns {@code true} if this method is a bridge
   614      * method; returns {@code false} otherwise.
   615      *
   616      * @return true if and only if this method is a bridge
   617      * method as defined by the Java Language Specification.
   618      * @since 1.5
   619      */
   620     public boolean isBridge() {
   621         return (getModifiers() & Modifier.BRIDGE) != 0;
   622     }
   623 
   624     /**
   625      * Returns {@code true} if this method was declared to take
   626      * a variable number of arguments; returns {@code false}
   627      * otherwise.
   628      *
   629      * @return {@code true} if an only if this method was declared to
   630      * take a variable number of arguments.
   631      * @since 1.5
   632      */
   633     public boolean isVarArgs() {
   634         return (getModifiers() & Modifier.VARARGS) != 0;
   635     }
   636 
   637     /**
   638      * Returns {@code true} if this method is a synthetic
   639      * method; returns {@code false} otherwise.
   640      *
   641      * @return true if and only if this method is a synthetic
   642      * method as defined by the Java Language Specification.
   643      * @since 1.5
   644      */
   645     public boolean isSynthetic() {
   646         return Modifier.isSynthetic(getModifiers());
   647     }
   648 
   649     @JavaScriptBody(args = { "ac" }, 
   650         body = 
   651           "var a = this._data().anno;"
   652         + "if (a) {"
   653         + "  return a['L' + ac.jvmName + ';'];"
   654         + "} else return null;"
   655     )
   656     private Object getAnnotationData(Class<?> annotationClass) {
   657         throw new UnsupportedOperationException();
   658     }
   659     
   660     /**
   661      * @throws NullPointerException {@inheritDoc}
   662      * @since 1.5
   663      */
   664     public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
   665         Object data = getAnnotationData(annotationClass);
   666         return data == null ? null : AnnotationImpl.create(annotationClass, data);
   667     }
   668 
   669     /**
   670      * @since 1.5
   671      */
   672     public Annotation[] getDeclaredAnnotations()  {
   673         throw new UnsupportedOperationException();
   674     }
   675 
   676     /**
   677      * Returns the default value for the annotation member represented by
   678      * this {@code Method} instance.  If the member is of a primitive type,
   679      * an instance of the corresponding wrapper type is returned. Returns
   680      * null if no default is associated with the member, or if the method
   681      * instance does not represent a declared member of an annotation type.
   682      *
   683      * @return the default value for the annotation member represented
   684      *     by this {@code Method} instance.
   685      * @throws TypeNotPresentException if the annotation is of type
   686      *     {@link Class} and no definition can be found for the
   687      *     default class value.
   688      * @since  1.5
   689      */
   690     public Object getDefaultValue() {
   691         throw new UnsupportedOperationException();
   692     }
   693 
   694     /**
   695      * Returns an array of arrays that represent the annotations on the formal
   696      * parameters, in declaration order, of the method represented by
   697      * this {@code Method} object. (Returns an array of length zero if the
   698      * underlying method is parameterless.  If the method has one or more
   699      * parameters, a nested array of length zero is returned for each parameter
   700      * with no annotations.) The annotation objects contained in the returned
   701      * arrays are serializable.  The caller of this method is free to modify
   702      * the returned arrays; it will have no effect on the arrays returned to
   703      * other callers.
   704      *
   705      * @return an array of arrays that represent the annotations on the formal
   706      *    parameters, in declaration order, of the method represented by this
   707      *    Method object
   708      * @since 1.5
   709      */
   710     public Annotation[][] getParameterAnnotations() {
   711         throw new UnsupportedOperationException();
   712     }
   713 
   714     static {
   715         MethodImpl.INSTANCE = new MethodImpl() {
   716             protected Method create(Class<?> declaringClass, String name, Object data, String sig) {
   717                 return new Method(declaringClass, name, data, sig);
   718             }
   719         };
   720     }
   721 }