81 /** Return the declaring class of this member. 82 * In the case of a bare name and type, the declaring class will be null. 83 */ 84 public Class<?> getDeclaringClass() { 85 return clazz; 86 } 87 88 /** Utility method producing the class loader of the declaring class. */ 89 public ClassLoader getClassLoader() { 90 return clazz.getClassLoader(); 91 } 92 93 /** Return the simple name of this member. 94 * For a type, it is the same as {@link Class#getSimpleName}. 95 * For a method or field, it is the simple name of the member. 96 * For a constructor, it is always {@code "<init>"}. 97 */ 98 public String getName() { 99 if (name == null) { 100 expandFromVM(); 101 if (name == null) return null; 102 } 103 return name; 104 } 105 106 public MethodType getMethodOrFieldType() { 107 if (isInvocable()) 108 return getMethodType(); 109 if (isGetter()) 110 return MethodType.methodType(getFieldType()); 111 if (isSetter()) 112 return MethodType.methodType(void.class, getFieldType()); 113 throw new InternalError("not a method or field: "+this); 114 } 115 116 /** Return the declared type of this member, which 117 * must be a method or constructor. 118 */ 119 public MethodType getMethodType() { 120 if (type == null) { 121 expandFromVM(); 122 if (type == null) return null; 123 } 124 if (!isInvocable()) 125 throw newIllegalArgumentException("not invocable, no method type"); 126 if (type instanceof MethodType) { 127 return (MethodType) type; 128 } 129 if (type instanceof String) { 130 String sig = (String) type; 131 MethodType res = MethodType.fromMethodDescriptorString(sig, getClassLoader()); 132 this.type = res; 133 return res; 134 } 135 if (type instanceof Object[]) { 136 Object[] typeInfo = (Object[]) type; 137 Class<?>[] ptypes = (Class<?>[]) typeInfo[1]; 138 Class<?> rtype = (Class<?>) typeInfo[0]; 139 MethodType res = MethodType.methodType(rtype, ptypes); 140 this.type = res; 141 return res; 142 } 143 throw new InternalError("bad method type "+type); 144 } 145 146 /** Return the actual type under which this method or constructor must be invoked. 147 * For non-static methods or constructors, this is the type with a leading parameter, 148 * a reference to declaring class. For static methods, it is the same as the declared type. 149 */ 150 public MethodType getInvocationType() { 151 MethodType itype = getMethodOrFieldType(); 152 if (isConstructor() && getReferenceKind() == REF_newInvokeSpecial) 153 return itype.changeReturnType(clazz); 154 if (!isStatic()) 155 return itype.insertParameterTypes(0, clazz); 156 return itype; 157 } 158 159 /** Utility method producing the parameter types of the method type. */ 160 public Class<?>[] getParameterTypes() { 161 return getMethodType().parameterArray(); 162 } 163 164 /** Utility method producing the return type of the method type. */ 165 public Class<?> getReturnType() { 166 return getMethodType().returnType(); 167 } 168 169 /** Return the declared type of this member, which 170 * must be a field or type. 171 * If it is a type member, that type itself is returned. 172 */ 173 public Class<?> getFieldType() { 174 if (type == null) { 175 expandFromVM(); 176 if (type == null) return null; 177 } 178 if (isInvocable()) 179 throw newIllegalArgumentException("not a field or nested class, no simple type"); 180 if (type instanceof Class<?>) { 181 return (Class<?>) type; 182 } 183 if (type instanceof String) { 184 String sig = (String) type; 185 MethodType mtype = MethodType.fromMethodDescriptorString("()"+sig, getClassLoader()); 186 Class<?> res = mtype.returnType(); 187 this.type = res; 188 return res; 189 } 190 throw new InternalError("bad field type "+type); 191 } 192 193 /** Utility method to produce either the method type or field type of this member. */ 194 public Object getType() { 195 return (isInvocable() ? getMethodType() : getFieldType()); 196 } 197 198 /** Utility method to produce the signature of this member, 199 * used within the class file format to describe its type. 200 */ 201 public String getSignature() { 202 if (type == null) { 203 expandFromVM(); 204 if (type == null) return null; 205 } 206 if (type instanceof String) 207 return (String) type; 208 if (isInvocable()) 209 return BytecodeDescriptor.unparse(getMethodType()); 210 else 211 return BytecodeDescriptor.unparse(getFieldType()); 212 } 213 214 /** Return the modifier flags of this member. 215 * @see java.lang.reflect.Modifier 216 */ 217 public int getModifiers() { 218 return (flags & RECOGNIZED_MODIFIERS); 219 } 220 221 /** Return the reference kind of this member, or zero if none. 222 */ 223 public byte getReferenceKind() { 224 return (byte) ((flags >>> MN_REFERENCE_KIND_SHIFT) & MN_REFERENCE_KIND_MASK); 225 } 226 private boolean referenceKindIsConsistent() { 227 byte refKind = getReferenceKind(); 446 public boolean isAccessibleFrom(Class<?> lookupClass) { 447 return VerifyAccess.isMemberAccessible(this.getDeclaringClass(), this.getDeclaringClass(), flags, 448 lookupClass, ALL_ACCESS|MethodHandles.Lookup.PACKAGE); 449 } 450 451 /** Initialize a query. It is not resolved. */ 452 private void init(Class<?> defClass, String name, Object type, int flags) { 453 // defining class is allowed to be null (for a naked name/type pair) 454 //name.toString(); // null check 455 //type.equals(type); // null check 456 // fill in fields: 457 this.clazz = defClass; 458 this.name = name; 459 this.type = type; 460 this.flags = flags; 461 assert(testAnyFlags(ALL_KINDS)); 462 assert(this.resolution == null); // nobody should have touched this yet 463 //assert(referenceKindIsConsistent()); // do this after resolution 464 } 465 466 private void expandFromVM() { 467 if (!isResolved()) return; 468 if (type instanceof Object[]) 469 type = null; // don't saddle JVM w/ typeInfo 470 MethodHandleNatives.expand(this); 471 } 472 473 // Capturing information from the Core Reflection API: 474 private static int flagsMods(int flags, int mods, byte refKind) { 475 assert((flags & RECOGNIZED_MODIFIERS) == 0); 476 assert((mods & ~RECOGNIZED_MODIFIERS) == 0); 477 assert((refKind & ~MN_REFERENCE_KIND_MASK) == 0); 478 return flags | mods | (refKind << MN_REFERENCE_KIND_SHIFT); 479 } 480 /** Create a name for the given reflected method. The resulting name will be in a resolved state. */ 481 public MemberName(Method m) { 482 this(m, false); 483 } 484 @SuppressWarnings("LeakingThisInConstructor") 485 public MemberName(Method m, boolean wantSpecial) { 486 m.getClass(); // NPE check 487 // fill in vmtarget, vmindex while we have m in hand: 488 MethodHandleNatives.init(this, m); 489 if (clazz == null) { // MHN.init failed | 81 /** Return the declaring class of this member. 82 * In the case of a bare name and type, the declaring class will be null. 83 */ 84 public Class<?> getDeclaringClass() { 85 return clazz; 86 } 87 88 /** Utility method producing the class loader of the declaring class. */ 89 public ClassLoader getClassLoader() { 90 return clazz.getClassLoader(); 91 } 92 93 /** Return the simple name of this member. 94 * For a type, it is the same as {@link Class#getSimpleName}. 95 * For a method or field, it is the simple name of the member. 96 * For a constructor, it is always {@code "<init>"}. 97 */ 98 public String getName() { 99 if (name == null) { 100 expandFromVM(); 101 if (name == null) { 102 return null; 103 } 104 } 105 return name; 106 } 107 108 public MethodType getMethodOrFieldType() { 109 if (isInvocable()) 110 return getMethodType(); 111 if (isGetter()) 112 return MethodType.methodType(getFieldType()); 113 if (isSetter()) 114 return MethodType.methodType(void.class, getFieldType()); 115 throw new InternalError("not a method or field: "+this); 116 } 117 118 /** Return the declared type of this member, which 119 * must be a method or constructor. 120 */ 121 public MethodType getMethodType() { 122 if (type == null) { 123 expandFromVM(); 124 if (type == null) { 125 return null; 126 } 127 } 128 if (!isInvocable()) { 129 throw newIllegalArgumentException("not invocable, no method type"); 130 } 131 132 final Object typeSnapshot = type; 133 if (typeSnapshot instanceof MethodType) { 134 return (MethodType) typeSnapshot; 135 } 136 137 // type is not a MethodType yet. Convert it thread-safely. 138 synchronized (this) { 139 if (type instanceof String) { 140 String sig = (String) type; 141 MethodType res = MethodType.fromMethodDescriptorString(sig, getClassLoader()); 142 type = res; 143 } else if (type instanceof Object[]) { 144 Object[] typeInfo = (Object[]) type; 145 Class<?>[] ptypes = (Class<?>[]) typeInfo[1]; 146 Class<?> rtype = (Class<?>) typeInfo[0]; 147 MethodType res = MethodType.methodType(rtype, ptypes); 148 type = res; 149 } 150 // Make sure type is a MethodType for racing threads. 151 assert type instanceof MethodType : "bad method type " + type; 152 } 153 return (MethodType) type; 154 } 155 156 /** Return the actual type under which this method or constructor must be invoked. 157 * For non-static methods or constructors, this is the type with a leading parameter, 158 * a reference to declaring class. For static methods, it is the same as the declared type. 159 */ 160 public MethodType getInvocationType() { 161 MethodType itype = getMethodOrFieldType(); 162 if (isConstructor() && getReferenceKind() == REF_newInvokeSpecial) 163 return itype.changeReturnType(clazz); 164 if (!isStatic()) 165 return itype.insertParameterTypes(0, clazz); 166 return itype; 167 } 168 169 /** Utility method producing the parameter types of the method type. */ 170 public Class<?>[] getParameterTypes() { 171 return getMethodType().parameterArray(); 172 } 173 174 /** Utility method producing the return type of the method type. */ 175 public Class<?> getReturnType() { 176 return getMethodType().returnType(); 177 } 178 179 /** Return the declared type of this member, which 180 * must be a field or type. 181 * If it is a type member, that type itself is returned. 182 */ 183 public Class<?> getFieldType() { 184 if (type == null) { 185 expandFromVM(); 186 if (type == null) { 187 return null; 188 } 189 } 190 if (isInvocable()) { 191 throw newIllegalArgumentException("not a field or nested class, no simple type"); 192 } 193 194 final Object typeSnapshot = type; 195 if (typeSnapshot instanceof Class<?>) { 196 return (Class<?>) typeSnapshot; 197 } 198 199 // type is not a Class yet. Convert it thread-safely. 200 synchronized (this) { 201 if (type instanceof String) { 202 String sig = (String) type; 203 MethodType mtype = MethodType.fromMethodDescriptorString("()"+sig, getClassLoader()); 204 Class<?> res = mtype.returnType(); 205 type = res; 206 } 207 // Make sure type is a Class for racing threads. 208 assert type instanceof Class<?> : "bad field type " + type; 209 } 210 return (Class<?>) type; 211 } 212 213 /** Utility method to produce either the method type or field type of this member. */ 214 public Object getType() { 215 return (isInvocable() ? getMethodType() : getFieldType()); 216 } 217 218 /** Utility method to produce the signature of this member, 219 * used within the class file format to describe its type. 220 */ 221 public String getSignature() { 222 if (type == null) { 223 expandFromVM(); 224 if (type == null) { 225 return null; 226 } 227 } 228 if (isInvocable()) 229 return BytecodeDescriptor.unparse(getMethodType()); 230 else 231 return BytecodeDescriptor.unparse(getFieldType()); 232 } 233 234 /** Return the modifier flags of this member. 235 * @see java.lang.reflect.Modifier 236 */ 237 public int getModifiers() { 238 return (flags & RECOGNIZED_MODIFIERS); 239 } 240 241 /** Return the reference kind of this member, or zero if none. 242 */ 243 public byte getReferenceKind() { 244 return (byte) ((flags >>> MN_REFERENCE_KIND_SHIFT) & MN_REFERENCE_KIND_MASK); 245 } 246 private boolean referenceKindIsConsistent() { 247 byte refKind = getReferenceKind(); 466 public boolean isAccessibleFrom(Class<?> lookupClass) { 467 return VerifyAccess.isMemberAccessible(this.getDeclaringClass(), this.getDeclaringClass(), flags, 468 lookupClass, ALL_ACCESS|MethodHandles.Lookup.PACKAGE); 469 } 470 471 /** Initialize a query. It is not resolved. */ 472 private void init(Class<?> defClass, String name, Object type, int flags) { 473 // defining class is allowed to be null (for a naked name/type pair) 474 //name.toString(); // null check 475 //type.equals(type); // null check 476 // fill in fields: 477 this.clazz = defClass; 478 this.name = name; 479 this.type = type; 480 this.flags = flags; 481 assert(testAnyFlags(ALL_KINDS)); 482 assert(this.resolution == null); // nobody should have touched this yet 483 //assert(referenceKindIsConsistent()); // do this after resolution 484 } 485 486 /** 487 * Calls down to the VM to fill in the fields. This method is 488 * synchronized to avoid racing calls. 489 */ 490 private void expandFromVM() { 491 if (type != null) { 492 return; 493 } 494 if (!isResolved()) { 495 return; 496 } 497 MethodHandleNatives.expand(this); 498 } 499 500 // Capturing information from the Core Reflection API: 501 private static int flagsMods(int flags, int mods, byte refKind) { 502 assert((flags & RECOGNIZED_MODIFIERS) == 0); 503 assert((mods & ~RECOGNIZED_MODIFIERS) == 0); 504 assert((refKind & ~MN_REFERENCE_KIND_MASK) == 0); 505 return flags | mods | (refKind << MN_REFERENCE_KIND_SHIFT); 506 } 507 /** Create a name for the given reflected method. The resulting name will be in a resolved state. */ 508 public MemberName(Method m) { 509 this(m, false); 510 } 511 @SuppressWarnings("LeakingThisInConstructor") 512 public MemberName(Method m, boolean wantSpecial) { 513 m.getClass(); // NPE check 514 // fill in vmtarget, vmindex while we have m in hand: 515 MethodHandleNatives.init(this, m); 516 if (clazz == null) { // MHN.init failed |