/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* A {@code MemberName} is a compact symbolic datum which fully characterizes
* a method or field reference.
* A member name refers to a field, method, constructor, or member type.
* Every member name has a simple name (a string) and a type (either a Class or MethodType).
* A member name may also have a non-null declaring class, or it may be simply
* A member name may also have non-zero modifier flags.
* Finally, a member name may be either resolved or unresolved.
* If it is resolved, the existence of the named
* <p>
* Whether resolved or not, a member name provides no access rights or
* invocation capability to its possessor. It is merely a compact
* representation of all symbolic information necessary to link to
* and properly use the named member.
* <p>
* When resolved, a member name's internal implementation may include references to JVM metadata.
* This representation is stateless and only decriptive.
* It provides no private information and no capability to use the member.
* <p>
* By contrast, a {@linkplain java.lang.reflect.Method} contains fuller information
* about the internals of a method (except its bytecodes) and also
* allows invocation. A MemberName is much lighter than a Method,
* since it contains about 7 fields to the 16 of Method (plus its sub-arrays),
* and those seven fields omit much of the information in Method.
* @author jrose
*/
//@Injected JVM_Method* vmtarget;
//@Injected int vmindex;
/** Return the declaring class of this member.
* In the case of a bare name and type, the declaring class will be null.
*/
return clazz;
}
/** Utility method producing the class loader of the declaring class. */
return clazz.getClassLoader();
}
/** Return the simple name of this member.
* For a type, it is the same as {@link Class#getSimpleName}.
* For a method or field, it is the simple name of the member.
* For a constructor, it is always {@code "<init>"}.
*/
expandFromVM();
}
return name;
}
if (isInvocable())
return getMethodType();
if (isGetter())
if (isSetter())
throw new InternalError("not a method or field: "+this);
}
/** Return the declared type of this member, which
* must be a method or constructor.
*/
expandFromVM();
}
if (!isInvocable())
throw newIllegalArgumentException("not invocable, no method type");
if (type instanceof MethodType) {
return (MethodType) type;
}
return res;
}
return res;
}
}
/** Return the actual type under which this method or constructor must be invoked.
* For non-static methods or constructors, this is the type with a leading parameter,
* a reference to declaring class. For static methods, it is the same as the declared type.
*/
if (!isStatic())
return itype;
}
/** Utility method producing the parameter types of the method type. */
return getMethodType().parameterArray();
}
/** Utility method producing the return type of the method type. */
return getMethodType().returnType();
}
/** Return the declared type of this member, which
* must be a field or type.
* If it is a type member, that type itself is returned.
*/
expandFromVM();
}
if (isInvocable())
throw newIllegalArgumentException("not a field or nested class, no simple type");
}
return res;
}
}
/** Utility method to produce either the method type or field type of this member. */
}
/** Utility method to produce the signature of this member,
* used within the class file format to describe its type.
*/
expandFromVM();
}
if (isInvocable())
else
}
/** Return the modifier flags of this member.
* @see java.lang.reflect.Modifier
*/
public int getModifiers() {
return (flags & RECOGNIZED_MODIFIERS);
}
/** Return the reference kind of this member, or zero if none.
*/
public byte getReferenceKind() {
}
private boolean referenceKindIsConsistent() {
byte refKind = getReferenceKind();
if (isField()) {
assert(staticIsConsistent());
} else if (isConstructor()) {
} else if (isMethod()) {
assert(staticIsConsistent());
if (clazz.isInterface())
assert(refKind == REF_invokeInterface ||
} else {
assert(false);
}
return true;
}
private boolean isObjectPublicMethod() {
return true;
return true;
if (name.equals("equals") && mtype.returnType() == boolean.class && mtype.parameterCount() == 1 && mtype.parameterType(0) == Object.class)
return true;
return false;
}
int refKind = getReferenceKind();
if (refKind == originalRefKind) return true;
switch (originalRefKind) {
case REF_invokeInterface:
// Looking up an interface method, can get (e.g.) Object.hashCode
assert(refKind == REF_invokeVirtual ||
refKind == REF_invokeSpecial) : this;
return true;
case REF_invokeVirtual:
case REF_newInvokeSpecial:
// Looked up a virtual, can get (e.g.) final String.hashCode.
assert(refKind == REF_invokeSpecial) : this;
return true;
}
assert(false) : this;
return true;
}
private boolean staticIsConsistent() {
byte refKind = getReferenceKind();
}
private boolean vminfoIsConsistent() {
byte refKind = getReferenceKind();
assert(isResolved()); // else don't call
} else {
else
}
return true;
}
assert(getReferenceKind() == oldKind);
// if (isConstructor() && refKind != REF_newInvokeSpecial)
// flags += (IS_METHOD - IS_CONSTRUCTOR);
// else if (refKind == REF_newInvokeSpecial && isMethod())
// flags += (IS_CONSTRUCTOR - IS_METHOD);
return this;
}
}
}
}
/** Utility method to query if this member is a method handle invocation (invoke or invokeExact). */
public boolean isMethodHandleInvoke() {
clazz == MethodHandle.class) {
}
return false;
}
/** Utility method to query the modifier flags of this member. */
public boolean isStatic() {
}
/** Utility method to query the modifier flags of this member. */
public boolean isPublic() {
}
/** Utility method to query the modifier flags of this member. */
public boolean isPrivate() {
}
/** Utility method to query the modifier flags of this member. */
public boolean isProtected() {
}
/** Utility method to query the modifier flags of this member. */
public boolean isFinal() {
}
/** Utility method to query whether this member or its defining class is final. */
public boolean canBeStaticallyBound() {
}
/** Utility method to query the modifier flags of this member. */
public boolean isVolatile() {
}
/** Utility method to query the modifier flags of this member. */
public boolean isAbstract() {
}
/** Utility method to query the modifier flags of this member. */
public boolean isNative() {
}
// let the rest (native, volatile, transient, etc.) be tested via Modifier.isFoo
// unofficial modifier flags, used by HotSpot:
/** Utility method to query the modifier flags of this member; returns false if the member is not a method. */
public boolean isBridge() {
}
/** Utility method to query the modifier flags of this member; returns false if the member is not a method. */
public boolean isVarargs() {
}
/** Utility method to query the modifier flags of this member; returns false if the member is not a method. */
public boolean isSynthetic() {
return testAllFlags(SYNTHETIC);
}
// modifiers exported by the JVM:
// private flags, not part of RECOGNIZED_MODIFIERS:
static final int
/** Utility method to query whether this member is a method or constructor. */
public boolean isInvocable() {
return testAnyFlags(IS_INVOCABLE);
}
/** Utility method to query whether this member is a method, constructor, or field. */
public boolean isFieldOrMethod() {
return testAnyFlags(IS_FIELD_OR_METHOD);
}
/** Query whether this member is a method. */
public boolean isMethod() {
return testAllFlags(IS_METHOD);
}
/** Query whether this member is a constructor. */
public boolean isConstructor() {
return testAllFlags(IS_CONSTRUCTOR);
}
/** Query whether this member is a field. */
public boolean isField() {
return testAllFlags(IS_FIELD);
}
/** Query whether this member is a type. */
public boolean isType() {
return testAllFlags(IS_TYPE);
}
/** Utility method to query whether this member is neither public, private, nor protected. */
public boolean isPackage() {
return !testAnyFlags(ALL_ACCESS);
}
/** Utility method to query whether this member is annotated with @CallerSensitive. */
public boolean isCallerSensitive() {
return testAllFlags(IS_CALLER_SENSITIVE);
}
/** Utility method to query whether this member is accessible from a given lookup class. */
}
/** Initialize a query. It is not resolved. */
//name.toString(); // null check
//type.equals(type); // null check
// fill in fields:
assert(testAnyFlags(ALL_KINDS));
//assert(referenceKindIsConsistent()); // do this after resolution
}
private void expandFromVM() {
if (!isResolved()) return;
MethodHandleNatives.expand(this);
}
// Capturing information from the Core Reflection API:
}
/** Create a name for the given reflected method. The resulting name will be in a resolved state. */
this(m, false);
}
@SuppressWarnings("LeakingThisInConstructor")
m.getClass(); // NPE check
// fill in vmtarget, vmindex while we have m in hand:
MethodHandleNatives.init(this, m);
if (wantSpecial) {
if (getReferenceKind() == REF_invokeVirtual)
}
}
switch (getReferenceKind()) {
case REF_invokeSpecial: return this;
case REF_newInvokeSpecial: return clone().changeReferenceKind(REF_invokeSpecial, REF_newInvokeSpecial);
}
throw new IllegalArgumentException(this.toString());
}
switch (getReferenceKind()) {
case REF_invokeSpecial: return clone().changeReferenceKind(REF_newInvokeSpecial, REF_invokeSpecial);
case REF_newInvokeSpecial: return this;
}
throw new IllegalArgumentException(this.toString());
}
/** Create a name for the given reflected constructor. The resulting name will be in a resolved state. */
@SuppressWarnings("LeakingThisInConstructor")
// fill in vmtarget, vmindex while we have ctor in hand:
this.name = CONSTRUCTOR_NAME;
}
/** Create a name for the given reflected field. The resulting name will be in a resolved state.
*/
this(fld, false);
}
@SuppressWarnings("LeakingThisInConstructor")
// fill in vmtarget, vmindex while we have fld in hand:
byte refKind = this.getReferenceKind();
if (makeSetter) {
}
}
public boolean isGetter() {
}
public boolean isSetter() {
}
byte refKind = getReferenceKind();
}
/** Create a name for the given class. The resulting name will be in a resolved state. */
initResolved(true);
}
// bare-bones constructor; the JVM will fill it in
MemberName() { }
// locally useful cloner
try {
return (MemberName) super.clone();
} catch (CloneNotSupportedException ex) {
throw newInternalError(ex);
}
}
/** Get the definition of this member name.
* This may be in a super-class of the declaring class of this member.
*/
if (isType()) return this;
res.expandFromVM();
return res;
}
public int hashCode() {
}
}
/** Decide if two member names have exactly the same symbolic content.
* Does not take into account any actual class members, so even if
* two member names resolve to the same actual member, they may
* be distinct references.
*/
if (this == that) return true;
}
// Construction from symbolic parts, for queries:
/** Create a field or type name from the given components: Declaring class, name, type, reference kind.
* The declaring class may be supplied as null if this is to be a bare name and type.
* The resulting name will in an unresolved state.
*/
initResolved(false);
}
/** Create a field or type name from the given components: Declaring class, name, type.
* The declaring class may be supplied as null if this is to be a bare name and type.
* The modifier flags default to zero.
* The resulting name will in an unresolved state.
*/
initResolved(false);
}
/** Create a method or constructor name from the given components: Declaring class, name, type, modifiers.
* It will be a constructor if and only if the name is {@code "<init>"}.
* The declaring class may be supplied as null if this is to be a bare name and type.
* The last argument is optional, a boolean which requests REF_invokeSpecial.
* The resulting name will in an unresolved state.
*/
@SuppressWarnings("LocalVariableHidesMemberVariable")
initResolved(false);
}
// /** Create a method or constructor name from the given components: Declaring class, name, type, modifiers.
// * It will be a constructor if and only if the name is {@code "<init>"}.
// * The declaring class may be supplied as null if this is to be a bare name and type.
// * The modifier flags default to zero.
// * The resulting name will in an unresolved state.
// */
// public MemberName(Class<?> defClass, String name, MethodType type, Void unused) {
// this(defClass, name, type, REF_NONE);
// }
/** Query whether this member name is resolved to a non-static, non-final method.
*/
public boolean hasReceiverTypeDispatch() {
}
/** Query whether this member name is resolved.
* A resolved member name is one for which the JVM has found
* a method, constructor, field, or type binding corresponding exactly to the name.
* (Document?)
*/
public boolean isResolved() {
return resolution == null;
}
if (!isResolved)
this.resolution = this;
assert(isResolved() == isResolved);
}
void checkForTypeAlias() {
if (isInvocable()) {
if (this.type instanceof MethodType)
else
} else {
else
}
}
/** Produce a string form of this member name.
* For types, it is simply the type's own string (as reported by {@code toString}).
* For fields, it is {@code "DeclaringClass.name/type"}.
* For methods and constructors, it is {@code "DeclaringClass.name(ptype...)rtype"}.
* If the declaring class is null, the prefix {@code "DeclaringClass."} is omitted.
* If the member is unresolved, a prefix {@code "*."} is prepended.
*/
@SuppressWarnings("LocalVariableHidesMemberVariable")
if (isType())
// else it is a field, method, or constructor
if (getDeclaringClass() != null) {
}
if (!isInvocable()) {
} else {
}
byte refKind = getReferenceKind();
}
//buf.append("#").append(System.identityHashCode(this));
}
}
return new IllegalAccessException(message);
}
if (isResolved())
return "no access";
else if (isConstructor())
return "no such constructor";
else if (isMethod())
return "no such method";
else
return "no such field";
}
resolution instanceof NoSuchFieldError))
else if (isConstructor())
else if (isMethod())
else
if (resolution instanceof Throwable)
return ex;
}
/** Actually making a query requires an access check. */
}
/** A factory type for resolving member names with the help of the VM.
* TBD: Define access-safe public constructors for this factory.
*/
/// Queries
else
}
final int BUF_MAX = 0x2000;
int totalCount = 0;
int bufCount = 0;
for (;;) {
totalCount, buf);
totalCount += bufCount;
break;
}
// JVM returned to us with an intentional overflow!
}
}
}
// Signature matching is not the same as type matching, since
// one signature might correspond to several types.
// So if matchType is a Class or MethodType, refilter the results.
}
}
return result;
}
/** Produce a resolved version of the given member.
* Super types are searched (for inherited members) if {@code searchSupers} is true.
* Access checking is performed on behalf of the given {@code lookupClass}.
* If lookup fails or access is not permitted, null is returned.
* Otherwise a fresh copy of the given member is returned, with modifier bits filled in.
*/
assert(refKind == m.getReferenceKind());
try {
m.checkForTypeAlias();
m.resolution = null;
} catch (LinkageError ex) {
// JVM reports that the "bytecode behavior" would get an error
assert(!m.isResolved());
m.resolution = ex;
return m;
}
assert(m.referenceKindIsConsistent());
m.initResolved(true);
assert(m.vminfoIsConsistent());
return m;
}
/** Produce a resolved version of the given member.
* Super types are searched (for inherited members) if {@code searchSupers} is true.
* Access checking is performed on behalf of the given {@code lookupClass}.
* If lookup fails or access is not permitted, a {@linkplain ReflectiveOperationException} is thrown.
* Otherwise a fresh copy of the given member is returned, with modifier bits filled in.
*/
public
throws IllegalAccessException, NoSuchMemberException {
if (result.isResolved())
return result;
}
/** Produce a resolved version of the given member.
* Super types are searched (for inherited members) if {@code searchSupers} is true.
* Access checking is performed on behalf of the given {@code lookupClass}.
* If lookup fails or access is not permitted, return null.
* Otherwise a fresh copy of the given member is returned, with modifier bits filled in.
*/
public
if (result.isResolved())
return result;
return null;
}
/** Return a list of all methods defined by the given class.
* Super types are searched (for inherited members) if {@code searchSupers} is true.
* Access checking is performed on behalf of the given {@code lookupClass}.
* Inaccessible members are not added to the last.
*/
Class<?> lookupClass) {
}
/** Return a list of matching methods defined by the given class.
* Super types are searched (for inherited members) if {@code searchSupers} is true.
* Returned methods will match the name (if not null) and the type (if not null).
* Access checking is performed on behalf of the given {@code lookupClass}.
* Inaccessible members are not added to the last.
*/
}
/** Return a list of all constructors defined by the given class.
* Access checking is performed on behalf of the given {@code lookupClass}.
* Inaccessible members are not added to the last.
*/
}
/** Return a list of all fields defined by the given class.
* Super types are searched (for inherited members) if {@code searchSupers} is true.
* Access checking is performed on behalf of the given {@code lookupClass}.
* Inaccessible members are not added to the last.
*/
Class<?> lookupClass) {
}
/** Return a list of all fields defined by the given class.
* Super types are searched (for inherited members) if {@code searchSupers} is true.
* Returned fields will match the name (if not null) and the type (if not null).
* Access checking is performed on behalf of the given {@code lookupClass}.
* Inaccessible members are not added to the last.
*/
}
/** Return a list of all nested types defined by the given class.
* Super types are searched (for inherited members) if {@code searchSupers} is true.
* Access checking is performed on behalf of the given {@code lookupClass}.
* Inaccessible members are not added to the last.
*/
Class<?> lookupClass) {
}
// fill the buffer with dummy structs for the JVM to fill in
for (int i = 0; i < length; i++)
buf[i] = new MemberName();
return buf;
}
}
// static {
// System.out.println("Hello world! My methods are:");
// System.out.println(Factory.INSTANCE.getMethods(MemberName.class, true, null));
// }
}