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.VerifyAccess;
29
30 import java.lang.reflect.Constructor;
31 import java.lang.reflect.Field;
32 import java.lang.reflect.Member;
33 import java.lang.reflect.Method;
34 import java.lang.reflect.Modifier;
35 import java.util.Objects;
36
37 import static java.lang.invoke.MethodHandleNatives.Constants.*;
38 import static java.lang.invoke.MethodHandleStatics.newIllegalArgumentException;
39 import static java.lang.invoke.MethodHandleStatics.newInternalError;
40
41 /**
42 * A {@code MemberName} is a compact symbolic datum which fully characterizes
43 * a method or field reference.
44 * A member name refers to a field, method, constructor, or member type.
45 * Every member name has a simple name (a string) and a type (either a Class or MethodType).
46 * A member name may also have a non-null declaring class, or it may be simply
47 * a naked name/type pair.
207 // Get a snapshot of type which doesn't get changed by racing threads.
208 final Object type = this.type;
209 if (type instanceof Class<?> cl) {
210 return cl;
211 }
212 }
213
214 // type is not a Class yet. Convert it thread-safely.
215 synchronized (this) {
216 if (type instanceof String sig) {
217 MethodType mtype = MethodType.fromDescriptor("()"+sig, getClassLoader());
218 Class<?> res = mtype.returnType();
219 type = res;
220 }
221 // Make sure type is a Class for racing threads.
222 assert type instanceof Class<?> : "bad field type " + type;
223 }
224 return (Class<?>) type;
225 }
226
227 /** Utility method to produce either the method type or field type of this member. */
228 public Object getType() {
229 return (isInvocable() ? getMethodType() : getFieldType());
230 }
231
232 /** Return the modifier flags of this member.
233 * @see java.lang.reflect.Modifier
234 */
235 public int getModifiers() {
236 return (flags & RECOGNIZED_MODIFIERS);
237 }
238
239 /** Return the reference kind of this member, or zero if none.
240 */
241 public byte getReferenceKind() {
242 return (byte) ((flags >>> MN_REFERENCE_KIND_SHIFT) & MN_REFERENCE_KIND_MASK);
243 }
244 private boolean referenceKindIsConsistent() {
245 byte refKind = getReferenceKind();
246 if (refKind == REF_NONE) return isType();
370 private static final int MH_INVOKE_MODS = Modifier.NATIVE | Modifier.FINAL | Modifier.PUBLIC;
371
372 /** Utility method to query the modifier flags of this member. */
373 public boolean isStatic() {
374 return Modifier.isStatic(flags);
375 }
376 /** Utility method to query the modifier flags of this member. */
377 public boolean isPublic() {
378 return Modifier.isPublic(flags);
379 }
380 /** Utility method to query the modifier flags of this member. */
381 public boolean isPrivate() {
382 return Modifier.isPrivate(flags);
383 }
384 /** Utility method to query the modifier flags of this member. */
385 public boolean isProtected() {
386 return Modifier.isProtected(flags);
387 }
388 /** Utility method to query the modifier flags of this member. */
389 public boolean isFinal() {
390 return Modifier.isFinal(flags);
391 }
392 /** Utility method to query whether this member or its defining class is final. */
393 public boolean canBeStaticallyBound() {
394 return Modifier.isFinal(flags | clazz.getModifiers());
395 }
396 /** Utility method to query the modifier flags of this member. */
397 public boolean isVolatile() {
398 return Modifier.isVolatile(flags);
399 }
400 /** Utility method to query the modifier flags of this member. */
401 public boolean isAbstract() {
402 return Modifier.isAbstract(flags);
403 }
404 /** Utility method to query the modifier flags of this member. */
405 public boolean isNative() {
406 return Modifier.isNative(flags);
407 }
408 // let the rest (native, volatile, transient, etc.) be tested via Modifier.isFoo
409
410 // unofficial modifier flags, used by HotSpot:
411 static final int BRIDGE = 0x00000040;
412 static final int VARARGS = 0x00000080;
413 static final int SYNTHETIC = 0x00001000;
414 static final int ANNOTATION= 0x00002000;
415 static final int ENUM = 0x00004000;
416 /** Utility method to query the modifier flags of this member; returns false if the member is not a method. */
417 public boolean isBridge() {
418 return allFlagsSet(IS_METHOD | BRIDGE);
419 }
420 /** Utility method to query the modifier flags of this member; returns false if the member is not a method. */
421 public boolean isVarargs() {
422 return allFlagsSet(VARARGS) && isInvocable();
423 }
424 /** Utility method to query the modifier flags of this member; returns false if the member is not a method. */
425 public boolean isSynthetic() {
426 return allFlagsSet(SYNTHETIC);
427 }
428
429 static final String CONSTRUCTOR_NAME = "<init>"; // the ever-popular
430
431 // modifiers exported by the JVM:
432 static final int RECOGNIZED_MODIFIERS = 0xFFFF;
433
434 // private flags, not part of RECOGNIZED_MODIFIERS:
435 static final int
436 IS_METHOD = MN_IS_METHOD, // method (not constructor)
437 IS_CONSTRUCTOR = MN_IS_CONSTRUCTOR, // constructor
438 IS_FIELD = MN_IS_FIELD, // field
439 IS_TYPE = MN_IS_TYPE, // nested type
440 CALLER_SENSITIVE = MN_CALLER_SENSITIVE, // @CallerSensitive annotation detected
441 TRUSTED_FINAL = MN_TRUSTED_FINAL; // trusted final field
442
443 static final int ALL_ACCESS = Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED;
444 static final int ALL_KINDS = IS_METHOD | IS_CONSTRUCTOR | IS_FIELD | IS_TYPE;
445 static final int IS_INVOCABLE = IS_METHOD | IS_CONSTRUCTOR;
446
447 /** Utility method to query whether this member is a method or constructor. */
448 public boolean isInvocable() {
449 return anyFlagSet(IS_INVOCABLE);
450 }
451 /** Query whether this member is a method. */
452 public boolean isMethod() {
453 return allFlagsSet(IS_METHOD);
454 }
455 /** Query whether this member is a constructor. */
456 public boolean isConstructor() {
457 return allFlagsSet(IS_CONSTRUCTOR);
458 }
459 /** Query whether this member is a field. */
460 public boolean isField() {
461 return allFlagsSet(IS_FIELD);
738 }
739
740 // Construction from symbolic parts, for queries:
741 /** Create a field or type name from the given components:
742 * Declaring class, name, type, reference kind.
743 * The declaring class may be supplied as null if this is to be a bare name and type.
744 * The resulting name will in an unresolved state.
745 */
746 public MemberName(Class<?> defClass, String name, Class<?> type, byte refKind) {
747 init(defClass, name, type, flagsMods(IS_FIELD, 0, refKind));
748 initResolved(false);
749 }
750 /** Create a method or constructor name from the given components:
751 * Declaring class, name, type, reference kind.
752 * It will be a constructor if and only if the name is {@code "<init>"}.
753 * The declaring class may be supplied as null if this is to be a bare name and type.
754 * The last argument is optional, a boolean which requests REF_invokeSpecial.
755 * The resulting name will in an unresolved state.
756 */
757 public MemberName(Class<?> defClass, String name, MethodType type, byte refKind) {
758 int initFlags = (name != null && name.equals(CONSTRUCTOR_NAME) ? IS_CONSTRUCTOR : IS_METHOD);
759 init(defClass, name, type, flagsMods(initFlags, 0, refKind));
760 initResolved(false);
761 }
762 /** Create a method, constructor, or field name from the given components:
763 * Reference kind, declaring class, name, type.
764 */
765 public MemberName(byte refKind, Class<?> defClass, String name, Object type) {
766 int kindFlags;
767 if (MethodHandleNatives.refKindIsField(refKind)) {
768 kindFlags = IS_FIELD;
769 if (!(type instanceof Class))
770 throw newIllegalArgumentException("not a field type");
771 } else if (MethodHandleNatives.refKindIsMethod(refKind)) {
772 kindFlags = IS_METHOD;
773 if (!(type instanceof MethodType))
774 throw newIllegalArgumentException("not a method type");
775 } else if (refKind == REF_newInvokeSpecial) {
776 kindFlags = IS_CONSTRUCTOR;
777 if (!(type instanceof MethodType) ||
778 !CONSTRUCTOR_NAME.equals(name))
|
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.CheckedType;
29 import jdk.internal.value.NormalCheckedType;
30 import jdk.internal.value.NullRestrictedCheckedType;
31 import sun.invoke.util.VerifyAccess;
32
33 import java.lang.reflect.Constructor;
34 import java.lang.reflect.Field;
35 import java.lang.reflect.Member;
36 import java.lang.reflect.Method;
37 import java.lang.reflect.Modifier;
38 import java.util.Objects;
39
40 import static java.lang.invoke.MethodHandleNatives.Constants.*;
41 import static java.lang.invoke.MethodHandleStatics.newIllegalArgumentException;
42 import static java.lang.invoke.MethodHandleStatics.newInternalError;
43
44 /**
45 * A {@code MemberName} is a compact symbolic datum which fully characterizes
46 * a method or field reference.
47 * A member name refers to a field, method, constructor, or member type.
48 * Every member name has a simple name (a string) and a type (either a Class or MethodType).
49 * A member name may also have a non-null declaring class, or it may be simply
50 * a naked name/type pair.
210 // Get a snapshot of type which doesn't get changed by racing threads.
211 final Object type = this.type;
212 if (type instanceof Class<?> cl) {
213 return cl;
214 }
215 }
216
217 // type is not a Class yet. Convert it thread-safely.
218 synchronized (this) {
219 if (type instanceof String sig) {
220 MethodType mtype = MethodType.fromDescriptor("()"+sig, getClassLoader());
221 Class<?> res = mtype.returnType();
222 type = res;
223 }
224 // Make sure type is a Class for racing threads.
225 assert type instanceof Class<?> : "bad field type " + type;
226 }
227 return (Class<?>) type;
228 }
229
230 /**
231 * Return {@code CheckedType} representing the type of this member.
232 */
233 public CheckedType getCheckedFieldType() {
234 return isNullRestricted() ? NullRestrictedCheckedType.of(getFieldType())
235 : NormalCheckedType.of(getFieldType());
236 }
237
238 /** Utility method to produce either the method type or field type of this member. */
239 public Object getType() {
240 return (isInvocable() ? getMethodType() : getFieldType());
241 }
242
243 /** Return the modifier flags of this member.
244 * @see java.lang.reflect.Modifier
245 */
246 public int getModifiers() {
247 return (flags & RECOGNIZED_MODIFIERS);
248 }
249
250 /** Return the reference kind of this member, or zero if none.
251 */
252 public byte getReferenceKind() {
253 return (byte) ((flags >>> MN_REFERENCE_KIND_SHIFT) & MN_REFERENCE_KIND_MASK);
254 }
255 private boolean referenceKindIsConsistent() {
256 byte refKind = getReferenceKind();
257 if (refKind == REF_NONE) return isType();
381 private static final int MH_INVOKE_MODS = Modifier.NATIVE | Modifier.FINAL | Modifier.PUBLIC;
382
383 /** Utility method to query the modifier flags of this member. */
384 public boolean isStatic() {
385 return Modifier.isStatic(flags);
386 }
387 /** Utility method to query the modifier flags of this member. */
388 public boolean isPublic() {
389 return Modifier.isPublic(flags);
390 }
391 /** Utility method to query the modifier flags of this member. */
392 public boolean isPrivate() {
393 return Modifier.isPrivate(flags);
394 }
395 /** Utility method to query the modifier flags of this member. */
396 public boolean isProtected() {
397 return Modifier.isProtected(flags);
398 }
399 /** Utility method to query the modifier flags of this member. */
400 public boolean isFinal() {
401 // all fields declared in a value type are effectively final
402 assert(!clazz.isValue() || !isField() || Modifier.isFinal(flags));
403 return Modifier.isFinal(flags);
404 }
405 /** Utility method to query whether this member or its defining class is final. */
406 public boolean canBeStaticallyBound() {
407 return Modifier.isFinal(flags | clazz.getModifiers());
408 }
409 /** Utility method to query the modifier flags of this member. */
410 public boolean isVolatile() {
411 return Modifier.isVolatile(flags);
412 }
413 /** Utility method to query the modifier flags of this member. */
414 public boolean isAbstract() {
415 return Modifier.isAbstract(flags);
416 }
417 /** Utility method to query the modifier flags of this member. */
418 public boolean isNative() {
419 return Modifier.isNative(flags);
420 }
421 // let the rest (native, volatile, transient, etc.) be tested via Modifier.isFoo
422
423 // unofficial modifier flags, used by HotSpot:
424 static final int BRIDGE = 0x00000040;
425 static final int VARARGS = 0x00000080;
426 static final int SYNTHETIC = 0x00001000;
427 static final int ANNOTATION = 0x00002000;
428 static final int ENUM = 0x00004000;
429
430 /** Utility method to query the modifier flags of this member; returns false if the member is not a method. */
431 public boolean isBridge() {
432 return allFlagsSet(IS_METHOD | BRIDGE);
433 }
434 /** Utility method to query the modifier flags of this member; returns false if the member is not a method. */
435 public boolean isVarargs() {
436 return allFlagsSet(VARARGS) && isInvocable();
437 }
438 /** Utility method to query the modifier flags of this member; returns false if the member is not a method. */
439 public boolean isSynthetic() {
440 return allFlagsSet(SYNTHETIC);
441 }
442
443 /** Query whether this member is a flattened field */
444 public boolean isFlat() { return (flags & MN_FLAT_FIELD) == MN_FLAT_FIELD; }
445
446 /** Query whether this member is a null-restricted field */
447 public boolean isNullRestricted() { return (flags & MN_NULL_RESTRICTED) == MN_NULL_RESTRICTED; }
448
449 static final String CONSTRUCTOR_NAME = "<init>";
450
451 // modifiers exported by the JVM:
452 static final int RECOGNIZED_MODIFIERS = 0xFFFF;
453
454 // private flags, not part of RECOGNIZED_MODIFIERS:
455 static final int
456 IS_METHOD = MN_IS_METHOD, // method (not constructor)
457 IS_CONSTRUCTOR = MN_IS_CONSTRUCTOR, // constructor
458 IS_FIELD = MN_IS_FIELD, // field
459 IS_TYPE = MN_IS_TYPE, // nested type
460 CALLER_SENSITIVE = MN_CALLER_SENSITIVE, // @CallerSensitive annotation detected
461 TRUSTED_FINAL = MN_TRUSTED_FINAL; // trusted final field
462
463 static final int ALL_ACCESS = Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED;
464 static final int ALL_KINDS = IS_METHOD | IS_CONSTRUCTOR | IS_FIELD | IS_TYPE;
465 static final int IS_INVOCABLE = IS_METHOD | IS_CONSTRUCTOR;
466
467 /** Utility method to query whether this member is a method or constructor. */
468 public boolean isInvocable() {
469 return anyFlagSet(IS_INVOCABLE);
470 }
471 /** Query whether this member is a method. */
472 public boolean isMethod() {
473 return allFlagsSet(IS_METHOD);
474 }
475 /** Query whether this member is a constructor. */
476 public boolean isConstructor() {
477 return allFlagsSet(IS_CONSTRUCTOR);
478 }
479 /** Query whether this member is a field. */
480 public boolean isField() {
481 return allFlagsSet(IS_FIELD);
758 }
759
760 // Construction from symbolic parts, for queries:
761 /** Create a field or type name from the given components:
762 * Declaring class, name, type, reference kind.
763 * The declaring class may be supplied as null if this is to be a bare name and type.
764 * The resulting name will in an unresolved state.
765 */
766 public MemberName(Class<?> defClass, String name, Class<?> type, byte refKind) {
767 init(defClass, name, type, flagsMods(IS_FIELD, 0, refKind));
768 initResolved(false);
769 }
770 /** Create a method or constructor name from the given components:
771 * Declaring class, name, type, reference kind.
772 * It will be a constructor if and only if the name is {@code "<init>"}.
773 * The declaring class may be supplied as null if this is to be a bare name and type.
774 * The last argument is optional, a boolean which requests REF_invokeSpecial.
775 * The resulting name will in an unresolved state.
776 */
777 public MemberName(Class<?> defClass, String name, MethodType type, byte refKind) {
778 int initFlags = CONSTRUCTOR_NAME.equals(name) ? IS_CONSTRUCTOR : IS_METHOD;
779 init(defClass, name, type, flagsMods(initFlags, 0, refKind));
780 initResolved(false);
781 }
782 /** Create a method, constructor, or field name from the given components:
783 * Reference kind, declaring class, name, type.
784 */
785 public MemberName(byte refKind, Class<?> defClass, String name, Object type) {
786 int kindFlags;
787 if (MethodHandleNatives.refKindIsField(refKind)) {
788 kindFlags = IS_FIELD;
789 if (!(type instanceof Class))
790 throw newIllegalArgumentException("not a field type");
791 } else if (MethodHandleNatives.refKindIsMethod(refKind)) {
792 kindFlags = IS_METHOD;
793 if (!(type instanceof MethodType))
794 throw newIllegalArgumentException("not a method type");
795 } else if (refKind == REF_newInvokeSpecial) {
796 kindFlags = IS_CONSTRUCTOR;
797 if (!(type instanceof MethodType) ||
798 !CONSTRUCTOR_NAME.equals(name))
|