< prev index next >

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

Print this page

 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);

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

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

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

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

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

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

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