< prev index next >

src/java.base/share/classes/java/lang/invoke/MemberName.java

Print this page

   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.invoke;
  27 

  28 import sun.invoke.util.BytecodeDescriptor;
  29 import sun.invoke.util.VerifyAccess;
  30 
  31 import java.lang.reflect.Constructor;
  32 import java.lang.reflect.Field;
  33 import java.lang.reflect.Member;
  34 import java.lang.reflect.Method;
  35 import java.lang.reflect.Modifier;
  36 import java.util.ArrayList;
  37 import java.util.Collections;
  38 import java.util.Iterator;
  39 import java.util.List;
  40 import java.util.Objects;
  41 
  42 import static java.lang.invoke.MethodHandleNatives.Constants.*;
  43 import static java.lang.invoke.MethodHandleStatics.newIllegalArgumentException;
  44 import static java.lang.invoke.MethodHandleStatics.newInternalError;
  45 
  46 /**
  47  * A {@code MemberName} is a compact symbolic datum which fully characterizes

 174         }
 175         if (!isInvocable()) {
 176             throw newIllegalArgumentException("not invocable, no method type");
 177         }
 178 
 179         // Get a snapshot of type which doesn't get changed by racing threads.
 180         final Object type = this.type;
 181         if (type instanceof String) {
 182             return (String) type;
 183         } else {
 184             return getMethodType().toMethodDescriptorString();
 185         }
 186     }
 187 
 188     /** Return the actual type under which this method or constructor must be invoked.
 189      *  For non-static methods or constructors, this is the type with a leading parameter,
 190      *  a reference to declaring class.  For static methods, it is the same as the declared type.
 191      */
 192     public MethodType getInvocationType() {
 193         MethodType itype = getMethodOrFieldType();
 194         if (isConstructor() && getReferenceKind() == REF_newInvokeSpecial)
 195             return itype.changeReturnType(clazz);

 196         if (!isStatic())
 197             return itype.insertParameterTypes(0, clazz);
 198         return itype;
 199     }
 200 
 201     /** Utility method producing the parameter types of the method type. */
 202     public Class<?>[] getParameterTypes() {
 203         return getMethodType().parameterArray();
 204     }
 205 
 206     /** Utility method producing the return type of the method type. */
 207     public Class<?> getReturnType() {
 208         return getMethodType().returnType();
 209     }
 210 
 211     /** Return the declared type of this member, which
 212      *  must be a field or type.
 213      *  If it is a type member, that type itself is returned.
 214      */
 215     public Class<?> getFieldType() {
 216         if (type == null) {
 217             expandFromVM();

 266     }
 267 
 268     /** Return the modifier flags of this member.
 269      *  @see java.lang.reflect.Modifier
 270      */
 271     public int getModifiers() {
 272         return (flags & RECOGNIZED_MODIFIERS);
 273     }
 274 
 275     /** Return the reference kind of this member, or zero if none.
 276      */
 277     public byte getReferenceKind() {
 278         return (byte) ((flags >>> MN_REFERENCE_KIND_SHIFT) & MN_REFERENCE_KIND_MASK);
 279     }
 280     private boolean referenceKindIsConsistent() {
 281         byte refKind = getReferenceKind();
 282         if (refKind == REF_NONE)  return isType();
 283         if (isField()) {
 284             assert(staticIsConsistent());
 285             assert(MethodHandleNatives.refKindIsField(refKind));
 286         } else if (isConstructor()) {
 287             assert(refKind == REF_newInvokeSpecial || refKind == REF_invokeSpecial);
 288         } else if (isMethod()) {
 289             assert(staticIsConsistent());
 290             assert(MethodHandleNatives.refKindIsMethod(refKind));
 291             if (clazz.isInterface())
 292                 assert(refKind == REF_invokeInterface ||
 293                        refKind == REF_invokeStatic    ||
 294                        refKind == REF_invokeSpecial   ||
 295                        refKind == REF_invokeVirtual && isObjectPublicMethod());
 296         } else {
 297             assert(false);
 298         }
 299         return true;
 300     }
 301     private boolean isObjectPublicMethod() {
 302         if (clazz == Object.class)  return true;
 303         MethodType mtype = getMethodType();
 304         if (name.equals("toString") && mtype.returnType() == String.class && mtype.parameterCount() == 0)
 305             return true;
 306         if (name.equals("hashCode") && mtype.returnType() == int.class && mtype.parameterCount() == 0)

 412     private static final int MH_INVOKE_MODS = Modifier.NATIVE | Modifier.FINAL | Modifier.PUBLIC;
 413 
 414     /** Utility method to query the modifier flags of this member. */
 415     public boolean isStatic() {
 416         return Modifier.isStatic(flags);
 417     }
 418     /** Utility method to query the modifier flags of this member. */
 419     public boolean isPublic() {
 420         return Modifier.isPublic(flags);
 421     }
 422     /** Utility method to query the modifier flags of this member. */
 423     public boolean isPrivate() {
 424         return Modifier.isPrivate(flags);
 425     }
 426     /** Utility method to query the modifier flags of this member. */
 427     public boolean isProtected() {
 428         return Modifier.isProtected(flags);
 429     }
 430     /** Utility method to query the modifier flags of this member. */
 431     public boolean isFinal() {


 432         return Modifier.isFinal(flags);
 433     }
 434     /** Utility method to query whether this member or its defining class is final. */
 435     public boolean canBeStaticallyBound() {
 436         return Modifier.isFinal(flags | clazz.getModifiers());
 437     }
 438     /** Utility method to query the modifier flags of this member. */
 439     public boolean isVolatile() {
 440         return Modifier.isVolatile(flags);
 441     }
 442     /** Utility method to query the modifier flags of this member. */
 443     public boolean isAbstract() {
 444         return Modifier.isAbstract(flags);
 445     }
 446     /** Utility method to query the modifier flags of this member. */
 447     public boolean isNative() {
 448         return Modifier.isNative(flags);
 449     }
 450     // let the rest (native, volatile, transient, etc.) be tested via Modifier.isFoo
 451 
 452     // unofficial modifier flags, used by HotSpot:
 453     static final int BRIDGE    = 0x00000040;
 454     static final int VARARGS   = 0x00000080;
 455     static final int SYNTHETIC = 0x00001000;
 456     static final int ANNOTATION= 0x00002000;
 457     static final int ENUM      = 0x00004000;

 458     /** Utility method to query the modifier flags of this member; returns false if the member is not a method. */
 459     public boolean isBridge() {
 460         return testAllFlags(IS_METHOD | BRIDGE);
 461     }
 462     /** Utility method to query the modifier flags of this member; returns false if the member is not a method. */
 463     public boolean isVarargs() {
 464         return testAllFlags(VARARGS) && isInvocable();
 465     }
 466     /** Utility method to query the modifier flags of this member; returns false if the member is not a method. */
 467     public boolean isSynthetic() {
 468         return testAllFlags(SYNTHETIC);
 469     }
 470 












 471     static final String CONSTRUCTOR_NAME = "<init>";  // the ever-popular
 472 

 473     // modifiers exported by the JVM:
 474     static final int RECOGNIZED_MODIFIERS = 0xFFFF;
 475 
 476     // private flags, not part of RECOGNIZED_MODIFIERS:
 477     static final int
 478             IS_METHOD        = MN_IS_METHOD,        // method (not constructor)
 479             IS_CONSTRUCTOR   = MN_IS_CONSTRUCTOR,   // constructor
 480             IS_FIELD         = MN_IS_FIELD,         // field
 481             IS_TYPE          = MN_IS_TYPE,          // nested type
 482             CALLER_SENSITIVE = MN_CALLER_SENSITIVE, // @CallerSensitive annotation detected
 483             TRUSTED_FINAL    = MN_TRUSTED_FINAL;    // trusted final field
 484 
 485     static final int ALL_ACCESS = Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED;
 486     static final int ALL_KINDS = IS_METHOD | IS_CONSTRUCTOR | IS_FIELD | IS_TYPE;
 487     static final int IS_INVOCABLE = IS_METHOD | IS_CONSTRUCTOR;
 488     static final int IS_FIELD_OR_METHOD = IS_METHOD | IS_FIELD;
 489     static final int SEARCH_ALL_SUPERS = MN_SEARCH_SUPERCLASSES | MN_SEARCH_INTERFACES;
 490 
 491     /** Utility method to query whether this member is a method or constructor. */
 492     public boolean isInvocable() {
 493         return testAnyFlags(IS_INVOCABLE);
 494     }
 495     /** Utility method to query whether this member is a method, constructor, or field. */
 496     public boolean isFieldOrMethod() {
 497         return testAnyFlags(IS_FIELD_OR_METHOD);
 498     }
 499     /** Query whether this member is a method. */
 500     public boolean isMethod() {
 501         return testAllFlags(IS_METHOD);
 502     }
 503     /** Query whether this member is a constructor. */
 504     public boolean isConstructor() {
 505         return testAllFlags(IS_CONSTRUCTOR);




 506     }
 507     /** Query whether this member is a field. */
 508     public boolean isField() {
 509         return testAllFlags(IS_FIELD);
 510     }
 511     /** Query whether this member is a type. */
 512     public boolean isType() {
 513         return testAllFlags(IS_TYPE);
 514     }
 515     /** Utility method to query whether this member is neither public, private, nor protected. */
 516     public boolean isPackage() {
 517         return !testAnyFlags(ALL_ACCESS);
 518     }
 519     /** Query whether this member has a CallerSensitive annotation. */
 520     public boolean isCallerSensitive() {
 521         return testAllFlags(CALLER_SENSITIVE);
 522     }
 523     /** Query whether this member is a trusted final field. */
 524     public boolean isTrustedFinalField() { return testAllFlags(TRUSTED_FINAL|IS_FIELD); }
 525 

 616                 throw new AbstractMethodError(this.toString());
 617             if (getReferenceKind() == REF_invokeVirtual)
 618                 changeReferenceKind(REF_invokeSpecial, REF_invokeVirtual);
 619             else if (getReferenceKind() == REF_invokeInterface)
 620                 // invokeSpecial on a default method
 621                 changeReferenceKind(REF_invokeSpecial, REF_invokeInterface);
 622         }
 623     }
 624     public MemberName asSpecial() {
 625         switch (getReferenceKind()) {
 626         case REF_invokeSpecial:     return this;
 627         case REF_invokeVirtual:     return clone().changeReferenceKind(REF_invokeSpecial, REF_invokeVirtual);
 628         case REF_invokeInterface:   return clone().changeReferenceKind(REF_invokeSpecial, REF_invokeInterface);
 629         case REF_newInvokeSpecial:  return clone().changeReferenceKind(REF_invokeSpecial, REF_newInvokeSpecial);
 630         }
 631         throw new IllegalArgumentException(this.toString());
 632     }
 633     /** If this MN is not REF_newInvokeSpecial, return a clone with that ref. kind.
 634      *  In that case it must already be REF_invokeSpecial.
 635      */
 636     public MemberName asConstructor() {
 637         switch (getReferenceKind()) {
 638         case REF_invokeSpecial:     return clone().changeReferenceKind(REF_newInvokeSpecial, REF_invokeSpecial);
 639         case REF_newInvokeSpecial:  return this;
 640         }
 641         throw new IllegalArgumentException(this.toString());
 642     }
 643     /** If this MN is a REF_invokeSpecial, return a clone with the "normal" kind
 644      *  REF_invokeVirtual; also switch either to REF_invokeInterface if clazz.isInterface.
 645      *  The end result is to get a fully virtualized version of the MN.
 646      *  (Note that resolving in the JVM will sometimes devirtualize, changing
 647      *  REF_invokeVirtual of a final to REF_invokeSpecial, and REF_invokeInterface
 648      *  in some corner cases to either of the previous two; this transform
 649      *  undoes that change under the assumption that it occurred.)
 650      */
 651     public MemberName asNormalOriginal() {
 652         byte normalVirtual = clazz.isInterface() ? REF_invokeInterface : REF_invokeVirtual;
 653         byte refKind = getReferenceKind();
 654         byte newRefKind = refKind;
 655         MemberName result = this;
 656         switch (refKind) {
 657         case REF_invokeInterface:
 658         case REF_invokeVirtual:
 659         case REF_invokeSpecial:
 660             newRefKind = normalVirtual;
 661             break;
 662         }
 663         if (newRefKind == refKind)
 664             return this;
 665         result = clone().changeReferenceKind(newRefKind, refKind);
 666         assert(this.referenceKindIsConsistentWith(result.getReferenceKind()));
 667         return result;
 668     }
 669     /** Create a name for the given reflected constructor.  The resulting name will be in a resolved state. */
 670     @SuppressWarnings("LeakingThisInConstructor")
 671     public MemberName(Constructor<?> ctor) {
 672         Objects.requireNonNull(ctor);
 673         // fill in vmtarget, vmindex while we have ctor in hand:
 674         MethodHandleNatives.init(this, ctor);
 675         assert(isResolved() && this.clazz != null);
 676         this.name = CONSTRUCTOR_NAME;
 677         if (this.type == null)
 678             this.type = new Object[] { void.class, ctor.getParameterTypes() };






 679     }
 680     /** Create a name for the given reflected field.  The resulting name will be in a resolved state.
 681      */
 682     public MemberName(Field fld) {
 683         this(fld, false);
 684     }
 685     @SuppressWarnings("LeakingThisInConstructor")
 686     public MemberName(Field fld, boolean makeSetter) {
 687         Objects.requireNonNull(fld);
 688         // fill in vmtarget, vmindex while we have fld in hand:
 689         MethodHandleNatives.init(this, fld);
 690         assert(isResolved() && this.clazz != null);
 691         this.name = fld.getName();
 692         this.type = fld.getType();
 693         assert((REF_putStatic - REF_getStatic) == (REF_putField - REF_getField));
 694         byte refKind = this.getReferenceKind();
 695         assert(refKind == (isStatic() ? REF_getStatic : REF_getField));
 696         if (makeSetter) {
 697             changeReferenceKind((byte)(refKind + (REF_putStatic - REF_getStatic)), refKind);
 698         }

 799     }
 800 
 801     // Construction from symbolic parts, for queries:
 802     /** Create a field or type name from the given components:
 803      *  Declaring class, name, type, reference kind.
 804      *  The declaring class may be supplied as null if this is to be a bare name and type.
 805      *  The resulting name will in an unresolved state.
 806      */
 807     public MemberName(Class<?> defClass, String name, Class<?> type, byte refKind) {
 808         init(defClass, name, type, flagsMods(IS_FIELD, 0, refKind));
 809         initResolved(false);
 810     }
 811     /** Create a method or constructor name from the given components:
 812      *  Declaring class, name, type, reference kind.
 813      *  It will be a constructor if and only if the name is {@code "<init>"}.
 814      *  The declaring class may be supplied as null if this is to be a bare name and type.
 815      *  The last argument is optional, a boolean which requests REF_invokeSpecial.
 816      *  The resulting name will in an unresolved state.
 817      */
 818     public MemberName(Class<?> defClass, String name, MethodType type, byte refKind) {
 819         int initFlags = (name != null && name.equals(CONSTRUCTOR_NAME) ? IS_CONSTRUCTOR : IS_METHOD);
 820         init(defClass, name, type, flagsMods(initFlags, 0, refKind));
 821         initResolved(false);
 822     }
 823     /** Create a method, constructor, or field name from the given components:
 824      *  Reference kind, declaring class, name, type.
 825      */
 826     public MemberName(byte refKind, Class<?> defClass, String name, Object type) {
 827         int kindFlags;
 828         if (MethodHandleNatives.refKindIsField(refKind)) {
 829             kindFlags = IS_FIELD;
 830             if (!(type instanceof Class))
 831                 throw newIllegalArgumentException("not a field type");
 832         } else if (MethodHandleNatives.refKindIsMethod(refKind)) {
 833             kindFlags = IS_METHOD;
 834             if (!(type instanceof MethodType))
 835                 throw newIllegalArgumentException("not a method type");
 836         } else if (refKind == REF_newInvokeSpecial) {
 837             kindFlags = IS_CONSTRUCTOR;
 838             if (!(type instanceof MethodType) ||
 839                 !CONSTRUCTOR_NAME.equals(name))
 840                 throw newIllegalArgumentException("not a constructor type or name");
 841         } else {
 842             throw newIllegalArgumentException("bad reference kind "+refKind);
 843         }
 844         init(defClass, name, type, flagsMods(kindFlags, 0, refKind));
 845         initResolved(false);
 846     }
 847     /** Query whether this member name is resolved to a non-static, non-final method.
 848      */
 849     public boolean hasReceiverTypeDispatch() {
 850         return MethodHandleNatives.refKindDoesDispatch(getReferenceKind());
 851     }
 852 
 853     /** Query whether this member name is resolved.
 854      *  A resolved member name is one for which the JVM has found
 855      *  a method, constructor, field, or type binding corresponding exactly to the name.
 856      *  (Document?)
 857      */

 940                 if (from instanceof MethodHandles.Lookup lookup) {
 941                     from = lookup.lookupClass();
 942                     m = lookup.lookupClass().getModule();
 943                     plc = lookup.previousLookupClass();
 944                 } else {
 945                     m = ((Class<?>)from).getModule();
 946                     plc = null;
 947                 }
 948                 message += ", from " + from + " (" + m + ")";
 949                 if (plc != null) {
 950                     message += ", previous lookup " +
 951                         plc.getName() + " (" + plc.getModule() + ")";
 952                 }
 953             }
 954         }
 955         return new IllegalAccessException(message);
 956     }
 957     private String message() {
 958         if (isResolved())
 959             return "no access";
 960         else if (isConstructor())
 961             return "no such constructor";
 962         else if (isMethod())
 963             return "no such method";
 964         else
 965             return "no such field";
 966     }
 967     public ReflectiveOperationException makeAccessException() {
 968         String message = message() + ": "+ toString();
 969         ReflectiveOperationException ex;
 970         if (isResolved() || !(resolution instanceof NoSuchMethodError ||
 971                               resolution instanceof NoSuchFieldError))
 972             ex = new IllegalAccessException(message);
 973         else if (isConstructor())
 974             ex = new NoSuchMethodException(message);
 975         else if (isMethod())
 976             ex = new NoSuchMethodException(message);
 977         else
 978             ex = new NoSuchFieldException(message);
 979         if (resolution instanceof Throwable)
 980             ex.initCause((Throwable) resolution);
 981         return ex;
 982     }
 983 
 984     /** Actually making a query requires an access check. */
 985     /*non-public*/
 986     static Factory getFactory() {
 987         return Factory.INSTANCE;
 988     }
 989     /** A factory type for resolving member names with the help of the VM.
 990      *  TBD: Define access-safe public constructors for this factory.
 991      */
 992     /*non-public*/
 993     static class Factory {

1134         /** Return a list of all methods defined by the given class.
1135          *  Super types are searched (for inherited members) if {@code searchSupers} is true.
1136          *  Access checking is performed on behalf of the given {@code lookupClass}.
1137          *  Inaccessible members are not added to the last.
1138          */
1139         public List<MemberName> getMethods(Class<?> defc, boolean searchSupers,
1140                 Class<?> lookupClass) {
1141             return getMethods(defc, searchSupers, null, null, lookupClass);
1142         }
1143         /** Return a list of matching methods defined by the given class.
1144          *  Super types are searched (for inherited members) if {@code searchSupers} is true.
1145          *  Returned methods will match the name (if not null) and the type (if not null).
1146          *  Access checking is performed on behalf of the given {@code lookupClass}.
1147          *  Inaccessible members are not added to the last.
1148          */
1149         public List<MemberName> getMethods(Class<?> defc, boolean searchSupers,
1150                 String name, MethodType type, Class<?> lookupClass) {
1151             int matchFlags = IS_METHOD | (searchSupers ? SEARCH_ALL_SUPERS : 0);
1152             return getMembers(defc, name, type, matchFlags, lookupClass);
1153         }
1154         /** Return a list of all constructors defined by the given class.
1155          *  Access checking is performed on behalf of the given {@code lookupClass}.
1156          *  Inaccessible members are not added to the last.
1157          */
1158         public List<MemberName> getConstructors(Class<?> defc, Class<?> lookupClass) {
1159             return getMembers(defc, null, null, IS_CONSTRUCTOR, lookupClass);
1160         }
1161         /** Return a list of all fields defined by the given class.
1162          *  Super types are searched (for inherited members) if {@code searchSupers} is true.
1163          *  Access checking is performed on behalf of the given {@code lookupClass}.
1164          *  Inaccessible members are not added to the last.
1165          */
1166         public List<MemberName> getFields(Class<?> defc, boolean searchSupers,
1167                 Class<?> lookupClass) {
1168             return getFields(defc, searchSupers, null, null, lookupClass);
1169         }
1170         /** Return a list of all fields defined by the given class.
1171          *  Super types are searched (for inherited members) if {@code searchSupers} is true.
1172          *  Returned fields will match the name (if not null) and the type (if not null).
1173          *  Access checking is performed on behalf of the given {@code lookupClass}.
1174          *  Inaccessible members are not added to the last.
1175          */
1176         public List<MemberName> getFields(Class<?> defc, boolean searchSupers,
1177                 String name, Class<?> type, Class<?> lookupClass) {
1178             int matchFlags = IS_FIELD | (searchSupers ? SEARCH_ALL_SUPERS : 0);
1179             return getMembers(defc, name, type, matchFlags, lookupClass);

   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.invoke;
  27 
  28 import jdk.internal.value.PrimitiveClass;
  29 import sun.invoke.util.BytecodeDescriptor;
  30 import sun.invoke.util.VerifyAccess;
  31 
  32 import java.lang.reflect.Constructor;
  33 import java.lang.reflect.Field;
  34 import java.lang.reflect.Member;
  35 import java.lang.reflect.Method;
  36 import java.lang.reflect.Modifier;
  37 import java.util.ArrayList;
  38 import java.util.Collections;
  39 import java.util.Iterator;
  40 import java.util.List;
  41 import java.util.Objects;
  42 
  43 import static java.lang.invoke.MethodHandleNatives.Constants.*;
  44 import static java.lang.invoke.MethodHandleStatics.newIllegalArgumentException;
  45 import static java.lang.invoke.MethodHandleStatics.newInternalError;
  46 
  47 /**
  48  * A {@code MemberName} is a compact symbolic datum which fully characterizes

 175         }
 176         if (!isInvocable()) {
 177             throw newIllegalArgumentException("not invocable, no method type");
 178         }
 179 
 180         // Get a snapshot of type which doesn't get changed by racing threads.
 181         final Object type = this.type;
 182         if (type instanceof String) {
 183             return (String) type;
 184         } else {
 185             return getMethodType().toMethodDescriptorString();
 186         }
 187     }
 188 
 189     /** Return the actual type under which this method or constructor must be invoked.
 190      *  For non-static methods or constructors, this is the type with a leading parameter,
 191      *  a reference to declaring class.  For static methods, it is the same as the declared type.
 192      */
 193     public MethodType getInvocationType() {
 194         MethodType itype = getMethodOrFieldType();
 195         Class<?> c = PrimitiveClass.isPrimitiveClass(clazz) ? PrimitiveClass.asValueType(clazz) : clazz;
 196         if (isObjectConstructor() && getReferenceKind() == REF_newInvokeSpecial)
 197             return itype.changeReturnType(c);
 198         if (!isStatic())
 199             return itype.insertParameterTypes(0, c);
 200         return itype;
 201     }
 202 
 203     /** Utility method producing the parameter types of the method type. */
 204     public Class<?>[] getParameterTypes() {
 205         return getMethodType().parameterArray();
 206     }
 207 
 208     /** Utility method producing the return type of the method type. */
 209     public Class<?> getReturnType() {
 210         return getMethodType().returnType();
 211     }
 212 
 213     /** Return the declared type of this member, which
 214      *  must be a field or type.
 215      *  If it is a type member, that type itself is returned.
 216      */
 217     public Class<?> getFieldType() {
 218         if (type == null) {
 219             expandFromVM();

 268     }
 269 
 270     /** Return the modifier flags of this member.
 271      *  @see java.lang.reflect.Modifier
 272      */
 273     public int getModifiers() {
 274         return (flags & RECOGNIZED_MODIFIERS);
 275     }
 276 
 277     /** Return the reference kind of this member, or zero if none.
 278      */
 279     public byte getReferenceKind() {
 280         return (byte) ((flags >>> MN_REFERENCE_KIND_SHIFT) & MN_REFERENCE_KIND_MASK);
 281     }
 282     private boolean referenceKindIsConsistent() {
 283         byte refKind = getReferenceKind();
 284         if (refKind == REF_NONE)  return isType();
 285         if (isField()) {
 286             assert(staticIsConsistent());
 287             assert(MethodHandleNatives.refKindIsField(refKind));
 288         } else if (isObjectConstructor()) {
 289             assert(refKind == REF_newInvokeSpecial || refKind == REF_invokeSpecial);
 290         } else if (isMethod()) {
 291             assert(staticIsConsistent());
 292             assert(MethodHandleNatives.refKindIsMethod(refKind));
 293             if (clazz.isInterface())
 294                 assert(refKind == REF_invokeInterface ||
 295                        refKind == REF_invokeStatic    ||
 296                        refKind == REF_invokeSpecial   ||
 297                        refKind == REF_invokeVirtual && isObjectPublicMethod());
 298         } else {
 299             assert(false);
 300         }
 301         return true;
 302     }
 303     private boolean isObjectPublicMethod() {
 304         if (clazz == Object.class)  return true;
 305         MethodType mtype = getMethodType();
 306         if (name.equals("toString") && mtype.returnType() == String.class && mtype.parameterCount() == 0)
 307             return true;
 308         if (name.equals("hashCode") && mtype.returnType() == int.class && mtype.parameterCount() == 0)

 414     private static final int MH_INVOKE_MODS = Modifier.NATIVE | Modifier.FINAL | Modifier.PUBLIC;
 415 
 416     /** Utility method to query the modifier flags of this member. */
 417     public boolean isStatic() {
 418         return Modifier.isStatic(flags);
 419     }
 420     /** Utility method to query the modifier flags of this member. */
 421     public boolean isPublic() {
 422         return Modifier.isPublic(flags);
 423     }
 424     /** Utility method to query the modifier flags of this member. */
 425     public boolean isPrivate() {
 426         return Modifier.isPrivate(flags);
 427     }
 428     /** Utility method to query the modifier flags of this member. */
 429     public boolean isProtected() {
 430         return Modifier.isProtected(flags);
 431     }
 432     /** Utility method to query the modifier flags of this member. */
 433     public boolean isFinal() {
 434         // all fields declared in a value type are effectively final
 435         assert(!clazz.isValue() || !isField() || Modifier.isFinal(flags));
 436         return Modifier.isFinal(flags);
 437     }
 438     /** Utility method to query whether this member or its defining class is final. */
 439     public boolean canBeStaticallyBound() {
 440         return Modifier.isFinal(flags | clazz.getModifiers());
 441     }
 442     /** Utility method to query the modifier flags of this member. */
 443     public boolean isVolatile() {
 444         return Modifier.isVolatile(flags);
 445     }
 446     /** Utility method to query the modifier flags of this member. */
 447     public boolean isAbstract() {
 448         return Modifier.isAbstract(flags);
 449     }
 450     /** Utility method to query the modifier flags of this member. */
 451     public boolean isNative() {
 452         return Modifier.isNative(flags);
 453     }
 454     // let the rest (native, volatile, transient, etc.) be tested via Modifier.isFoo
 455 
 456     // unofficial modifier flags, used by HotSpot:
 457     static final int BRIDGE      = 0x00000040;
 458     static final int VARARGS     = 0x00000080;
 459     static final int SYNTHETIC   = 0x00001000;
 460     static final int ANNOTATION  = 0x00002000;
 461     static final int ENUM        = 0x00004000;
 462 
 463     /** Utility method to query the modifier flags of this member; returns false if the member is not a method. */
 464     public boolean isBridge() {
 465         return testAllFlags(IS_METHOD | BRIDGE);
 466     }
 467     /** Utility method to query the modifier flags of this member; returns false if the member is not a method. */
 468     public boolean isVarargs() {
 469         return testAllFlags(VARARGS) && isInvocable();
 470     }
 471     /** Utility method to query the modifier flags of this member; returns false if the member is not a method. */
 472     public boolean isSynthetic() {
 473         return testAllFlags(SYNTHETIC);
 474     }
 475 
 476     /** Query whether this member is a flattened field */
 477     public boolean isFlattened() { return (flags & MN_FLATTENED) == MN_FLATTENED; }
 478 
 479     /** Query whether this member is a field of a primitive class. */
 480     public boolean isInlineableField()  {
 481         if (isField()) {
 482             Class<?> type = getFieldType();
 483             return PrimitiveClass.isPrimitiveValueType(type) || (type.isValue() && !PrimitiveClass.isPrimitiveClass(type));
 484         }
 485         return false;
 486     }
 487 
 488     static final String CONSTRUCTOR_NAME = "<init>";  // the ever-popular
 489 
 490     // modifiers exported by the JVM:
 491     // modifiers exported by the JVM:
 492     static final int RECOGNIZED_MODIFIERS = 0xFFFF;
 493 
 494     // private flags, not part of RECOGNIZED_MODIFIERS:
 495     static final int
 496             IS_METHOD             = MN_IS_METHOD,              // method (not object constructor)
 497             IS_OBJECT_CONSTRUCTOR = MN_IS_OBJECT_CONSTRUCTOR,  // object constructor
 498             IS_FIELD              = MN_IS_FIELD,               // field
 499             IS_TYPE               = MN_IS_TYPE,                // nested type
 500             CALLER_SENSITIVE      = MN_CALLER_SENSITIVE,       // @CallerSensitive annotation detected
 501             TRUSTED_FINAL         = MN_TRUSTED_FINAL;    // trusted final field
 502 
 503     static final int ALL_ACCESS = Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED;
 504     static final int ALL_KINDS = IS_METHOD | IS_OBJECT_CONSTRUCTOR | IS_FIELD | IS_TYPE;
 505     static final int IS_INVOCABLE = IS_METHOD | IS_OBJECT_CONSTRUCTOR;
 506     static final int IS_FIELD_OR_METHOD = IS_METHOD | IS_FIELD;
 507     static final int SEARCH_ALL_SUPERS = MN_SEARCH_SUPERCLASSES | MN_SEARCH_INTERFACES;
 508 
 509     /** Utility method to query whether this member is a method or constructor. */
 510     public boolean isInvocable() {
 511         return testAnyFlags(IS_INVOCABLE);
 512     }
 513     /** Utility method to query whether this member is a method, constructor, or field. */
 514     public boolean isFieldOrMethod() {
 515         return testAnyFlags(IS_FIELD_OR_METHOD);
 516     }
 517     /** Query whether this member is a method. */
 518     public boolean isMethod() {
 519         return testAllFlags(IS_METHOD);
 520     }
 521     /** Query whether this member is a constructor. */
 522     public boolean isObjectConstructor() {
 523         return testAllFlags(IS_OBJECT_CONSTRUCTOR);
 524     }
 525     /** Query whether this member is an object constructor or static <init> factory */
 526     public boolean isObjectConstructorOrStaticInitMethod() {
 527         return isObjectConstructor() || (getName().equals(CONSTRUCTOR_NAME) && testAllFlags(IS_METHOD));
 528     }
 529     /** Query whether this member is a field. */
 530     public boolean isField() {
 531         return testAllFlags(IS_FIELD);
 532     }
 533     /** Query whether this member is a type. */
 534     public boolean isType() {
 535         return testAllFlags(IS_TYPE);
 536     }
 537     /** Utility method to query whether this member is neither public, private, nor protected. */
 538     public boolean isPackage() {
 539         return !testAnyFlags(ALL_ACCESS);
 540     }
 541     /** Query whether this member has a CallerSensitive annotation. */
 542     public boolean isCallerSensitive() {
 543         return testAllFlags(CALLER_SENSITIVE);
 544     }
 545     /** Query whether this member is a trusted final field. */
 546     public boolean isTrustedFinalField() { return testAllFlags(TRUSTED_FINAL|IS_FIELD); }
 547 

 638                 throw new AbstractMethodError(this.toString());
 639             if (getReferenceKind() == REF_invokeVirtual)
 640                 changeReferenceKind(REF_invokeSpecial, REF_invokeVirtual);
 641             else if (getReferenceKind() == REF_invokeInterface)
 642                 // invokeSpecial on a default method
 643                 changeReferenceKind(REF_invokeSpecial, REF_invokeInterface);
 644         }
 645     }
 646     public MemberName asSpecial() {
 647         switch (getReferenceKind()) {
 648         case REF_invokeSpecial:     return this;
 649         case REF_invokeVirtual:     return clone().changeReferenceKind(REF_invokeSpecial, REF_invokeVirtual);
 650         case REF_invokeInterface:   return clone().changeReferenceKind(REF_invokeSpecial, REF_invokeInterface);
 651         case REF_newInvokeSpecial:  return clone().changeReferenceKind(REF_invokeSpecial, REF_newInvokeSpecial);
 652         }
 653         throw new IllegalArgumentException(this.toString());
 654     }
 655     /** If this MN is not REF_newInvokeSpecial, return a clone with that ref. kind.
 656      *  In that case it must already be REF_invokeSpecial.
 657      */
 658     public MemberName asObjectConstructor() {
 659         switch (getReferenceKind()) {
 660         case REF_invokeSpecial:     return clone().changeReferenceKind(REF_newInvokeSpecial, REF_invokeSpecial);
 661         case REF_newInvokeSpecial:  return this;
 662         }
 663         throw new IllegalArgumentException(this.toString());
 664     }
 665     /** If this MN is a REF_invokeSpecial, return a clone with the "normal" kind
 666      *  REF_invokeVirtual; also switch either to REF_invokeInterface if clazz.isInterface.
 667      *  The end result is to get a fully virtualized version of the MN.
 668      *  (Note that resolving in the JVM will sometimes devirtualize, changing
 669      *  REF_invokeVirtual of a final to REF_invokeSpecial, and REF_invokeInterface
 670      *  in some corner cases to either of the previous two; this transform
 671      *  undoes that change under the assumption that it occurred.)
 672      */
 673     public MemberName asNormalOriginal() {
 674         byte normalVirtual = clazz.isInterface() ? REF_invokeInterface : REF_invokeVirtual;
 675         byte refKind = getReferenceKind();
 676         byte newRefKind = refKind;
 677         MemberName result = this;
 678         switch (refKind) {
 679         case REF_invokeInterface:
 680         case REF_invokeVirtual:
 681         case REF_invokeSpecial:
 682             newRefKind = normalVirtual;
 683             break;
 684         }
 685         if (newRefKind == refKind)
 686             return this;
 687         result = clone().changeReferenceKind(newRefKind, refKind);
 688         assert(this.referenceKindIsConsistentWith(result.getReferenceKind()));
 689         return result;
 690     }
 691     /** Create a name for the given reflected constructor.  The resulting name will be in a resolved state. */
 692     @SuppressWarnings("LeakingThisInConstructor")
 693     public MemberName(Constructor<?> ctor) {
 694         Objects.requireNonNull(ctor);
 695         // fill in vmtarget, vmindex while we have ctor in hand:
 696         MethodHandleNatives.init(this, ctor);
 697         assert(isResolved() && this.clazz != null);
 698         this.name = CONSTRUCTOR_NAME;
 699         if (this.type == null) {
 700             Class<?> rtype = void.class;
 701             if (isStatic()) {  // a static init factory, not a true constructor
 702                 rtype = getDeclaringClass();
 703                 // FIXME: If it's a hidden class, this sig won't work.
 704             }
 705             this.type = new Object[] { rtype, ctor.getParameterTypes() };
 706         }
 707     }
 708     /** Create a name for the given reflected field.  The resulting name will be in a resolved state.
 709      */
 710     public MemberName(Field fld) {
 711         this(fld, false);
 712     }
 713     @SuppressWarnings("LeakingThisInConstructor")
 714     public MemberName(Field fld, boolean makeSetter) {
 715         Objects.requireNonNull(fld);
 716         // fill in vmtarget, vmindex while we have fld in hand:
 717         MethodHandleNatives.init(this, fld);
 718         assert(isResolved() && this.clazz != null);
 719         this.name = fld.getName();
 720         this.type = fld.getType();
 721         assert((REF_putStatic - REF_getStatic) == (REF_putField - REF_getField));
 722         byte refKind = this.getReferenceKind();
 723         assert(refKind == (isStatic() ? REF_getStatic : REF_getField));
 724         if (makeSetter) {
 725             changeReferenceKind((byte)(refKind + (REF_putStatic - REF_getStatic)), refKind);
 726         }

 827     }
 828 
 829     // Construction from symbolic parts, for queries:
 830     /** Create a field or type name from the given components:
 831      *  Declaring class, name, type, reference kind.
 832      *  The declaring class may be supplied as null if this is to be a bare name and type.
 833      *  The resulting name will in an unresolved state.
 834      */
 835     public MemberName(Class<?> defClass, String name, Class<?> type, byte refKind) {
 836         init(defClass, name, type, flagsMods(IS_FIELD, 0, refKind));
 837         initResolved(false);
 838     }
 839     /** Create a method or constructor name from the given components:
 840      *  Declaring class, name, type, reference kind.
 841      *  It will be a constructor if and only if the name is {@code "<init>"}.
 842      *  The declaring class may be supplied as null if this is to be a bare name and type.
 843      *  The last argument is optional, a boolean which requests REF_invokeSpecial.
 844      *  The resulting name will in an unresolved state.
 845      */
 846     public MemberName(Class<?> defClass, String name, MethodType type, byte refKind) {
 847         int initFlags = (name != null && name.equals(CONSTRUCTOR_NAME) && type.returnType() == void.class ? IS_OBJECT_CONSTRUCTOR : IS_METHOD);
 848         init(defClass, name, type, flagsMods(initFlags, 0, refKind));
 849         initResolved(false);
 850     }
 851     /** Create a method, constructor, or field name from the given components:
 852      *  Reference kind, declaring class, name, type.
 853      */
 854     public MemberName(byte refKind, Class<?> defClass, String name, Object type) {
 855         int kindFlags;
 856         if (MethodHandleNatives.refKindIsField(refKind)) {
 857             kindFlags = IS_FIELD;
 858             if (!(type instanceof Class))
 859                 throw newIllegalArgumentException("not a field type");
 860         } else if (MethodHandleNatives.refKindIsMethod(refKind)) {
 861             kindFlags = IS_METHOD;
 862             if (!(type instanceof MethodType))
 863                 throw newIllegalArgumentException("not a method type");
 864         } else if (refKind == REF_newInvokeSpecial) {
 865             kindFlags = IS_OBJECT_CONSTRUCTOR;
 866             if (!(type instanceof MethodType) ||
 867                 !CONSTRUCTOR_NAME.equals(name))
 868                 throw newIllegalArgumentException("not a constructor type or name");
 869         } else {
 870             throw newIllegalArgumentException("bad reference kind "+refKind);
 871         }
 872         init(defClass, name, type, flagsMods(kindFlags, 0, refKind));
 873         initResolved(false);
 874     }
 875     /** Query whether this member name is resolved to a non-static, non-final method.
 876      */
 877     public boolean hasReceiverTypeDispatch() {
 878         return MethodHandleNatives.refKindDoesDispatch(getReferenceKind());
 879     }
 880 
 881     /** Query whether this member name is resolved.
 882      *  A resolved member name is one for which the JVM has found
 883      *  a method, constructor, field, or type binding corresponding exactly to the name.
 884      *  (Document?)
 885      */

 968                 if (from instanceof MethodHandles.Lookup lookup) {
 969                     from = lookup.lookupClass();
 970                     m = lookup.lookupClass().getModule();
 971                     plc = lookup.previousLookupClass();
 972                 } else {
 973                     m = ((Class<?>)from).getModule();
 974                     plc = null;
 975                 }
 976                 message += ", from " + from + " (" + m + ")";
 977                 if (plc != null) {
 978                     message += ", previous lookup " +
 979                         plc.getName() + " (" + plc.getModule() + ")";
 980                 }
 981             }
 982         }
 983         return new IllegalAccessException(message);
 984     }
 985     private String message() {
 986         if (isResolved())
 987             return "no access";
 988         else if (isObjectConstructor())
 989             return "no such constructor";
 990         else if (isMethod())
 991             return "no such method";
 992         else
 993             return "no such field";
 994     }
 995     public ReflectiveOperationException makeAccessException() {
 996         String message = message() + ": "+ toString();
 997         ReflectiveOperationException ex;
 998         if (isResolved() || !(resolution instanceof NoSuchMethodError ||
 999                               resolution instanceof NoSuchFieldError))
1000             ex = new IllegalAccessException(message);
1001         else if (isObjectConstructor())
1002             ex = new NoSuchMethodException(message);
1003         else if (isMethod())
1004             ex = new NoSuchMethodException(message);
1005         else
1006             ex = new NoSuchFieldException(message);
1007         if (resolution instanceof Throwable)
1008             ex.initCause((Throwable) resolution);
1009         return ex;
1010     }
1011 
1012     /** Actually making a query requires an access check. */
1013     /*non-public*/
1014     static Factory getFactory() {
1015         return Factory.INSTANCE;
1016     }
1017     /** A factory type for resolving member names with the help of the VM.
1018      *  TBD: Define access-safe public constructors for this factory.
1019      */
1020     /*non-public*/
1021     static class Factory {

1162         /** Return a list of all methods defined by the given class.
1163          *  Super types are searched (for inherited members) if {@code searchSupers} is true.
1164          *  Access checking is performed on behalf of the given {@code lookupClass}.
1165          *  Inaccessible members are not added to the last.
1166          */
1167         public List<MemberName> getMethods(Class<?> defc, boolean searchSupers,
1168                 Class<?> lookupClass) {
1169             return getMethods(defc, searchSupers, null, null, lookupClass);
1170         }
1171         /** Return a list of matching methods defined by the given class.
1172          *  Super types are searched (for inherited members) if {@code searchSupers} is true.
1173          *  Returned methods will match the name (if not null) and the type (if not null).
1174          *  Access checking is performed on behalf of the given {@code lookupClass}.
1175          *  Inaccessible members are not added to the last.
1176          */
1177         public List<MemberName> getMethods(Class<?> defc, boolean searchSupers,
1178                 String name, MethodType type, Class<?> lookupClass) {
1179             int matchFlags = IS_METHOD | (searchSupers ? SEARCH_ALL_SUPERS : 0);
1180             return getMembers(defc, name, type, matchFlags, lookupClass);
1181         }
1182         /** Return a list of all object constructors defined by the given class.
1183          *  Access checking is performed on behalf of the given {@code lookupClass}.
1184          *  Inaccessible members are not added to the last.
1185          */
1186         public List<MemberName> getObjectConstructors(Class<?> defc, Class<?> lookupClass) {
1187             return getMembers(defc, null, null, IS_OBJECT_CONSTRUCTOR, lookupClass);
1188         }
1189         /** Return a list of all fields defined by the given class.
1190          *  Super types are searched (for inherited members) if {@code searchSupers} is true.
1191          *  Access checking is performed on behalf of the given {@code lookupClass}.
1192          *  Inaccessible members are not added to the last.
1193          */
1194         public List<MemberName> getFields(Class<?> defc, boolean searchSupers,
1195                 Class<?> lookupClass) {
1196             return getFields(defc, searchSupers, null, null, lookupClass);
1197         }
1198         /** Return a list of all fields defined by the given class.
1199          *  Super types are searched (for inherited members) if {@code searchSupers} is true.
1200          *  Returned fields will match the name (if not null) and the type (if not null).
1201          *  Access checking is performed on behalf of the given {@code lookupClass}.
1202          *  Inaccessible members are not added to the last.
1203          */
1204         public List<MemberName> getFields(Class<?> defc, boolean searchSupers,
1205                 String name, Class<?> type, Class<?> lookupClass) {
1206             int matchFlags = IS_FIELD | (searchSupers ? SEARCH_ALL_SUPERS : 0);
1207             return getMembers(defc, name, type, matchFlags, lookupClass);
< prev index next >