8065172: More core reflection final and volatile annotations
More fiddling with "final" and "volatile" field modifiers Reviewed-by: jfranck, plevart, psandoz
This commit is contained in:
parent
b479361747
commit
0a3973c5a6
@ -52,7 +52,7 @@ class Label {
|
||||
final short patchBCI;
|
||||
final int stackDepth;
|
||||
}
|
||||
private List<PatchInfo> patches = new ArrayList<>();
|
||||
private final List<PatchInfo> patches = new ArrayList<>();
|
||||
|
||||
public Label() {
|
||||
}
|
||||
|
@ -135,7 +135,7 @@ public class ReflectionFactory {
|
||||
* be initialized and therefore must not be called until the
|
||||
* first get/set of this field.
|
||||
* @param field the field
|
||||
* @param override true if caller has overridden aaccessibility
|
||||
* @param override true if caller has overridden accessibility
|
||||
*/
|
||||
public FieldAccessor newFieldAccessor(Field field, boolean override) {
|
||||
checkInitted();
|
||||
|
@ -280,19 +280,25 @@ class AnnotationInvocationHandler implements InvocationHandler, Serializable {
|
||||
* be rare).
|
||||
*/
|
||||
private Method[] getMemberMethods() {
|
||||
if (memberMethods == null) {
|
||||
memberMethods = AccessController.doPrivileged(
|
||||
new PrivilegedAction<Method[]>() {
|
||||
public Method[] run() {
|
||||
final Method[] mm = type.getDeclaredMethods();
|
||||
validateAnnotationMethods(mm);
|
||||
AccessibleObject.setAccessible(mm, true);
|
||||
return mm;
|
||||
}
|
||||
});
|
||||
Method[] value = memberMethods;
|
||||
if (value == null) {
|
||||
value = computeMemberMethods();
|
||||
memberMethods = value;
|
||||
}
|
||||
return memberMethods;
|
||||
return value;
|
||||
}
|
||||
|
||||
private Method[] computeMemberMethods() {
|
||||
return AccessController.doPrivileged(
|
||||
new PrivilegedAction<Method[]>() {
|
||||
public Method[] run() {
|
||||
final Method[] methods = type.getDeclaredMethods();
|
||||
validateAnnotationMethods(methods);
|
||||
AccessibleObject.setAccessible(methods, true);
|
||||
return methods;
|
||||
}});
|
||||
}
|
||||
|
||||
private transient volatile Method[] memberMethods = null;
|
||||
|
||||
/**
|
||||
|
@ -772,7 +772,7 @@ public class AnnotationParser {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an appropriate exception proxy for a mismatching array
|
||||
* Returns an appropriate exception proxy for a mismatching array
|
||||
* annotation where the erroneous array has the specified tag.
|
||||
*/
|
||||
private static ExceptionProxy exceptionProxy(int tag) {
|
||||
|
@ -115,7 +115,7 @@ public final class AnnotationSupport {
|
||||
|
||||
|
||||
/**
|
||||
* Figures out if conatiner class comes before containee class among the
|
||||
* Figures out if container class comes before containee class among the
|
||||
* keys of the given map.
|
||||
*
|
||||
* @return true if container class is found before containee class when
|
||||
|
@ -55,7 +55,7 @@ public class AnnotationType {
|
||||
private final Map<String, Object> memberDefaults;
|
||||
|
||||
/**
|
||||
* Member name -> Method object mapping. This (and its assoicated
|
||||
* Member name -> Method object mapping. This (and its associated
|
||||
* accessor) are used only to generate AnnotationTypeMismatchExceptions.
|
||||
*/
|
||||
private final Map<String, Method> members;
|
||||
@ -117,7 +117,7 @@ public class AnnotationType {
|
||||
memberDefaults = new HashMap<String, Object>(0);
|
||||
members = new HashMap<String, Method>(methods.length+1, 1.0f);
|
||||
|
||||
for (Method method : methods) {
|
||||
for (Method method : methods) {
|
||||
if (method.getParameterTypes().length != 0)
|
||||
throw new IllegalArgumentException(method + " has params");
|
||||
String name = method.getName();
|
||||
|
@ -36,7 +36,7 @@ import java.lang.reflect.Method;
|
||||
class AnnotationTypeMismatchExceptionProxy extends ExceptionProxy {
|
||||
private static final long serialVersionUID = 7844069490309503934L;
|
||||
private Method member;
|
||||
private String foundType;
|
||||
private final String foundType;
|
||||
|
||||
/**
|
||||
* It turns out to be convenient to construct these proxies in
|
||||
|
@ -33,8 +33,8 @@ package sun.reflect.annotation;
|
||||
*/
|
||||
public class EnumConstantNotPresentExceptionProxy extends ExceptionProxy {
|
||||
private static final long serialVersionUID = -604662101303187330L;
|
||||
Class<? extends Enum<?>> enumType;
|
||||
String constName;
|
||||
final Class<? extends Enum<?>> enumType;
|
||||
final String constName;
|
||||
|
||||
public EnumConstantNotPresentExceptionProxy(Class<? extends Enum<?>> enumType,
|
||||
String constName) {
|
||||
|
@ -34,8 +34,8 @@ import java.lang.annotation.*;
|
||||
*/
|
||||
public class TypeNotPresentExceptionProxy extends ExceptionProxy {
|
||||
private static final long serialVersionUID = 5565925172427947573L;
|
||||
String typeName;
|
||||
Throwable cause;
|
||||
final String typeName;
|
||||
final Throwable cause;
|
||||
|
||||
public TypeNotPresentExceptionProxy(String typeName, Throwable cause) {
|
||||
this.typeName = typeName;
|
||||
|
@ -76,11 +76,11 @@ public class CoreReflectionFactory implements GenericsFactory {
|
||||
* kind. Classes produced will be those that would be loaded by the
|
||||
* defining class loader of the declaration <tt>d</tt> (if <tt>d</tt>
|
||||
* is a type declaration, or by the defining loader of the declaring
|
||||
* class of <tt>d</tt> otherwise.
|
||||
* class of <tt>d</tt> otherwise.
|
||||
* <p> Type variables will be created or lookup as necessary in the
|
||||
* scope <tt> s</tt>.
|
||||
* @param d - the generic declaration (class, interface, method or
|
||||
* constructor) that thsi factory services
|
||||
* constructor) that this factory services
|
||||
* @param s the scope in which the factory will allocate and search for
|
||||
* type variables
|
||||
* @return an instance of <tt>CoreReflectionFactory</tt>
|
||||
|
@ -42,7 +42,7 @@ import sun.reflect.generics.tree.FieldTypeSignature;
|
||||
* of a specific implementation by using this interface. For example,
|
||||
* repositories of generic type information are initialized with a
|
||||
* factory conforming to this interface, and use it to generate the
|
||||
* tpe information they are required to provide. As a result, such
|
||||
* type information they are required to provide. As a result, such
|
||||
* repository code can be shared across different reflective systems.
|
||||
*/
|
||||
public interface GenericsFactory {
|
||||
@ -60,7 +60,7 @@ public interface GenericsFactory {
|
||||
TypeVariable<?> makeTypeVariable(String name,
|
||||
FieldTypeSignature[] bounds);
|
||||
/**
|
||||
* Return an instance of the <tt>ParameterizedType</tt> interface
|
||||
* Returns an instance of the <tt>ParameterizedType</tt> interface
|
||||
* that corresponds to a generic type instantiation of the
|
||||
* generic declaration <tt>declaration</tt> with actual type arguments
|
||||
* <tt>typeArgs</tt>.
|
||||
@ -123,7 +123,7 @@ public interface GenericsFactory {
|
||||
/**
|
||||
* Returns a (possibly generic) array type.
|
||||
* If the component type is a parameterized type, it must
|
||||
* only have unbounded wildcard arguemnts, otherwise
|
||||
* only have unbounded wildcard arguments, otherwise
|
||||
* a MalformedParameterizedTypeException is thrown.
|
||||
* @param componentType - the component type of the array
|
||||
* @return a (possibly generic) array type.
|
||||
|
@ -227,7 +227,7 @@ public class SignatureParser {
|
||||
* "<" FormalTypeParameter+ ">"
|
||||
*/
|
||||
private FormalTypeParameter[] parseFormalTypeParameters(){
|
||||
List<FormalTypeParameter> ftps = new ArrayList<>(3);
|
||||
List<FormalTypeParameter> ftps = new ArrayList<>(3);
|
||||
assert(current() == '<'); // should not have been called at all
|
||||
if (current() != '<') { throw error("expected '<'");}
|
||||
advance();
|
||||
|
@ -53,10 +53,10 @@ public class GenericArrayTypeImpl
|
||||
|
||||
|
||||
/**
|
||||
* Returns a <tt>Type</tt> object representing the component type
|
||||
* Returns a <tt>Type</tt> object representing the component type
|
||||
* of this array.
|
||||
*
|
||||
* @return a <tt>Type</tt> object representing the component type
|
||||
* @return a <tt>Type</tt> object representing the component type
|
||||
* of this array
|
||||
* @since 1.5
|
||||
*/
|
||||
|
@ -25,7 +25,9 @@
|
||||
|
||||
package sun.reflect.generics.reflectiveObjects;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import sun.reflect.generics.factory.GenericsFactory;
|
||||
import sun.reflect.generics.tree.FieldTypeSignature;
|
||||
import sun.reflect.generics.visitor.Reifier;
|
||||
|
||||
|
||||
@ -54,4 +56,16 @@ public abstract class LazyReflectiveObjectGenerator {
|
||||
// produce a reifying visitor (could this be typed as a TypeTreeVisitor?
|
||||
protected Reifier getReifier(){return Reifier.make(getFactory());}
|
||||
|
||||
Type[] reifyBounds(FieldTypeSignature[] boundASTs) {
|
||||
final int length = boundASTs.length;
|
||||
final Type[] bounds = new Type[length];
|
||||
// iterate over bound trees, reifying each in turn
|
||||
for (int i = 0; i < length; i++) {
|
||||
Reifier r = getReifier();
|
||||
boundASTs[i].accept(r);
|
||||
bounds[i] = r.getResult();
|
||||
}
|
||||
return bounds;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -51,17 +51,16 @@ import sun.reflect.misc.ReflectUtil;
|
||||
*/
|
||||
public class TypeVariableImpl<D extends GenericDeclaration>
|
||||
extends LazyReflectiveObjectGenerator implements TypeVariable<D> {
|
||||
D genericDeclaration;
|
||||
private String name;
|
||||
// upper bounds - evaluated lazily
|
||||
private Type[] bounds;
|
||||
private final D genericDeclaration;
|
||||
private final String name;
|
||||
|
||||
// The ASTs for the bounds. We are required to evaluate the bounds
|
||||
// lazily, so we store these at least until we are first asked
|
||||
// for the bounds. This also neatly solves the
|
||||
// problem with F-bounds - you can't reify them before the formal
|
||||
// is defined.
|
||||
private FieldTypeSignature[] boundASTs;
|
||||
/**
|
||||
* The upper bounds. Lazily converted from FieldTypeSignature[] to Type[].
|
||||
* We are required to evaluate the bounds lazily, so we store them as ASTs
|
||||
* until we are first asked for them. This also neatly solves the problem
|
||||
* with F-bounds - you can't reify them before the formal is defined.
|
||||
*/
|
||||
private volatile Object[] bounds;
|
||||
|
||||
// constructor is private to enforce access through static factory
|
||||
private TypeVariableImpl(D decl, String n, FieldTypeSignature[] bs,
|
||||
@ -69,18 +68,7 @@ public class TypeVariableImpl<D extends GenericDeclaration>
|
||||
super(f);
|
||||
genericDeclaration = decl;
|
||||
name = n;
|
||||
boundASTs = bs;
|
||||
}
|
||||
|
||||
// Accessors
|
||||
|
||||
// accessor for ASTs for bounds. Must not be called after
|
||||
// bounds have been evaluated, because we might throw the ASTs
|
||||
// away (but that is not thread-safe, is it?)
|
||||
private FieldTypeSignature[] getBoundASTs() {
|
||||
// check that bounds were not evaluated yet
|
||||
assert(bounds == null);
|
||||
return boundASTs;
|
||||
bounds = bs;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -123,7 +111,7 @@ public class TypeVariableImpl<D extends GenericDeclaration>
|
||||
* <li>Otherwise, B is resolved.
|
||||
* </ul>
|
||||
*
|
||||
* @throws <tt>TypeNotPresentException</tt> if any of the
|
||||
* @throws <tt>TypeNotPresentException</tt> if any of the
|
||||
* bounds refers to a non-existent type declaration
|
||||
* @throws <tt>MalformedParameterizedTypeException</tt> if any of the
|
||||
* bounds refer to a parameterized type that cannot be instantiated
|
||||
@ -132,34 +120,23 @@ public class TypeVariableImpl<D extends GenericDeclaration>
|
||||
* type variable
|
||||
*/
|
||||
public Type[] getBounds() {
|
||||
// lazily initialize bounds if necessary
|
||||
if (bounds == null) {
|
||||
FieldTypeSignature[] fts = getBoundASTs(); // get AST
|
||||
// allocate result array; note that
|
||||
// keeping ts and bounds separate helps with threads
|
||||
Type[] ts = new Type[fts.length];
|
||||
// iterate over bound trees, reifying each in turn
|
||||
for ( int j = 0; j < fts.length; j++) {
|
||||
Reifier r = getReifier();
|
||||
fts[j].accept(r);
|
||||
ts[j] = r.getResult();
|
||||
}
|
||||
// cache result
|
||||
bounds = ts;
|
||||
// could throw away bound ASTs here; thread safety?
|
||||
Object[] value = bounds;
|
||||
if (value instanceof FieldTypeSignature[]) {
|
||||
value = reifyBounds((FieldTypeSignature[])value);
|
||||
bounds = value;
|
||||
}
|
||||
return bounds.clone(); // return cached bounds
|
||||
return (Type[])value.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <tt>GenericDeclaration</tt> object representing the
|
||||
* Returns the <tt>GenericDeclaration</tt> object representing the
|
||||
* generic declaration that declared this type variable.
|
||||
*
|
||||
* @return the generic declaration that declared this type variable.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public D getGenericDeclaration(){
|
||||
public D getGenericDeclaration() {
|
||||
if (genericDeclaration instanceof Class)
|
||||
ReflectUtil.checkPackageAccess((Class)genericDeclaration);
|
||||
else if ((genericDeclaration instanceof Method) ||
|
||||
|
@ -39,25 +39,26 @@ import java.util.Arrays;
|
||||
*/
|
||||
public class WildcardTypeImpl extends LazyReflectiveObjectGenerator
|
||||
implements WildcardType {
|
||||
// upper bounds - evaluated lazily
|
||||
private Type[] upperBounds;
|
||||
// lower bounds - evaluated lazily
|
||||
private Type[] lowerBounds;
|
||||
// The ASTs for the bounds. We are required to evaluate the bounds
|
||||
// lazily, so we store these at least until we are first asked
|
||||
// for the bounds. This also neatly solves the
|
||||
// problem with F-bounds - you can't reify them before the formal
|
||||
// is defined.
|
||||
private FieldTypeSignature[] upperBoundASTs;
|
||||
private FieldTypeSignature[] lowerBoundASTs;
|
||||
|
||||
/*
|
||||
* We are required to evaluate the bounds lazily, so we store them as ASTs
|
||||
* until we are first asked for them. This also neatly solves the problem
|
||||
* with F-bounds - you can't reify them before the formal is defined.
|
||||
*/
|
||||
|
||||
/** The upper bounds. Lazily converted from FieldTypeSignature[] to Type[]. */
|
||||
private volatile Object[] upperBounds;
|
||||
|
||||
/** The lower bounds. Lazily converted from FieldTypeSignature[] to Type[]. */
|
||||
private volatile Object[] lowerBounds;
|
||||
|
||||
// constructor is private to enforce access through static factory
|
||||
private WildcardTypeImpl(FieldTypeSignature[] ubs,
|
||||
FieldTypeSignature[] lbs,
|
||||
GenericsFactory f) {
|
||||
super(f);
|
||||
upperBoundASTs = ubs;
|
||||
lowerBoundASTs = lbs;
|
||||
upperBounds = ubs;
|
||||
lowerBounds = lbs;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -76,27 +77,8 @@ public class WildcardTypeImpl extends LazyReflectiveObjectGenerator
|
||||
return new WildcardTypeImpl(ubs, lbs, f);
|
||||
}
|
||||
|
||||
// Accessors
|
||||
|
||||
// accessor for ASTs for upper bounds. Must not be called after upper
|
||||
// bounds have been evaluated, because we might throw the ASTs
|
||||
// away (but that is not thread-safe, is it?)
|
||||
private FieldTypeSignature[] getUpperBoundASTs() {
|
||||
// check that upper bounds were not evaluated yet
|
||||
assert(upperBounds == null);
|
||||
return upperBoundASTs;
|
||||
}
|
||||
// accessor for ASTs for lower bounds. Must not be called after lower
|
||||
// bounds have been evaluated, because we might throw the ASTs
|
||||
// away (but that is not thread-safe, is it?)
|
||||
private FieldTypeSignature[] getLowerBoundASTs() {
|
||||
// check that lower bounds were not evaluated yet
|
||||
assert(lowerBounds == null);
|
||||
return lowerBoundASTs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of <tt>Type</tt> objects representing the upper
|
||||
* Returns an array of <tt>Type</tt> objects representing the upper
|
||||
* bound(s) of this type variable. Note that if no upper bound is
|
||||
* explicitly declared, the upper bound is <tt>Object</tt>.
|
||||
*
|
||||
@ -117,24 +99,12 @@ public class WildcardTypeImpl extends LazyReflectiveObjectGenerator
|
||||
* for any reason
|
||||
*/
|
||||
public Type[] getUpperBounds() {
|
||||
// lazily initialize bounds if necessary
|
||||
if (upperBounds == null) {
|
||||
FieldTypeSignature[] fts = getUpperBoundASTs(); // get AST
|
||||
|
||||
// allocate result array; note that
|
||||
// keeping ts and bounds separate helps with threads
|
||||
Type[] ts = new Type[fts.length];
|
||||
// iterate over bound trees, reifying each in turn
|
||||
for ( int j = 0; j < fts.length; j++) {
|
||||
Reifier r = getReifier();
|
||||
fts[j].accept(r);
|
||||
ts[j] = r.getResult();
|
||||
}
|
||||
// cache result
|
||||
upperBounds = ts;
|
||||
// could throw away upper bound ASTs here; thread safety?
|
||||
Object[] value = upperBounds;
|
||||
if (value instanceof FieldTypeSignature[]) {
|
||||
value = reifyBounds((FieldTypeSignature[])value);
|
||||
upperBounds = value;
|
||||
}
|
||||
return upperBounds.clone(); // return cached bounds
|
||||
return (Type[])value.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -160,23 +130,12 @@ public class WildcardTypeImpl extends LazyReflectiveObjectGenerator
|
||||
* for any reason
|
||||
*/
|
||||
public Type[] getLowerBounds() {
|
||||
// lazily initialize bounds if necessary
|
||||
if (lowerBounds == null) {
|
||||
FieldTypeSignature[] fts = getLowerBoundASTs(); // get AST
|
||||
// allocate result array; note that
|
||||
// keeping ts and bounds separate helps with threads
|
||||
Type[] ts = new Type[fts.length];
|
||||
// iterate over bound trees, reifying each in turn
|
||||
for ( int j = 0; j < fts.length; j++) {
|
||||
Reifier r = getReifier();
|
||||
fts[j].accept(r);
|
||||
ts[j] = r.getResult();
|
||||
}
|
||||
// cache result
|
||||
lowerBounds = ts;
|
||||
// could throw away lower bound ASTs here; thread safety?
|
||||
Object[] value = lowerBounds;
|
||||
if (value instanceof FieldTypeSignature[]) {
|
||||
value = reifyBounds((FieldTypeSignature[])value);
|
||||
lowerBounds = value;
|
||||
}
|
||||
return lowerBounds.clone(); // return cached bounds
|
||||
return (Type[])value.clone();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
|
@ -56,7 +56,7 @@ public abstract class AbstractRepository<T extends Tree> {
|
||||
/**
|
||||
* Returns a <tt>Reifier</tt> used to convert parts of the
|
||||
* AST into reflective objects.
|
||||
* @return a <tt>Reifier</tt> used to convert parts of the
|
||||
* @return a <tt>Reifier</tt> used to convert parts of the
|
||||
* AST into reflective objects
|
||||
*/
|
||||
protected Reifier getReifier(){return Reifier.make(getFactory());}
|
||||
@ -76,7 +76,7 @@ public abstract class AbstractRepository<T extends Tree> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the AST for the genric type info of this entity.
|
||||
* Returns the AST for the generic type info of this entity.
|
||||
* @param s - a string representing the generic signature of this
|
||||
* entity
|
||||
* @return the AST for the generic type info of this entity.
|
||||
|
@ -25,12 +25,12 @@
|
||||
|
||||
package sun.reflect.generics.repository;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import sun.reflect.generics.factory.GenericsFactory;
|
||||
import sun.reflect.generics.tree.ClassSignature;
|
||||
import sun.reflect.generics.tree.TypeTree;
|
||||
import sun.reflect.generics.visitor.Reifier;
|
||||
import sun.reflect.generics.parser.SignatureParser;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
|
||||
/**
|
||||
@ -70,47 +70,54 @@ public class ClassRepository extends GenericDeclRepository<ClassSignature> {
|
||||
return new ClassRepository(rawSig, f);
|
||||
}
|
||||
|
||||
// public API
|
||||
/*
|
||||
* When queried for a particular piece of type information, the
|
||||
* general pattern is to consult the corresponding cached value.
|
||||
* If the corresponding field is non-null, it is returned.
|
||||
* If not, it is created lazily. This is done by selecting the appropriate
|
||||
* part of the tree and transforming it into a reflective object
|
||||
* using a visitor.
|
||||
* a visitor, which is created by feeding it the factory
|
||||
* using a visitor, which is created by feeding it the factory
|
||||
* with which the repository was created.
|
||||
*/
|
||||
|
||||
public Type getSuperclass() {
|
||||
Type superclass = this.superclass;
|
||||
if (superclass == null) { // lazily initialize superclass
|
||||
Reifier r = getReifier(); // obtain visitor
|
||||
// Extract superclass subtree from AST and reify
|
||||
getTree().getSuperclass().accept(r);
|
||||
// extract result from visitor and cache it
|
||||
superclass = r.getResult();
|
||||
this.superclass = superclass;
|
||||
Type value = superclass;
|
||||
if (value == null) {
|
||||
value = computeSuperclass();
|
||||
superclass = value;
|
||||
}
|
||||
return superclass; // return cached result
|
||||
return value;
|
||||
}
|
||||
|
||||
public Type[] getSuperInterfaces() {
|
||||
Type[] superInterfaces = this.superInterfaces;
|
||||
if (superInterfaces == null) { // lazily initialize super interfaces
|
||||
// first, extract super interface subtree(s) from AST
|
||||
TypeTree[] ts = getTree().getSuperInterfaces();
|
||||
// create array to store reified subtree(s)
|
||||
superInterfaces = new Type[ts.length];
|
||||
// reify all subtrees
|
||||
for (int i = 0; i < ts.length; i++) {
|
||||
Reifier r = getReifier(); // obtain visitor
|
||||
ts[i].accept(r);// reify subtree
|
||||
// extract result from visitor and store it
|
||||
superInterfaces[i] = r.getResult();
|
||||
}
|
||||
this.superInterfaces = superInterfaces;
|
||||
Type[] value = superInterfaces;
|
||||
if (value == null) {
|
||||
value = computeSuperInterfaces();
|
||||
superInterfaces = value;
|
||||
}
|
||||
return superInterfaces.clone(); // return cached result
|
||||
return value.clone();
|
||||
}
|
||||
|
||||
private Type computeSuperclass() {
|
||||
Reifier r = getReifier(); // obtain visitor
|
||||
// Extract superclass subtree from AST and reify
|
||||
getTree().getSuperclass().accept(r);
|
||||
return r.getResult();
|
||||
}
|
||||
|
||||
private Type[] computeSuperInterfaces() {
|
||||
// first, extract super interface subtree(s) from AST
|
||||
TypeTree[] ts = getTree().getSuperInterfaces();
|
||||
// create array to store reified subtree(s)
|
||||
int length = ts.length;
|
||||
Type[] superInterfaces = new Type[length];
|
||||
// reify all subtrees
|
||||
for (int i = 0; i < length; i++) {
|
||||
Reifier r = getReifier(); // obtain visitor
|
||||
ts[i].accept(r);// reify subtree
|
||||
// extract result from visitor and store it
|
||||
superInterfaces[i] = r.getResult();
|
||||
}
|
||||
return superInterfaces;
|
||||
}
|
||||
}
|
||||
|
@ -43,8 +43,11 @@ import sun.reflect.generics.visitor.Reifier;
|
||||
public class ConstructorRepository
|
||||
extends GenericDeclRepository<MethodTypeSignature> {
|
||||
|
||||
private Type[] paramTypes; // caches the generic parameter types info
|
||||
private Type[] exceptionTypes; // caches the generic exception types info
|
||||
/** The generic parameter types. Lazily initialized. */
|
||||
private volatile Type[] parameterTypes;
|
||||
|
||||
/** The generic exception types. Lazily initialized. */
|
||||
private volatile Type[] exceptionTypes;
|
||||
|
||||
// protected, to enforce use of static factory yet allow subclassing
|
||||
protected ConstructorRepository(String rawSig, GenericsFactory f) {
|
||||
@ -64,57 +67,67 @@ public class ConstructorRepository
|
||||
* @return a <tt>ConstructorRepository</tt> that manages the generic type
|
||||
* information represented in the signature <tt>rawSig</tt>
|
||||
*/
|
||||
public static ConstructorRepository make(String rawSig,
|
||||
GenericsFactory f) {
|
||||
public static ConstructorRepository make(String rawSig, GenericsFactory f) {
|
||||
return new ConstructorRepository(rawSig, f);
|
||||
}
|
||||
|
||||
// public API
|
||||
|
||||
/*
|
||||
* When queried for a particular piece of type information, the
|
||||
* general pattern is to consult the corresponding cached value.
|
||||
* If the corresponding field is non-null, it is returned.
|
||||
* If not, it is created lazily. This is done by selecting the appropriate
|
||||
* part of the tree and transforming it into a reflective object
|
||||
* using a visitor.
|
||||
* a visitor, which is created by feeding it the factory
|
||||
* using a visitor, which is created by feeding it the factory
|
||||
* with which the repository was created.
|
||||
*/
|
||||
|
||||
public Type[] getParameterTypes(){
|
||||
if (paramTypes == null) { // lazily initialize parameter types
|
||||
// first, extract parameter type subtree(s) from AST
|
||||
TypeSignature[] pts = getTree().getParameterTypes();
|
||||
// create array to store reified subtree(s)
|
||||
Type[] ps = new Type[pts.length];
|
||||
// reify all subtrees
|
||||
for (int i = 0; i < pts.length; i++) {
|
||||
Reifier r = getReifier(); // obtain visitor
|
||||
pts[i].accept(r); // reify subtree
|
||||
// extract result from visitor and store it
|
||||
ps[i] = r.getResult();
|
||||
}
|
||||
paramTypes = ps; // cache overall result
|
||||
public Type[] getParameterTypes() {
|
||||
Type[] value = parameterTypes;
|
||||
if (value == null) {
|
||||
value = computeParameterTypes();
|
||||
parameterTypes = value;
|
||||
}
|
||||
return paramTypes.clone(); // return cached result
|
||||
return value.clone();
|
||||
}
|
||||
|
||||
public Type[] getExceptionTypes(){
|
||||
if (exceptionTypes == null) { // lazily initialize exception types
|
||||
// first, extract exception type subtree(s) from AST
|
||||
FieldTypeSignature[] ets = getTree().getExceptionTypes();
|
||||
// create array to store reified subtree(s)
|
||||
Type[] es = new Type[ets.length];
|
||||
// reify all subtrees
|
||||
for (int i = 0; i < ets.length; i++) {
|
||||
Reifier r = getReifier(); // obtain visitor
|
||||
ets[i].accept(r); // reify subtree
|
||||
// extract result from visitor and store it
|
||||
es[i] = r.getResult();
|
||||
}
|
||||
exceptionTypes = es; // cache overall result
|
||||
public Type[] getExceptionTypes() {
|
||||
Type[] value = exceptionTypes;
|
||||
if (value == null) {
|
||||
value = computeExceptionTypes();
|
||||
exceptionTypes = value;
|
||||
}
|
||||
return exceptionTypes.clone(); // return cached result
|
||||
return value.clone();
|
||||
}
|
||||
|
||||
private Type[] computeParameterTypes() {
|
||||
// first, extract parameter type subtree(s) from AST
|
||||
TypeSignature[] pts = getTree().getParameterTypes();
|
||||
// create array to store reified subtree(s)
|
||||
int length = pts.length;
|
||||
Type[] parameterTypes = new Type[length];
|
||||
// reify all subtrees
|
||||
for (int i = 0; i < length; i++) {
|
||||
Reifier r = getReifier(); // obtain visitor
|
||||
pts[i].accept(r); // reify subtree
|
||||
// extract result from visitor and store it
|
||||
parameterTypes[i] = r.getResult();
|
||||
}
|
||||
return parameterTypes;
|
||||
}
|
||||
|
||||
private Type[] computeExceptionTypes() {
|
||||
// first, extract exception type subtree(s) from AST
|
||||
FieldTypeSignature[] ets = getTree().getExceptionTypes();
|
||||
// create array to store reified subtree(s)
|
||||
int length = ets.length;
|
||||
Type[] exceptionTypes = new Type[length];
|
||||
// reify all subtrees
|
||||
for (int i = 0; i < length; i++) {
|
||||
Reifier r = getReifier(); // obtain visitor
|
||||
ets[i].accept(r); // reify subtree
|
||||
// extract result from visitor and store it
|
||||
exceptionTypes[i] = r.getResult();
|
||||
}
|
||||
return exceptionTypes;
|
||||
}
|
||||
}
|
||||
|
@ -41,7 +41,8 @@ import sun.reflect.generics.visitor.Reifier;
|
||||
*/
|
||||
public class FieldRepository extends AbstractRepository<TypeSignature> {
|
||||
|
||||
private Type genericType; // caches the generic type info
|
||||
/** The generic type info. Lazily initialized. */
|
||||
private volatile Type genericType;
|
||||
|
||||
// protected, to enforce use of static factory yet allow subclassing
|
||||
protected FieldRepository(String rawSig, GenericsFactory f) {
|
||||
@ -61,31 +62,32 @@ public class FieldRepository extends AbstractRepository<TypeSignature> {
|
||||
* @return a <tt>FieldRepository</tt> that manages the generic type
|
||||
* information represented in the signature <tt>rawSig</tt>
|
||||
*/
|
||||
public static FieldRepository make(String rawSig,
|
||||
GenericsFactory f) {
|
||||
public static FieldRepository make(String rawSig, GenericsFactory f) {
|
||||
return new FieldRepository(rawSig, f);
|
||||
}
|
||||
|
||||
// public API
|
||||
|
||||
/*
|
||||
* When queried for a particular piece of type information, the
|
||||
* general pattern is to consult the corresponding cached value.
|
||||
* If the corresponding field is non-null, it is returned.
|
||||
* If not, it is created lazily. This is done by selecting the appropriate
|
||||
* part of the tree and transforming it into a reflective object
|
||||
* using a visitor.
|
||||
* a visitor, which is created by feeding it the factory
|
||||
* using a visitor, which is created by feeding it the factory
|
||||
* with which the repository was created.
|
||||
*/
|
||||
|
||||
public Type getGenericType(){
|
||||
if (genericType == null) { // lazily initialize generic type
|
||||
Reifier r = getReifier(); // obtain visitor
|
||||
getTree().accept(r); // reify subtree
|
||||
// extract result from visitor and cache it
|
||||
genericType = r.getResult();
|
||||
public Type getGenericType() {
|
||||
Type value = genericType;
|
||||
if (value == null) {
|
||||
value = computeGenericType();
|
||||
genericType = value;
|
||||
}
|
||||
return genericType; // return cached result
|
||||
return value;
|
||||
}
|
||||
|
||||
private Type computeGenericType() {
|
||||
Reifier r = getReifier(); // obtain visitor
|
||||
getTree().accept(r); // reify subtree
|
||||
return r.getResult(); // extract result from visitor
|
||||
}
|
||||
}
|
||||
|
@ -43,13 +43,12 @@ public abstract class GenericDeclRepository<S extends Signature>
|
||||
extends AbstractRepository<S> {
|
||||
|
||||
/** The formal type parameters. Lazily initialized. */
|
||||
private volatile TypeVariable<?>[] typeParams;
|
||||
private volatile TypeVariable<?>[] typeParameters;
|
||||
|
||||
protected GenericDeclRepository(String rawSig, GenericsFactory f) {
|
||||
super(rawSig, f);
|
||||
}
|
||||
|
||||
// public API
|
||||
/*
|
||||
* When queried for a particular piece of type information, the
|
||||
* general pattern is to consult the corresponding cached value.
|
||||
@ -61,25 +60,31 @@ public abstract class GenericDeclRepository<S extends Signature>
|
||||
*/
|
||||
|
||||
/**
|
||||
* Return the formal type parameters of this generic declaration.
|
||||
* Returns the formal type parameters of this generic declaration.
|
||||
* @return the formal type parameters of this generic declaration
|
||||
*/
|
||||
public TypeVariable<?>[] getTypeParameters() {
|
||||
TypeVariable<?>[] typeParams = this.typeParams;
|
||||
if (typeParams == null) { // lazily initialize type parameters
|
||||
// first, extract type parameter subtree(s) from AST
|
||||
FormalTypeParameter[] ftps = getTree().getFormalTypeParameters();
|
||||
// create array to store reified subtree(s)
|
||||
typeParams = new TypeVariable<?>[ftps.length];
|
||||
// reify all subtrees
|
||||
for (int i = 0; i < ftps.length; i++) {
|
||||
Reifier r = getReifier(); // obtain visitor
|
||||
ftps[i].accept(r); // reify subtree
|
||||
// extract result from visitor and store it
|
||||
typeParams[i] = (TypeVariable<?>) r.getResult();
|
||||
}
|
||||
this.typeParams = typeParams; // cache overall result
|
||||
TypeVariable<?>[] value = typeParameters;
|
||||
if (value == null) {
|
||||
value = computeTypeParameters();
|
||||
typeParameters = value;
|
||||
}
|
||||
return typeParams.clone(); // return cached result
|
||||
return value.clone();
|
||||
}
|
||||
|
||||
private TypeVariable<?>[] computeTypeParameters() {
|
||||
// first, extract type parameter subtree(s) from AST
|
||||
FormalTypeParameter[] ftps = getTree().getFormalTypeParameters();
|
||||
// create array to store reified subtree(s)
|
||||
int length = ftps.length;
|
||||
TypeVariable<?>[] typeParameters = new TypeVariable<?>[length];
|
||||
// reify all subtrees
|
||||
for (int i = 0; i < length; i++) {
|
||||
Reifier r = getReifier(); // obtain visitor
|
||||
ftps[i].accept(r); // reify subtree
|
||||
// extract result from visitor and store it
|
||||
typeParameters[i] = (TypeVariable<?>) r.getResult();
|
||||
}
|
||||
return typeParameters;
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +39,8 @@ import sun.reflect.generics.visitor.Reifier;
|
||||
*/
|
||||
public class MethodRepository extends ConstructorRepository {
|
||||
|
||||
private Type returnType; // caches the generic return type info
|
||||
/** The generic return type info. Lazily initialized. */
|
||||
private volatile Type returnType;
|
||||
|
||||
// private, to enforce use of static factory
|
||||
private MethodRepository(String rawSig, GenericsFactory f) {
|
||||
@ -59,18 +60,21 @@ public class MethodRepository extends ConstructorRepository {
|
||||
return new MethodRepository(rawSig, f);
|
||||
}
|
||||
|
||||
// public API
|
||||
|
||||
public Type getReturnType() {
|
||||
if (returnType == null) { // lazily initialize return type
|
||||
Reifier r = getReifier(); // obtain visitor
|
||||
// Extract return type subtree from AST and reify
|
||||
getTree().getReturnType().accept(r);
|
||||
// extract result from visitor and cache it
|
||||
returnType = r.getResult();
|
||||
}
|
||||
return returnType; // return cached result
|
||||
Type value = returnType;
|
||||
if (value == null) {
|
||||
value = computeReturnType();
|
||||
returnType = value;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
private Type computeReturnType() {
|
||||
Reifier r = getReifier(); // obtain visitor
|
||||
// Extract return type subtree from AST and reify
|
||||
getTree().getReturnType().accept(r);
|
||||
// extract result from visitor and cache it
|
||||
return r.getResult();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -29,7 +29,6 @@ import java.lang.reflect.GenericDeclaration;
|
||||
import java.lang.reflect.TypeVariable;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Abstract superclass for lazy scope objects, used when building
|
||||
* factories for generic information repositories.
|
||||
@ -49,7 +48,7 @@ public abstract class AbstractScope<D extends GenericDeclaration>
|
||||
/**
|
||||
* Constructor. Takes a reflective object whose scope the newly
|
||||
* constructed instance will represent.
|
||||
* @param D - A generic declaration whose scope the newly
|
||||
* @param decl - A generic declaration whose scope the newly
|
||||
* constructed instance will represent
|
||||
*/
|
||||
protected AbstractScope(D decl){ recvr = decl;}
|
||||
@ -63,7 +62,7 @@ public abstract class AbstractScope<D extends GenericDeclaration>
|
||||
|
||||
/** This method must be implemented by any concrete subclass.
|
||||
* It must return the enclosing scope of this scope. If this scope
|
||||
* is a top-level scope, an instance of DummyScope must be returned.
|
||||
* is a top-level scope, an instance of DummyScope must be returned.
|
||||
* @return The enclosing scope of this scope
|
||||
*/
|
||||
protected abstract Scope computeEnclosingScope();
|
||||
@ -72,13 +71,13 @@ public abstract class AbstractScope<D extends GenericDeclaration>
|
||||
* Accessor for the enclosing scope, which is computed lazily and cached.
|
||||
* @return the enclosing scope
|
||||
*/
|
||||
protected Scope getEnclosingScope(){
|
||||
Scope enclosingScope = this.enclosingScope;
|
||||
if (enclosingScope == null) {
|
||||
enclosingScope = computeEnclosingScope();
|
||||
this.enclosingScope = enclosingScope;
|
||||
protected Scope getEnclosingScope() {
|
||||
Scope value = enclosingScope;
|
||||
if (value == null) {
|
||||
value = computeEnclosingScope();
|
||||
enclosingScope = value;
|
||||
}
|
||||
return enclosingScope;
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -27,7 +27,7 @@ package sun.reflect.generics.tree;
|
||||
|
||||
/**
|
||||
* Common superinterface for generic signatures. These are the signatures
|
||||
* of complete class and method/constructor delcarations.
|
||||
* of complete class and method/constructor declarations.
|
||||
*/
|
||||
public interface Signature extends Tree{
|
||||
FormalTypeParameter[] getFormalTypeParameters();
|
||||
|
@ -28,8 +28,8 @@ package sun.reflect.generics.tree;
|
||||
import sun.reflect.generics.visitor.TypeTreeVisitor;
|
||||
|
||||
public class Wildcard implements TypeArgument {
|
||||
private FieldTypeSignature[] upperBounds;
|
||||
private FieldTypeSignature[] lowerBounds;
|
||||
private final FieldTypeSignature[] upperBounds;
|
||||
private final FieldTypeSignature[] lowerBounds;
|
||||
|
||||
private Wildcard(FieldTypeSignature[] ubs, FieldTypeSignature[] lbs) {
|
||||
upperBounds = ubs;
|
||||
@ -43,11 +43,11 @@ public class Wildcard implements TypeArgument {
|
||||
return new Wildcard(ubs, lbs);
|
||||
}
|
||||
|
||||
public FieldTypeSignature[] getUpperBounds(){
|
||||
public FieldTypeSignature[] getUpperBounds() {
|
||||
return upperBounds;
|
||||
}
|
||||
|
||||
public FieldTypeSignature[] getLowerBounds(){
|
||||
public FieldTypeSignature[] getLowerBounds() {
|
||||
if (lowerBounds.length == 1 &&
|
||||
lowerBounds[0] == BottomSignature.make())
|
||||
return emptyBounds;
|
||||
|
@ -39,7 +39,7 @@ import sun.reflect.generics.factory.*;
|
||||
*/
|
||||
public class Reifier implements TypeTreeVisitor<Type> {
|
||||
private Type resultType;
|
||||
private GenericsFactory factory;
|
||||
private final GenericsFactory factory;
|
||||
|
||||
private Reifier(GenericsFactory f){
|
||||
factory = f;
|
||||
|
@ -40,6 +40,7 @@ import java.lang.reflect.Method;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.AccessibleObject;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import sun.misc.IOUtils;
|
||||
@ -216,17 +217,21 @@ public final class MethodUtil extends SecureClassLoader {
|
||||
* key in the method cache.
|
||||
*/
|
||||
private static class Signature {
|
||||
private String methodName;
|
||||
private Class<?>[] argClasses;
|
||||
|
||||
private volatile int hashCode = 0;
|
||||
private final String methodName;
|
||||
private final Class<?>[] argClasses;
|
||||
private final int hashCode;
|
||||
|
||||
Signature(Method m) {
|
||||
this.methodName = m.getName();
|
||||
this.argClasses = m.getParameterTypes();
|
||||
this.hashCode = methodName.hashCode() + Arrays.hashCode(argClasses);
|
||||
}
|
||||
|
||||
public boolean equals(Object o2) {
|
||||
@Override public int hashCode() {
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
@Override public boolean equals(Object o2) {
|
||||
if (this == o2) {
|
||||
return true;
|
||||
}
|
||||
@ -244,25 +249,6 @@ public final class MethodUtil extends SecureClassLoader {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hash code computed using algorithm suggested in
|
||||
* Effective Java, Item 8.
|
||||
*/
|
||||
public int hashCode() {
|
||||
if (hashCode == 0) {
|
||||
int result = 17;
|
||||
result = 37 * result + methodName.hashCode();
|
||||
if (argClasses != null) {
|
||||
for (int i = 0; i < argClasses.length; i++) {
|
||||
result = 37 * result + ((argClasses[i] == null) ? 0 :
|
||||
argClasses[i].hashCode());
|
||||
}
|
||||
}
|
||||
hashCode = result;
|
||||
}
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -319,7 +319,7 @@ public final class ReflectUtil {
|
||||
return;
|
||||
}
|
||||
|
||||
// disallow any method not declared in one of the proxy intefaces
|
||||
// disallow any method not declared in one of the proxy interfaces
|
||||
throw new IllegalArgumentException("Can't handle: " + method);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user