feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package sun.reflect.generics.reflectiveObjects;
|
||||
|
||||
import java.lang.reflect.GenericArrayType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Implementation of GenericArrayType interface for core reflection.
|
||||
*/
|
||||
public class GenericArrayTypeImpl
|
||||
implements GenericArrayType {
|
||||
private final Type genericComponentType;
|
||||
|
||||
// private constructor enforces use of static factory
|
||||
private GenericArrayTypeImpl(Type ct) {
|
||||
genericComponentType = ct;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method.
|
||||
* @param ct - the desired component type of the generic array type
|
||||
* being created
|
||||
* @return a generic array type with the desired component type
|
||||
*/
|
||||
public static GenericArrayTypeImpl make(Type ct) {
|
||||
return new GenericArrayTypeImpl(ct);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a <tt>Type</tt> object representing the component type
|
||||
* of this array.
|
||||
*
|
||||
* @return a <tt>Type</tt> object representing the component type
|
||||
* of this array
|
||||
* @since 1.5
|
||||
*/
|
||||
public Type getGenericComponentType() {
|
||||
return genericComponentType; // return cached component type
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
Type componentType = getGenericComponentType();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
if (componentType instanceof Class)
|
||||
sb.append(((Class)componentType).getName() );
|
||||
else
|
||||
sb.append(componentType.toString());
|
||||
sb.append("[]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof GenericArrayType) {
|
||||
GenericArrayType that = (GenericArrayType) o;
|
||||
|
||||
return Objects.equals(genericComponentType, that.getGenericComponentType());
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(genericComponentType);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package sun.reflect.generics.reflectiveObjects;
|
||||
|
||||
import sun.reflect.generics.factory.GenericsFactory;
|
||||
import sun.reflect.generics.visitor.Reifier;
|
||||
|
||||
|
||||
/**
|
||||
* Common infrastructure for things that lazily generate reflective generics
|
||||
* objects.
|
||||
* <p> In all these cases, one needs produce a visitor that will, on demand,
|
||||
* traverse the stored AST(s) and reify them into reflective objects.
|
||||
* The visitor needs to be initialized with a factory, which will be
|
||||
* provided when the instance is initialized.
|
||||
* The factory should be cached.
|
||||
*
|
||||
*/
|
||||
public abstract class LazyReflectiveObjectGenerator {
|
||||
private final GenericsFactory factory; // cached factory
|
||||
|
||||
protected LazyReflectiveObjectGenerator(GenericsFactory f) {
|
||||
factory = f;
|
||||
}
|
||||
|
||||
// accessor for factory
|
||||
private GenericsFactory getFactory() {
|
||||
return factory;
|
||||
}
|
||||
|
||||
// produce a reifying visitor (could this be typed as a TypeTreeVisitor?
|
||||
protected Reifier getReifier(){return Reifier.make(getFactory());}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package sun.reflect.generics.reflectiveObjects;
|
||||
|
||||
/** Temporary class used to indicate missing functionality */
|
||||
public class NotImplementedException extends RuntimeException {
|
||||
private static final long serialVersionUID = -9177857708926624790L;
|
||||
}
|
||||
@@ -0,0 +1,242 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package sun.reflect.generics.reflectiveObjects;
|
||||
|
||||
import sun.reflect.generics.tree.FieldTypeSignature;
|
||||
|
||||
import java.lang.reflect.MalformedParameterizedTypeException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.lang.reflect.TypeVariable;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
/** Implementing class for ParameterizedType interface. */
|
||||
|
||||
public class ParameterizedTypeImpl implements ParameterizedType {
|
||||
private final Type[] actualTypeArguments;
|
||||
private final Class<?> rawType;
|
||||
private final Type ownerType;
|
||||
|
||||
private ParameterizedTypeImpl(Class<?> rawType,
|
||||
Type[] actualTypeArguments,
|
||||
Type ownerType) {
|
||||
this.actualTypeArguments = actualTypeArguments;
|
||||
this.rawType = rawType;
|
||||
this.ownerType = (ownerType != null) ? ownerType : rawType.getDeclaringClass();
|
||||
validateConstructorArguments();
|
||||
}
|
||||
|
||||
private void validateConstructorArguments() {
|
||||
TypeVariable<?>[] formals = rawType.getTypeParameters();
|
||||
// check correct arity of actual type args
|
||||
if (formals.length != actualTypeArguments.length){
|
||||
throw new MalformedParameterizedTypeException();
|
||||
}
|
||||
for (int i = 0; i < actualTypeArguments.length; i++) {
|
||||
// check actuals against formals' bounds
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Static factory. Given a (generic) class, actual type arguments
|
||||
* and an owner type, creates a parameterized type.
|
||||
* This class can be instantiated with a a raw type that does not
|
||||
* represent a generic type, provided the list of actual type
|
||||
* arguments is empty.
|
||||
* If the ownerType argument is null, the declaring class of the
|
||||
* raw type is used as the owner type.
|
||||
* <p> This method throws a MalformedParameterizedTypeException
|
||||
* under the following circumstances:
|
||||
* If the number of actual type arguments (i.e., the size of the
|
||||
* array <tt>typeArgs</tt>) does not correspond to the number of
|
||||
* formal type arguments.
|
||||
* If any of the actual type arguments is not an instance of the
|
||||
* bounds on the corresponding formal.
|
||||
* @param rawType the Class representing the generic type declaration being
|
||||
* instantiated
|
||||
* @param actualTypeArguments - a (possibly empty) array of types
|
||||
* representing the actual type arguments to the parameterized type
|
||||
* @param ownerType - the enclosing type, if known.
|
||||
* @return An instance of <tt>ParameterizedType</tt>
|
||||
* @throws MalformedParameterizedTypeException - if the instantiation
|
||||
* is invalid
|
||||
*/
|
||||
public static ParameterizedTypeImpl make(Class<?> rawType,
|
||||
Type[] actualTypeArguments,
|
||||
Type ownerType) {
|
||||
return new ParameterizedTypeImpl(rawType, actualTypeArguments,
|
||||
ownerType);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of <tt>Type</tt> objects representing the actual type
|
||||
* arguments to this type.
|
||||
*
|
||||
* <p>Note that in some cases, the returned array be empty. This can occur
|
||||
* if this type represents a non-parameterized type nested within
|
||||
* a parameterized type.
|
||||
*
|
||||
* @return an array of <tt>Type</tt> objects representing the actual type
|
||||
* arguments to this type
|
||||
* @throws <tt>TypeNotPresentException</tt> if any of the
|
||||
* actual type arguments refers to a non-existent type declaration
|
||||
* @throws <tt>MalformedParameterizedTypeException</tt> if any of the
|
||||
* actual type parameters refer to a parameterized type that cannot
|
||||
* be instantiated for any reason
|
||||
* @since 1.5
|
||||
*/
|
||||
public Type[] getActualTypeArguments() {
|
||||
return actualTypeArguments.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <tt>Type</tt> object representing the class or interface
|
||||
* that declared this type.
|
||||
*
|
||||
* @return the <tt>Type</tt> object representing the class or interface
|
||||
* that declared this type
|
||||
*/
|
||||
public Class<?> getRawType() {
|
||||
return rawType;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a <tt>Type</tt> object representing the type that this type
|
||||
* is a member of. For example, if this type is <tt>O<T>.I<S></tt>,
|
||||
* return a representation of <tt>O<T></tt>.
|
||||
*
|
||||
* <p>If this type is a top-level type, <tt>null</tt> is returned.
|
||||
*
|
||||
* @return a <tt>Type</tt> object representing the type that
|
||||
* this type is a member of. If this type is a top-level type,
|
||||
* <tt>null</tt> is returned
|
||||
* @throws <tt>TypeNotPresentException</tt> if the owner type
|
||||
* refers to a non-existent type declaration
|
||||
* @throws <tt>MalformedParameterizedTypeException</tt> if the owner type
|
||||
* refers to a parameterized type that cannot be instantiated
|
||||
* for any reason
|
||||
*
|
||||
*/
|
||||
public Type getOwnerType() {
|
||||
return ownerType;
|
||||
}
|
||||
|
||||
/*
|
||||
* From the JavaDoc for java.lang.reflect.ParameterizedType
|
||||
* "Instances of classes that implement this interface must
|
||||
* implement an equals() method that equates any two instances
|
||||
* that share the same generic type declaration and have equal
|
||||
* type parameters."
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof ParameterizedType) {
|
||||
// Check that information is equivalent
|
||||
ParameterizedType that = (ParameterizedType) o;
|
||||
|
||||
if (this == that)
|
||||
return true;
|
||||
|
||||
Type thatOwner = that.getOwnerType();
|
||||
Type thatRawType = that.getRawType();
|
||||
|
||||
if (false) { // Debugging
|
||||
boolean ownerEquality = (ownerType == null ?
|
||||
thatOwner == null :
|
||||
ownerType.equals(thatOwner));
|
||||
boolean rawEquality = (rawType == null ?
|
||||
thatRawType == null :
|
||||
rawType.equals(thatRawType));
|
||||
|
||||
boolean typeArgEquality = Arrays.equals(actualTypeArguments, // avoid clone
|
||||
that.getActualTypeArguments());
|
||||
for (Type t : actualTypeArguments) {
|
||||
System.out.printf("\t\t%s%s%n", t, t.getClass());
|
||||
}
|
||||
|
||||
System.out.printf("\towner %s\traw %s\ttypeArg %s%n",
|
||||
ownerEquality, rawEquality, typeArgEquality);
|
||||
return ownerEquality && rawEquality && typeArgEquality;
|
||||
}
|
||||
|
||||
return
|
||||
Objects.equals(ownerType, thatOwner) &&
|
||||
Objects.equals(rawType, thatRawType) &&
|
||||
Arrays.equals(actualTypeArguments, // avoid clone
|
||||
that.getActualTypeArguments());
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return
|
||||
Arrays.hashCode(actualTypeArguments) ^
|
||||
Objects.hashCode(ownerType) ^
|
||||
Objects.hashCode(rawType);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
if (ownerType != null) {
|
||||
if (ownerType instanceof Class)
|
||||
sb.append(((Class)ownerType).getName());
|
||||
else
|
||||
sb.append(ownerType.toString());
|
||||
|
||||
sb.append("$");
|
||||
|
||||
if (ownerType instanceof ParameterizedTypeImpl) {
|
||||
// Find simple name of nested type by removing the
|
||||
// shared prefix with owner.
|
||||
sb.append(rawType.getName().replace( ((ParameterizedTypeImpl)ownerType).rawType.getName() + "$",
|
||||
""));
|
||||
} else
|
||||
sb.append(rawType.getSimpleName());
|
||||
} else
|
||||
sb.append(rawType.getName());
|
||||
|
||||
if (actualTypeArguments != null &&
|
||||
actualTypeArguments.length > 0) {
|
||||
sb.append("<");
|
||||
boolean first = true;
|
||||
for(Type t: actualTypeArguments) {
|
||||
if (!first)
|
||||
sb.append(", ");
|
||||
sb.append(t.getTypeName());
|
||||
first = false;
|
||||
}
|
||||
sb.append(">");
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,272 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package sun.reflect.generics.reflectiveObjects;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
import java.lang.reflect.AnnotatedType;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.GenericDeclaration;
|
||||
import java.lang.reflect.Member;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Type;
|
||||
import java.lang.reflect.TypeVariable;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import sun.reflect.annotation.AnnotationSupport;
|
||||
import sun.reflect.annotation.TypeAnnotationParser;
|
||||
import sun.reflect.annotation.AnnotationType;
|
||||
import sun.reflect.generics.factory.GenericsFactory;
|
||||
import sun.reflect.generics.tree.FieldTypeSignature;
|
||||
import sun.reflect.generics.visitor.Reifier;
|
||||
import sun.reflect.misc.ReflectUtil;
|
||||
|
||||
/**
|
||||
* Implementation of <tt>java.lang.reflect.TypeVariable</tt> interface
|
||||
* for core reflection.
|
||||
*/
|
||||
public class TypeVariableImpl<D extends GenericDeclaration>
|
||||
extends LazyReflectiveObjectGenerator implements TypeVariable<D> {
|
||||
D genericDeclaration;
|
||||
private String name;
|
||||
// upper bounds - evaluated lazily
|
||||
private Type[] bounds;
|
||||
|
||||
// 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;
|
||||
|
||||
// constructor is private to enforce access through static factory
|
||||
private TypeVariableImpl(D decl, String n, FieldTypeSignature[] bs,
|
||||
GenericsFactory f) {
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method.
|
||||
* @param decl - the reflective object that declared the type variable
|
||||
* that this method should create
|
||||
* @param name - the name of the type variable to be returned
|
||||
* @param bs - an array of ASTs representing the bounds for the type
|
||||
* variable to be created
|
||||
* @param f - a factory that can be used to manufacture reflective
|
||||
* objects that represent the bounds of this type variable
|
||||
* @return A type variable with name, bounds, declaration and factory
|
||||
* specified
|
||||
*/
|
||||
public static <T extends GenericDeclaration>
|
||||
TypeVariableImpl<T> make(T decl, String name,
|
||||
FieldTypeSignature[] bs,
|
||||
GenericsFactory f) {
|
||||
|
||||
if (!((decl instanceof Class) ||
|
||||
(decl instanceof Method) ||
|
||||
(decl instanceof Constructor))) {
|
||||
throw new AssertionError("Unexpected kind of GenericDeclaration" +
|
||||
decl.getClass().toString());
|
||||
}
|
||||
return new TypeVariableImpl<T>(decl, name, bs, f);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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>.
|
||||
*
|
||||
* <p>For each upper bound B:
|
||||
* <ul>
|
||||
* <li>if B is a parameterized type or a type variable, it is created,
|
||||
* (see {@link #ParameterizedType} for the details of the creation
|
||||
* process for parameterized types).
|
||||
* <li>Otherwise, B is resolved.
|
||||
* </ul>
|
||||
*
|
||||
* @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
|
||||
* for any reason
|
||||
* @return an array of Types representing the upper bound(s) of this
|
||||
* 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?
|
||||
}
|
||||
return bounds.clone(); // return cached bounds
|
||||
}
|
||||
|
||||
/**
|
||||
* 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(){
|
||||
if (genericDeclaration instanceof Class)
|
||||
ReflectUtil.checkPackageAccess((Class)genericDeclaration);
|
||||
else if ((genericDeclaration instanceof Method) ||
|
||||
(genericDeclaration instanceof Constructor))
|
||||
ReflectUtil.conservativeCheckMemberAccess((Member)genericDeclaration);
|
||||
else
|
||||
throw new AssertionError("Unexpected kind of GenericDeclaration");
|
||||
return genericDeclaration;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the name of this type variable, as it occurs in the source code.
|
||||
*
|
||||
* @return the name of this type variable, as it appears in the source code
|
||||
*/
|
||||
public String getName() { return name; }
|
||||
|
||||
public String toString() {return getName();}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof TypeVariable &&
|
||||
o.getClass() == TypeVariableImpl.class) {
|
||||
TypeVariable<?> that = (TypeVariable<?>) o;
|
||||
|
||||
GenericDeclaration thatDecl = that.getGenericDeclaration();
|
||||
String thatName = that.getName();
|
||||
|
||||
return Objects.equals(genericDeclaration, thatDecl) &&
|
||||
Objects.equals(name, thatName);
|
||||
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return genericDeclaration.hashCode() ^ name.hashCode();
|
||||
}
|
||||
|
||||
// Implementations of AnnotatedElement methods.
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
|
||||
Objects.requireNonNull(annotationClass);
|
||||
// T is an Annotation type, the return value of get will be an annotation
|
||||
return (T)mapAnnotations(getAnnotations()).get(annotationClass);
|
||||
}
|
||||
|
||||
public <T extends Annotation> T getDeclaredAnnotation(Class<T> annotationClass) {
|
||||
Objects.requireNonNull(annotationClass);
|
||||
return getAnnotation(annotationClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {
|
||||
Objects.requireNonNull(annotationClass);
|
||||
return AnnotationSupport.getDirectlyAndIndirectlyPresent(mapAnnotations(getAnnotations()), annotationClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotationClass) {
|
||||
Objects.requireNonNull(annotationClass);
|
||||
return getAnnotationsByType(annotationClass);
|
||||
}
|
||||
|
||||
public Annotation[] getAnnotations() {
|
||||
int myIndex = typeVarIndex();
|
||||
if (myIndex < 0)
|
||||
throw new AssertionError("Index must be non-negative.");
|
||||
return TypeAnnotationParser.parseTypeVariableAnnotations(getGenericDeclaration(), myIndex);
|
||||
}
|
||||
|
||||
public Annotation[] getDeclaredAnnotations() {
|
||||
return getAnnotations();
|
||||
}
|
||||
|
||||
public AnnotatedType[] getAnnotatedBounds() {
|
||||
return TypeAnnotationParser.parseAnnotatedBounds(getBounds(),
|
||||
getGenericDeclaration(),
|
||||
typeVarIndex());
|
||||
}
|
||||
|
||||
private static final Annotation[] EMPTY_ANNOTATION_ARRAY = new Annotation[0];
|
||||
|
||||
// Helpers for annotation methods
|
||||
private int typeVarIndex() {
|
||||
TypeVariable<?>[] tVars = getGenericDeclaration().getTypeParameters();
|
||||
int i = -1;
|
||||
for (TypeVariable<?> v : tVars) {
|
||||
i++;
|
||||
if (equals(v))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private static Map<Class<? extends Annotation>, Annotation> mapAnnotations(Annotation[] annos) {
|
||||
Map<Class<? extends Annotation>, Annotation> result =
|
||||
new LinkedHashMap<>();
|
||||
for (Annotation a : annos) {
|
||||
Class<? extends Annotation> klass = a.annotationType();
|
||||
AnnotationType type = AnnotationType.getInstance(klass);
|
||||
if (type.retention() == RetentionPolicy.RUNTIME)
|
||||
if (result.put(klass, a) != null)
|
||||
throw new AnnotationFormatError("Duplicate annotation for class: "+klass+": " + a);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,231 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package sun.reflect.generics.reflectiveObjects;
|
||||
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.lang.reflect.WildcardType;
|
||||
import sun.reflect.generics.factory.GenericsFactory;
|
||||
import sun.reflect.generics.tree.FieldTypeSignature;
|
||||
import sun.reflect.generics.visitor.Reifier;
|
||||
import java.util.Arrays;
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of WildcardType interface for core reflection.
|
||||
*/
|
||||
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;
|
||||
|
||||
// constructor is private to enforce access through static factory
|
||||
private WildcardTypeImpl(FieldTypeSignature[] ubs,
|
||||
FieldTypeSignature[] lbs,
|
||||
GenericsFactory f) {
|
||||
super(f);
|
||||
upperBoundASTs = ubs;
|
||||
lowerBoundASTs = lbs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method.
|
||||
* @param ubs - an array of ASTs representing the upper bounds for the type
|
||||
* variable to be created
|
||||
* @param lbs - an array of ASTs representing the lower bounds for the type
|
||||
* variable to be created
|
||||
* @param f - a factory that can be used to manufacture reflective
|
||||
* objects that represent the bounds of this wildcard type
|
||||
* @return a wild card type with the requested bounds and factory
|
||||
*/
|
||||
public static WildcardTypeImpl make(FieldTypeSignature[] ubs,
|
||||
FieldTypeSignature[] lbs,
|
||||
GenericsFactory f) {
|
||||
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
|
||||
* bound(s) of this type variable. Note that if no upper bound is
|
||||
* explicitly declared, the upper bound is <tt>Object</tt>.
|
||||
*
|
||||
* <p>For each upper bound B :
|
||||
* <ul>
|
||||
* <li>if B is a parameterized type or a type variable, it is created,
|
||||
* (see {@link #ParameterizedType} for the details of the creation
|
||||
* process for parameterized types).
|
||||
* <li>Otherwise, B is resolved.
|
||||
* </ul>
|
||||
*
|
||||
* @return an array of Types representing the upper bound(s) of this
|
||||
* type variable
|
||||
* @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
|
||||
* 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?
|
||||
}
|
||||
return upperBounds.clone(); // return cached bounds
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of <tt>Type</tt> objects representing the
|
||||
* lower bound(s) of this type variable. Note that if no lower bound is
|
||||
* explicitly declared, the lower bound is the type of <tt>null</tt>.
|
||||
* In this case, a zero length array is returned.
|
||||
*
|
||||
* <p>For each lower bound B :
|
||||
* <ul>
|
||||
* <li>if B is a parameterized type or a type variable, it is created,
|
||||
* (see {@link #ParameterizedType} for the details of the creation
|
||||
* process for parameterized types).
|
||||
* <li>Otherwise, B is resolved.
|
||||
* </ul>
|
||||
*
|
||||
* @return an array of Types representing the lower bound(s) of this
|
||||
* type variable
|
||||
* @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
|
||||
* 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?
|
||||
}
|
||||
return lowerBounds.clone(); // return cached bounds
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
Type[] lowerBounds = getLowerBounds();
|
||||
Type[] bounds = lowerBounds;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
if (lowerBounds.length > 0)
|
||||
sb.append("? super ");
|
||||
else {
|
||||
Type[] upperBounds = getUpperBounds();
|
||||
if (upperBounds.length > 0 && !upperBounds[0].equals(Object.class) ) {
|
||||
bounds = upperBounds;
|
||||
sb.append("? extends ");
|
||||
} else
|
||||
return "?";
|
||||
}
|
||||
|
||||
assert bounds.length > 0;
|
||||
|
||||
boolean first = true;
|
||||
for(Type bound: bounds) {
|
||||
if (!first)
|
||||
sb.append(" & ");
|
||||
|
||||
first = false;
|
||||
sb.append(bound.getTypeName());
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof WildcardType) {
|
||||
WildcardType that = (WildcardType) o;
|
||||
return
|
||||
Arrays.equals(this.getLowerBounds(),
|
||||
that.getLowerBounds()) &&
|
||||
Arrays.equals(this.getUpperBounds(),
|
||||
that.getUpperBounds());
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
Type [] lowerBounds = getLowerBounds();
|
||||
Type [] upperBounds = getUpperBounds();
|
||||
|
||||
return Arrays.hashCode(lowerBounds) ^ Arrays.hashCode(upperBounds);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user