1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/rt/emul/mini/src/main/java/java/lang/reflect/Method.java Tue Feb 26 16:54:16 2013 +0100
1.3 @@ -0,0 +1,721 @@
1.4 +/*
1.5 + * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
1.7 + *
1.8 + * This code is free software; you can redistribute it and/or modify it
1.9 + * under the terms of the GNU General Public License version 2 only, as
1.10 + * published by the Free Software Foundation. Oracle designates this
1.11 + * particular file as subject to the "Classpath" exception as provided
1.12 + * by Oracle in the LICENSE file that accompanied this code.
1.13 + *
1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1.17 + * version 2 for more details (a copy is included in the LICENSE file that
1.18 + * accompanied this code).
1.19 + *
1.20 + * You should have received a copy of the GNU General Public License version
1.21 + * 2 along with this work; if not, write to the Free Software Foundation,
1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1.23 + *
1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
1.25 + * or visit www.oracle.com if you need additional information or have any
1.26 + * questions.
1.27 + */
1.28 +
1.29 +package java.lang.reflect;
1.30 +
1.31 +import java.lang.annotation.Annotation;
1.32 +import java.util.Enumeration;
1.33 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
1.34 +import org.apidesign.bck2brwsr.emul.reflect.AnnotationImpl;
1.35 +import org.apidesign.bck2brwsr.emul.reflect.MethodImpl;
1.36 +
1.37 +/**
1.38 + * A {@code Method} provides information about, and access to, a single method
1.39 + * on a class or interface. The reflected method may be a class method
1.40 + * or an instance method (including an abstract method).
1.41 + *
1.42 + * <p>A {@code Method} permits widening conversions to occur when matching the
1.43 + * actual parameters to invoke with the underlying method's formal
1.44 + * parameters, but it throws an {@code IllegalArgumentException} if a
1.45 + * narrowing conversion would occur.
1.46 + *
1.47 + * @see Member
1.48 + * @see java.lang.Class
1.49 + * @see java.lang.Class#getMethods()
1.50 + * @see java.lang.Class#getMethod(String, Class[])
1.51 + * @see java.lang.Class#getDeclaredMethods()
1.52 + * @see java.lang.Class#getDeclaredMethod(String, Class[])
1.53 + *
1.54 + * @author Kenneth Russell
1.55 + * @author Nakul Saraiya
1.56 + */
1.57 +public final
1.58 + class Method extends AccessibleObject implements GenericDeclaration,
1.59 + Member {
1.60 + private final Class<?> clazz;
1.61 + private final String name;
1.62 + private final Object data;
1.63 + private final String sig;
1.64 +
1.65 + // Generics infrastructure
1.66 +
1.67 + private String getGenericSignature() {return null;}
1.68 +
1.69 + /**
1.70 + * Package-private constructor used by ReflectAccess to enable
1.71 + * instantiation of these objects in Java code from the java.lang
1.72 + * package via sun.reflect.LangReflectAccess.
1.73 + */
1.74 + Method(Class<?> declaringClass, String name, Object data, String sig)
1.75 + {
1.76 + this.clazz = declaringClass;
1.77 + this.name = name;
1.78 + this.data = data;
1.79 + this.sig = sig;
1.80 + }
1.81 +
1.82 + /**
1.83 + * Package-private routine (exposed to java.lang.Class via
1.84 + * ReflectAccess) which returns a copy of this Method. The copy's
1.85 + * "root" field points to this Method.
1.86 + */
1.87 + Method copy() {
1.88 + return this;
1.89 + }
1.90 +
1.91 + /**
1.92 + * Returns the {@code Class} object representing the class or interface
1.93 + * that declares the method represented by this {@code Method} object.
1.94 + */
1.95 + public Class<?> getDeclaringClass() {
1.96 + return clazz;
1.97 + }
1.98 +
1.99 + /**
1.100 + * Returns the name of the method represented by this {@code Method}
1.101 + * object, as a {@code String}.
1.102 + */
1.103 + public String getName() {
1.104 + return name;
1.105 + }
1.106 +
1.107 + /**
1.108 + * Returns the Java language modifiers for the method represented
1.109 + * by this {@code Method} object, as an integer. The {@code Modifier} class should
1.110 + * be used to decode the modifiers.
1.111 + *
1.112 + * @see Modifier
1.113 + */
1.114 + public int getModifiers() {
1.115 + return getAccess(data);
1.116 + }
1.117 +
1.118 + @JavaScriptBody(args = "self", body = "return self.access;")
1.119 + private static native int getAccess(Object self);
1.120 +
1.121 + /**
1.122 + * Returns an array of {@code TypeVariable} objects that represent the
1.123 + * type variables declared by the generic declaration represented by this
1.124 + * {@code GenericDeclaration} object, in declaration order. Returns an
1.125 + * array of length 0 if the underlying generic declaration declares no type
1.126 + * variables.
1.127 + *
1.128 + * @return an array of {@code TypeVariable} objects that represent
1.129 + * the type variables declared by this generic declaration
1.130 + * @throws GenericSignatureFormatError if the generic
1.131 + * signature of this generic declaration does not conform to
1.132 + * the format specified in
1.133 + * <cite>The Java™ Virtual Machine Specification</cite>
1.134 + * @since 1.5
1.135 + */
1.136 + public TypeVariable<Method>[] getTypeParameters() {
1.137 + throw new UnsupportedOperationException();
1.138 + }
1.139 +
1.140 + /**
1.141 + * Returns a {@code Class} object that represents the formal return type
1.142 + * of the method represented by this {@code Method} object.
1.143 + *
1.144 + * @return the return type for the method this object represents
1.145 + */
1.146 + public Class<?> getReturnType() {
1.147 + return MethodImpl.signatureParser(sig).nextElement();
1.148 + }
1.149 +
1.150 + /**
1.151 + * Returns a {@code Type} object that represents the formal return
1.152 + * type of the method represented by this {@code Method} object.
1.153 + *
1.154 + * <p>If the return type is a parameterized type,
1.155 + * the {@code Type} object returned must accurately reflect
1.156 + * the actual type parameters used in the source code.
1.157 + *
1.158 + * <p>If the return type is a type variable or a parameterized type, it
1.159 + * is created. Otherwise, it is resolved.
1.160 + *
1.161 + * @return a {@code Type} object that represents the formal return
1.162 + * type of the underlying method
1.163 + * @throws GenericSignatureFormatError
1.164 + * if the generic method signature does not conform to the format
1.165 + * specified in
1.166 + * <cite>The Java™ Virtual Machine Specification</cite>
1.167 + * @throws TypeNotPresentException if the underlying method's
1.168 + * return type refers to a non-existent type declaration
1.169 + * @throws MalformedParameterizedTypeException if the
1.170 + * underlying method's return typed refers to a parameterized
1.171 + * type that cannot be instantiated for any reason
1.172 + * @since 1.5
1.173 + */
1.174 + public Type getGenericReturnType() {
1.175 + throw new UnsupportedOperationException();
1.176 + }
1.177 +
1.178 +
1.179 + /**
1.180 + * Returns an array of {@code Class} objects that represent the formal
1.181 + * parameter types, in declaration order, of the method
1.182 + * represented by this {@code Method} object. Returns an array of length
1.183 + * 0 if the underlying method takes no parameters.
1.184 + *
1.185 + * @return the parameter types for the method this object
1.186 + * represents
1.187 + */
1.188 + public Class<?>[] getParameterTypes() {
1.189 + Class[] arr = new Class[MethodImpl.signatureElements(sig) - 1];
1.190 + Enumeration<Class> en = MethodImpl.signatureParser(sig);
1.191 + en.nextElement(); // return type
1.192 + for (int i = 0; i < arr.length; i++) {
1.193 + arr[i] = en.nextElement();
1.194 + }
1.195 + return arr;
1.196 + }
1.197 +
1.198 + /**
1.199 + * Returns an array of {@code Type} objects that represent the formal
1.200 + * parameter types, in declaration order, of the method represented by
1.201 + * this {@code Method} object. Returns an array of length 0 if the
1.202 + * underlying method takes no parameters.
1.203 + *
1.204 + * <p>If a formal parameter type is a parameterized type,
1.205 + * the {@code Type} object returned for it must accurately reflect
1.206 + * the actual type parameters used in the source code.
1.207 + *
1.208 + * <p>If a formal parameter type is a type variable or a parameterized
1.209 + * type, it is created. Otherwise, it is resolved.
1.210 + *
1.211 + * @return an array of Types that represent the formal
1.212 + * parameter types of the underlying method, in declaration order
1.213 + * @throws GenericSignatureFormatError
1.214 + * if the generic method signature does not conform to the format
1.215 + * specified in
1.216 + * <cite>The Java™ Virtual Machine Specification</cite>
1.217 + * @throws TypeNotPresentException if any of the parameter
1.218 + * types of the underlying method refers to a non-existent type
1.219 + * declaration
1.220 + * @throws MalformedParameterizedTypeException if any of
1.221 + * the underlying method's parameter types refer to a parameterized
1.222 + * type that cannot be instantiated for any reason
1.223 + * @since 1.5
1.224 + */
1.225 + public Type[] getGenericParameterTypes() {
1.226 + throw new UnsupportedOperationException();
1.227 + }
1.228 +
1.229 +
1.230 + /**
1.231 + * Returns an array of {@code Class} objects that represent
1.232 + * the types of the exceptions declared to be thrown
1.233 + * by the underlying method
1.234 + * represented by this {@code Method} object. Returns an array of length
1.235 + * 0 if the method declares no exceptions in its {@code throws} clause.
1.236 + *
1.237 + * @return the exception types declared as being thrown by the
1.238 + * method this object represents
1.239 + */
1.240 + public Class<?>[] getExceptionTypes() {
1.241 + throw new UnsupportedOperationException();
1.242 + //return (Class<?>[]) exceptionTypes.clone();
1.243 + }
1.244 +
1.245 + /**
1.246 + * Returns an array of {@code Type} objects that represent the
1.247 + * exceptions declared to be thrown by this {@code Method} object.
1.248 + * Returns an array of length 0 if the underlying method declares
1.249 + * no exceptions in its {@code throws} clause.
1.250 + *
1.251 + * <p>If an exception type is a type variable or a parameterized
1.252 + * type, it is created. Otherwise, it is resolved.
1.253 + *
1.254 + * @return an array of Types that represent the exception types
1.255 + * thrown by the underlying method
1.256 + * @throws GenericSignatureFormatError
1.257 + * if the generic method signature does not conform to the format
1.258 + * specified in
1.259 + * <cite>The Java™ Virtual Machine Specification</cite>
1.260 + * @throws TypeNotPresentException if the underlying method's
1.261 + * {@code throws} clause refers to a non-existent type declaration
1.262 + * @throws MalformedParameterizedTypeException if
1.263 + * the underlying method's {@code throws} clause refers to a
1.264 + * parameterized type that cannot be instantiated for any reason
1.265 + * @since 1.5
1.266 + */
1.267 + public Type[] getGenericExceptionTypes() {
1.268 + throw new UnsupportedOperationException();
1.269 + }
1.270 +
1.271 + /**
1.272 + * Compares this {@code Method} against the specified object. Returns
1.273 + * true if the objects are the same. Two {@code Methods} are the same if
1.274 + * they were declared by the same class and have the same name
1.275 + * and formal parameter types and return type.
1.276 + */
1.277 + public boolean equals(Object obj) {
1.278 + if (obj != null && obj instanceof Method) {
1.279 + Method other = (Method)obj;
1.280 + return data == other.data;
1.281 + }
1.282 + return false;
1.283 + }
1.284 +
1.285 + /**
1.286 + * Returns a hashcode for this {@code Method}. The hashcode is computed
1.287 + * as the exclusive-or of the hashcodes for the underlying
1.288 + * method's declaring class name and the method's name.
1.289 + */
1.290 + public int hashCode() {
1.291 + return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
1.292 + }
1.293 +
1.294 + /**
1.295 + * Returns a string describing this {@code Method}. The string is
1.296 + * formatted as the method access modifiers, if any, followed by
1.297 + * the method return type, followed by a space, followed by the
1.298 + * class declaring the method, followed by a period, followed by
1.299 + * the method name, followed by a parenthesized, comma-separated
1.300 + * list of the method's formal parameter types. If the method
1.301 + * throws checked exceptions, the parameter list is followed by a
1.302 + * space, followed by the word throws followed by a
1.303 + * comma-separated list of the thrown exception types.
1.304 + * For example:
1.305 + * <pre>
1.306 + * public boolean java.lang.Object.equals(java.lang.Object)
1.307 + * </pre>
1.308 + *
1.309 + * <p>The access modifiers are placed in canonical order as
1.310 + * specified by "The Java Language Specification". This is
1.311 + * {@code public}, {@code protected} or {@code private} first,
1.312 + * and then other modifiers in the following order:
1.313 + * {@code abstract}, {@code static}, {@code final},
1.314 + * {@code synchronized}, {@code native}, {@code strictfp}.
1.315 + */
1.316 + public String toString() {
1.317 + try {
1.318 + StringBuilder sb = new StringBuilder();
1.319 + int mod = getModifiers() & Modifier.methodModifiers();
1.320 + if (mod != 0) {
1.321 + sb.append(Modifier.toString(mod)).append(' ');
1.322 + }
1.323 + sb.append(Field.getTypeName(getReturnType())).append(' ');
1.324 + sb.append(Field.getTypeName(getDeclaringClass())).append('.');
1.325 + sb.append(getName()).append('(');
1.326 + Class<?>[] params = getParameterTypes(); // avoid clone
1.327 + for (int j = 0; j < params.length; j++) {
1.328 + sb.append(Field.getTypeName(params[j]));
1.329 + if (j < (params.length - 1))
1.330 + sb.append(',');
1.331 + }
1.332 + sb.append(')');
1.333 + /*
1.334 + Class<?>[] exceptions = exceptionTypes; // avoid clone
1.335 + if (exceptions.length > 0) {
1.336 + sb.append(" throws ");
1.337 + for (int k = 0; k < exceptions.length; k++) {
1.338 + sb.append(exceptions[k].getName());
1.339 + if (k < (exceptions.length - 1))
1.340 + sb.append(',');
1.341 + }
1.342 + }
1.343 + */
1.344 + return sb.toString();
1.345 + } catch (Exception e) {
1.346 + return "<" + e + ">";
1.347 + }
1.348 + }
1.349 +
1.350 + /**
1.351 + * Returns a string describing this {@code Method}, including
1.352 + * type parameters. The string is formatted as the method access
1.353 + * modifiers, if any, followed by an angle-bracketed
1.354 + * comma-separated list of the method's type parameters, if any,
1.355 + * followed by the method's generic return type, followed by a
1.356 + * space, followed by the class declaring the method, followed by
1.357 + * a period, followed by the method name, followed by a
1.358 + * parenthesized, comma-separated list of the method's generic
1.359 + * formal parameter types.
1.360 + *
1.361 + * If this method was declared to take a variable number of
1.362 + * arguments, instead of denoting the last parameter as
1.363 + * "<tt><i>Type</i>[]</tt>", it is denoted as
1.364 + * "<tt><i>Type</i>...</tt>".
1.365 + *
1.366 + * A space is used to separate access modifiers from one another
1.367 + * and from the type parameters or return type. If there are no
1.368 + * type parameters, the type parameter list is elided; if the type
1.369 + * parameter list is present, a space separates the list from the
1.370 + * class name. If the method is declared to throw exceptions, the
1.371 + * parameter list is followed by a space, followed by the word
1.372 + * throws followed by a comma-separated list of the generic thrown
1.373 + * exception types. If there are no type parameters, the type
1.374 + * parameter list is elided.
1.375 + *
1.376 + * <p>The access modifiers are placed in canonical order as
1.377 + * specified by "The Java Language Specification". This is
1.378 + * {@code public}, {@code protected} or {@code private} first,
1.379 + * and then other modifiers in the following order:
1.380 + * {@code abstract}, {@code static}, {@code final},
1.381 + * {@code synchronized}, {@code native}, {@code strictfp}.
1.382 + *
1.383 + * @return a string describing this {@code Method},
1.384 + * include type parameters
1.385 + *
1.386 + * @since 1.5
1.387 + */
1.388 + public String toGenericString() {
1.389 + try {
1.390 + StringBuilder sb = new StringBuilder();
1.391 + int mod = getModifiers() & Modifier.methodModifiers();
1.392 + if (mod != 0) {
1.393 + sb.append(Modifier.toString(mod)).append(' ');
1.394 + }
1.395 + TypeVariable<?>[] typeparms = getTypeParameters();
1.396 + if (typeparms.length > 0) {
1.397 + boolean first = true;
1.398 + sb.append('<');
1.399 + for(TypeVariable<?> typeparm: typeparms) {
1.400 + if (!first)
1.401 + sb.append(',');
1.402 + // Class objects can't occur here; no need to test
1.403 + // and call Class.getName().
1.404 + sb.append(typeparm.toString());
1.405 + first = false;
1.406 + }
1.407 + sb.append("> ");
1.408 + }
1.409 +
1.410 + Type genRetType = getGenericReturnType();
1.411 + sb.append( ((genRetType instanceof Class<?>)?
1.412 + Field.getTypeName((Class<?>)genRetType):genRetType.toString()))
1.413 + .append(' ');
1.414 +
1.415 + sb.append(Field.getTypeName(getDeclaringClass())).append('.');
1.416 + sb.append(getName()).append('(');
1.417 + Type[] params = getGenericParameterTypes();
1.418 + for (int j = 0; j < params.length; j++) {
1.419 + String param = (params[j] instanceof Class)?
1.420 + Field.getTypeName((Class)params[j]):
1.421 + (params[j].toString());
1.422 + if (isVarArgs() && (j == params.length - 1)) // replace T[] with T...
1.423 + param = param.replaceFirst("\\[\\]$", "...");
1.424 + sb.append(param);
1.425 + if (j < (params.length - 1))
1.426 + sb.append(',');
1.427 + }
1.428 + sb.append(')');
1.429 + Type[] exceptions = getGenericExceptionTypes();
1.430 + if (exceptions.length > 0) {
1.431 + sb.append(" throws ");
1.432 + for (int k = 0; k < exceptions.length; k++) {
1.433 + sb.append((exceptions[k] instanceof Class)?
1.434 + ((Class)exceptions[k]).getName():
1.435 + exceptions[k].toString());
1.436 + if (k < (exceptions.length - 1))
1.437 + sb.append(',');
1.438 + }
1.439 + }
1.440 + return sb.toString();
1.441 + } catch (Exception e) {
1.442 + return "<" + e + ">";
1.443 + }
1.444 + }
1.445 +
1.446 + /**
1.447 + * Invokes the underlying method represented by this {@code Method}
1.448 + * object, on the specified object with the specified parameters.
1.449 + * Individual parameters are automatically unwrapped to match
1.450 + * primitive formal parameters, and both primitive and reference
1.451 + * parameters are subject to method invocation conversions as
1.452 + * necessary.
1.453 + *
1.454 + * <p>If the underlying method is static, then the specified {@code obj}
1.455 + * argument is ignored. It may be null.
1.456 + *
1.457 + * <p>If the number of formal parameters required by the underlying method is
1.458 + * 0, the supplied {@code args} array may be of length 0 or null.
1.459 + *
1.460 + * <p>If the underlying method is an instance method, it is invoked
1.461 + * using dynamic method lookup as documented in The Java Language
1.462 + * Specification, Second Edition, section 15.12.4.4; in particular,
1.463 + * overriding based on the runtime type of the target object will occur.
1.464 + *
1.465 + * <p>If the underlying method is static, the class that declared
1.466 + * the method is initialized if it has not already been initialized.
1.467 + *
1.468 + * <p>If the method completes normally, the value it returns is
1.469 + * returned to the caller of invoke; if the value has a primitive
1.470 + * type, it is first appropriately wrapped in an object. However,
1.471 + * if the value has the type of an array of a primitive type, the
1.472 + * elements of the array are <i>not</i> wrapped in objects; in
1.473 + * other words, an array of primitive type is returned. If the
1.474 + * underlying method return type is void, the invocation returns
1.475 + * null.
1.476 + *
1.477 + * @param obj the object the underlying method is invoked from
1.478 + * @param args the arguments used for the method call
1.479 + * @return the result of dispatching the method represented by
1.480 + * this object on {@code obj} with parameters
1.481 + * {@code args}
1.482 + *
1.483 + * @exception IllegalAccessException if this {@code Method} object
1.484 + * is enforcing Java language access control and the underlying
1.485 + * method is inaccessible.
1.486 + * @exception IllegalArgumentException if the method is an
1.487 + * instance method and the specified object argument
1.488 + * is not an instance of the class or interface
1.489 + * declaring the underlying method (or of a subclass
1.490 + * or implementor thereof); if the number of actual
1.491 + * and formal parameters differ; if an unwrapping
1.492 + * conversion for primitive arguments fails; or if,
1.493 + * after possible unwrapping, a parameter value
1.494 + * cannot be converted to the corresponding formal
1.495 + * parameter type by a method invocation conversion.
1.496 + * @exception InvocationTargetException if the underlying method
1.497 + * throws an exception.
1.498 + * @exception NullPointerException if the specified object is null
1.499 + * and the method is an instance method.
1.500 + * @exception ExceptionInInitializerError if the initialization
1.501 + * provoked by this method fails.
1.502 + */
1.503 + public Object invoke(Object obj, Object... args)
1.504 + throws IllegalAccessException, IllegalArgumentException,
1.505 + InvocationTargetException
1.506 + {
1.507 + final boolean isStatic = (getModifiers() & Modifier.STATIC) == 0;
1.508 + if (isStatic && obj == null) {
1.509 + throw new NullPointerException();
1.510 + }
1.511 + Class[] types = getParameterTypes();
1.512 + if (types.length != args.length) {
1.513 + throw new IllegalArgumentException("Types len " + types.length + " args: " + args.length);
1.514 + } else {
1.515 + args = args.clone();
1.516 + for (int i = 0; i < types.length; i++) {
1.517 + Class c = types[i];
1.518 + if (c.isPrimitive()) {
1.519 + args[i] = toPrimitive(c, args[i]);
1.520 + }
1.521 + }
1.522 + }
1.523 + Object res = invoke0(isStatic, this, obj, args);
1.524 + if (getReturnType().isPrimitive()) {
1.525 + res = fromPrimitive(getReturnType(), res);
1.526 + }
1.527 + return res;
1.528 + }
1.529 +
1.530 + @JavaScriptBody(args = { "st", "method", "self", "args" }, body =
1.531 + "var p;\n"
1.532 + + "if (st) {\n"
1.533 + + " p = new Array(1);\n"
1.534 + + " p[0] = self;\n"
1.535 + + " p = p.concat(args);\n"
1.536 + + "} else {\n"
1.537 + + " p = args;\n"
1.538 + + "}\n"
1.539 + + "return method._data().apply(self, p);\n"
1.540 + )
1.541 + private static native Object invoke0(boolean isStatic, Method m, Object self, Object[] args);
1.542 +
1.543 + static Object fromPrimitive(Class<?> type, Object o) {
1.544 + if (type == Integer.TYPE) {
1.545 + return fromRaw(Integer.class, "valueOf__Ljava_lang_Integer_2I", o);
1.546 + }
1.547 + if (type == Long.TYPE) {
1.548 + return fromRaw(Long.class, "valueOf__Ljava_lang_Long_2J", o);
1.549 + }
1.550 + if (type == Double.TYPE) {
1.551 + return fromRaw(Double.class, "valueOf__Ljava_lang_Double_2D", o);
1.552 + }
1.553 + if (type == Float.TYPE) {
1.554 + return fromRaw(Float.class, "valueOf__Ljava_lang_Float_2F", o);
1.555 + }
1.556 + if (type == Byte.TYPE) {
1.557 + return fromRaw(Byte.class, "valueOf__Ljava_lang_Byte_2B", o);
1.558 + }
1.559 + if (type == Boolean.TYPE) {
1.560 + return fromRaw(Boolean.class, "valueOf__Ljava_lang_Boolean_2Z", o);
1.561 + }
1.562 + if (type == Short.TYPE) {
1.563 + return fromRaw(Short.class, "valueOf__Ljava_lang_Short_2S", o);
1.564 + }
1.565 + if (type == Character.TYPE) {
1.566 + return fromRaw(Character.class, "valueOf__Ljava_lang_Character_2C", o);
1.567 + }
1.568 + if (type.getName().equals("void")) {
1.569 + return null;
1.570 + }
1.571 + throw new IllegalStateException("Can't convert " + o);
1.572 + }
1.573 +
1.574 + @JavaScriptBody(args = { "cls", "m", "o" },
1.575 + body = "return cls.cnstr(false)[m](o);"
1.576 + )
1.577 + private static native Integer fromRaw(Class<?> cls, String m, Object o);
1.578 +
1.579 + private static Object toPrimitive(Class<?> type, Object o) {
1.580 + if (type == Integer.TYPE) {
1.581 + return toRaw("intValue__I", o);
1.582 + }
1.583 + if (type == Long.TYPE) {
1.584 + return toRaw("longValue__J", o);
1.585 + }
1.586 + if (type == Double.TYPE) {
1.587 + return toRaw("doubleValue__D", o);
1.588 + }
1.589 + if (type == Float.TYPE) {
1.590 + return toRaw("floatValue__F", o);
1.591 + }
1.592 + if (type == Byte.TYPE) {
1.593 + return toRaw("byteValue__B", o);
1.594 + }
1.595 + if (type == Boolean.TYPE) {
1.596 + return toRaw("booleanValue__Z", o);
1.597 + }
1.598 + if (type == Short.TYPE) {
1.599 + return toRaw("shortValue__S", o);
1.600 + }
1.601 + if (type == Character.TYPE) {
1.602 + return toRaw("charValue__C", o);
1.603 + }
1.604 + if (type.getName().equals("void")) {
1.605 + return o;
1.606 + }
1.607 + throw new IllegalStateException("Can't convert " + o);
1.608 + }
1.609 +
1.610 + @JavaScriptBody(args = { "m", "o" },
1.611 + body = "return o[m](o);"
1.612 + )
1.613 + private static native Object toRaw(String m, Object o);
1.614 +
1.615 + /**
1.616 + * Returns {@code true} if this method is a bridge
1.617 + * method; returns {@code false} otherwise.
1.618 + *
1.619 + * @return true if and only if this method is a bridge
1.620 + * method as defined by the Java Language Specification.
1.621 + * @since 1.5
1.622 + */
1.623 + public boolean isBridge() {
1.624 + return (getModifiers() & Modifier.BRIDGE) != 0;
1.625 + }
1.626 +
1.627 + /**
1.628 + * Returns {@code true} if this method was declared to take
1.629 + * a variable number of arguments; returns {@code false}
1.630 + * otherwise.
1.631 + *
1.632 + * @return {@code true} if an only if this method was declared to
1.633 + * take a variable number of arguments.
1.634 + * @since 1.5
1.635 + */
1.636 + public boolean isVarArgs() {
1.637 + return (getModifiers() & Modifier.VARARGS) != 0;
1.638 + }
1.639 +
1.640 + /**
1.641 + * Returns {@code true} if this method is a synthetic
1.642 + * method; returns {@code false} otherwise.
1.643 + *
1.644 + * @return true if and only if this method is a synthetic
1.645 + * method as defined by the Java Language Specification.
1.646 + * @since 1.5
1.647 + */
1.648 + public boolean isSynthetic() {
1.649 + return Modifier.isSynthetic(getModifiers());
1.650 + }
1.651 +
1.652 + @JavaScriptBody(args = { "ac" },
1.653 + body =
1.654 + "var a = this._data().anno;"
1.655 + + "if (a) {"
1.656 + + " return a['L' + ac.jvmName + ';'];"
1.657 + + "} else return null;"
1.658 + )
1.659 + private Object getAnnotationData(Class<?> annotationClass) {
1.660 + throw new UnsupportedOperationException();
1.661 + }
1.662 +
1.663 + /**
1.664 + * @throws NullPointerException {@inheritDoc}
1.665 + * @since 1.5
1.666 + */
1.667 + public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
1.668 + Object data = getAnnotationData(annotationClass);
1.669 + return data == null ? null : AnnotationImpl.create(annotationClass, data);
1.670 + }
1.671 +
1.672 + /**
1.673 + * @since 1.5
1.674 + */
1.675 + public Annotation[] getDeclaredAnnotations() {
1.676 + throw new UnsupportedOperationException();
1.677 + }
1.678 +
1.679 + /**
1.680 + * Returns the default value for the annotation member represented by
1.681 + * this {@code Method} instance. If the member is of a primitive type,
1.682 + * an instance of the corresponding wrapper type is returned. Returns
1.683 + * null if no default is associated with the member, or if the method
1.684 + * instance does not represent a declared member of an annotation type.
1.685 + *
1.686 + * @return the default value for the annotation member represented
1.687 + * by this {@code Method} instance.
1.688 + * @throws TypeNotPresentException if the annotation is of type
1.689 + * {@link Class} and no definition can be found for the
1.690 + * default class value.
1.691 + * @since 1.5
1.692 + */
1.693 + public Object getDefaultValue() {
1.694 + throw new UnsupportedOperationException();
1.695 + }
1.696 +
1.697 + /**
1.698 + * Returns an array of arrays that represent the annotations on the formal
1.699 + * parameters, in declaration order, of the method represented by
1.700 + * this {@code Method} object. (Returns an array of length zero if the
1.701 + * underlying method is parameterless. If the method has one or more
1.702 + * parameters, a nested array of length zero is returned for each parameter
1.703 + * with no annotations.) The annotation objects contained in the returned
1.704 + * arrays are serializable. The caller of this method is free to modify
1.705 + * the returned arrays; it will have no effect on the arrays returned to
1.706 + * other callers.
1.707 + *
1.708 + * @return an array of arrays that represent the annotations on the formal
1.709 + * parameters, in declaration order, of the method represented by this
1.710 + * Method object
1.711 + * @since 1.5
1.712 + */
1.713 + public Annotation[][] getParameterAnnotations() {
1.714 + throw new UnsupportedOperationException();
1.715 + }
1.716 +
1.717 + static {
1.718 + MethodImpl.INSTANCE = new MethodImpl() {
1.719 + protected Method create(Class<?> declaringClass, String name, Object data, String sig) {
1.720 + return new Method(declaringClass, name, data, sig);
1.721 + }
1.722 + };
1.723 + }
1.724 +}