/*
* 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.
*/
/**
* Utility class containing various operations on types.
*
* <p>Unless other names are more illustrative, the following naming
* conventions should be observed in this file:
*
* <dl>
* <dt>t</dt>
* <dd>If the first argument to an operation is a type, it should be named t.</dd>
* <dt>s</dt>
* <dd>Similarly, if the second argument to an operation is a type, it should be named s.</dd>
* <dt>ts</dt>
* <dd>If an operations takes a list of types, the first should be named ts.</dd>
* <dt>ss</dt>
* <dd>A second list of types should be named ss.</dd>
* </dl>
*
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
public class Types {
final boolean allowBoxing;
final boolean allowCovariantReturns;
final boolean allowObjectToPrimitiveCast;
// <editor-fold defaultstate="collapsed" desc="Instantiating">
return instance;
}
}
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="upperBound">
/**
* The "rvalue conversion".<br>
* The upper bound of most types is the type
* itself. Wildcards, on the other hand have upper
* and lower bounds.
* @param t a type
* @return the upper bound of the given type
*/
return upperBound.visit(t);
}
// where
if (t.isSuperBound())
else
}
}
};
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="lowerBound">
/**
* The "lvalue conversion".<br>
* The lower bound of most types is the type
* itself. Wildcards, on the other hand have upper
* and lower bounds.
* @param t a type
* @return the lower bound of the given type
*/
return lowerBound.visit(t);
}
// where
}
return visit(t.getLowerBound());
}
};
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="isUnbounded">
/**
* Checks that all the arguments to a class are unbounded
* wildcards or something else that doesn't make any restrictions
* on the arguments. If a class isUnbounded, a raw super- or
* subclass can be cast to it without a warning.
* @param t a type
* @return true iff the given type is unbounded or raw
*/
return isUnbounded.visit(t);
}
// where
return true;
}
return false;
}
return true;
}
};
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="asSub">
/**
* Return the least specific subtype of t that starts with symbol
* sym. If none exists, return null. The least specific subtype
* is determined as follows:
*
* <p>If there is exactly one parameterized instance of sym that is a
* subtype of t, that parameterized instance is returned.<br>
* Otherwise, if the plain type or raw type `sym' is a subtype of
* type t, the type `sym' itself is returned. Otherwise, null is
* returned.
*/
}
// where
return null;
}
return t;
return null;
try {
} catch (AdaptFailure ex) {
return null;
}
return null;
if (t.isRaw()) {
// The subtype of a raw type is raw
} else {
// Unbound type arguments default to ?
qs.append(new WildcardType(syms.objectType, BoundKind.UNBOUND, syms.boundClass, (TypeVar) iter.head));
}
}
}
return res;
}
return t;
}
};
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="isConvertible">
/**
* conversion to s?
*/
return true;
boolean tPrimitive = t.isPrimitive();
boolean sPrimitive = s.isPrimitive();
if (tPrimitive == sPrimitive) {
return isSubtypeUnchecked(t, s, warn);
}
if (!allowBoxing) return false;
return tPrimitive
: isSubtype(unboxedType(t), s);
}
/**
* convertions to s?
*/
}
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="isSubtype">
/**
* Is t an unchecked subtype of s?
*/
}
/**
* Is t an unchecked subtype of s?
*/
if (result) {
checkUnsafeVarargsConversion(t, s, warn);
}
return result;
}
//where
} else {
}
} else if (isSubtype(t, s)) {
return true;
}
}
}
else if (!s.isRaw()) {
if (isReifiable(s))
else
return true;
}
}
return false;
}
boolean shouldWarn = false;
switch (s.tag) {
case ARRAY:
!isReifiable(from);
break;
case CLASS:
break;
}
if (shouldWarn) {
}
}
/**
* Is t a subtype of s?<br>
* (not defined for Method and ForAll types)
*/
return isSubtype(t, s, true);
}
return isSubtype(t, s, false);
}
if (t == s)
return true;
if (s.tag >= firstPartialTag)
return isSuperType(s, t);
if (s.isCompound()) {
return false;
}
return true;
}
if (s != lower)
}
// where
{
switch (t.tag) {
case TYPEVAR:
return isSubtypeNoCapture(t.getUpperBound(), s);
case BOT:
return
case WILDCARD: //we shouldn't be here - avoids crash (see 7034495)
case NONE:
return false;
default:
}
}
try {
return containsType(t.getTypeArguments(),
s.getTypeArguments());
} finally {
}
} else {
return containsType(t.getTypeArguments(),
rewriteSupers(s).getTypeArguments());
}
}
if (!t.isParameterized())
return t;
return t;
boolean changed = false;
if (s.isSuperBound() && !s.isExtendsBound()) {
changed = true;
} else if (s != orig) {
s = new WildcardType(upperBound(s),
changed = true;
}
}
if (changed)
else
return t;
}
// You're not allowed to write
// Vector<Object> vec = new Vector<String>();
// But with wildcards you can write
// Vector<? extends Object> vec = new Vector<String>();
// which means that subtype checking must be done
// here instead of same-type checking (via containsType).
s.getEnclosingType());
}
else
}
}
return false;
}
//todo: test against origin needed? or replace with substitution?
return true;
return true;
}
return true;
}
};
/**
* Is t a subtype of every type in given list `ts'?<br>
* (not defined for Method and ForAll types)<br>
* Allows unchecked conversions.
*/
return false;
return true;
}
/**
* Are corresponding elements of ts subtypes of ss? If lists are
* of different length, return false.
*/
/*inlined: ts.nonEmpty() && ss.nonEmpty()*/ &&
}
/*inlined: ts.isEmpty() && ss.isEmpty();*/
}
/**
* Are corresponding elements of ts subtypes of ss, allowing
* unchecked conversions? If lists are of different length,
* return false.
**/
/*inlined: ts.nonEmpty() && ss.nonEmpty()*/ &&
}
/*inlined: ts.isEmpty() && ss.isEmpty();*/
}
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="isSuperType">
/**
* Is t a supertype of s?
*/
switch (t.tag) {
case ERROR:
return true;
case UNDETVAR: {
if (t == s ||
return true;
}
default:
return isSubtype(s, t);
}
}
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="isSameType">
/**
* Are corresponding elements of the lists the same type? If
* lists are of different length, return false.
*/
/*inlined: ts.nonEmpty() && ss.nonEmpty()*/ &&
}
/*inlined: ts.isEmpty() && ss.isEmpty();*/
}
/**
* Is t the same type as s?
*/
return isSameType.visit(t, s);
}
// where
if (t == s)
return true;
if (s.tag >= firstPartialTag)
return visit(s, t);
switch (t.tag) {
case TYPEVAR: {
//type-substitution does not preserve type-var types
//check that type var symbols and bounds are indeed the same
}
else {
//special case for s == ? super X, where upper(s) = u
//check that u == t, where u has been set by Type.withTypeVar
return s.isSuperBound() &&
!s.isExtendsBound() &&
visit(t, upperBound(s));
}
}
default:
}
}
if (s.tag >= firstPartialTag)
return visit(s, t);
else
return false;
}
if (t == s)
return true;
if (s.tag >= firstPartialTag)
return visit(s, t);
if (s.isSuperBound() && !s.isExtendsBound())
if (t.isCompound() && s.isCompound()) {
return false;
for (Type x : interfaces(t))
for (Type x : interfaces(s)) {
return false;
}
}
}
if (t == s)
return true;
if (s.tag >= firstPartialTag)
return visit(s, t);
}
// isSameType for methods does not take thrown
// exceptions into account!
}
return t == s;
}
return false;
return hasSameBounds(t, forAll)
}
// FIXME, this might be leftovers from before capture conversion
return false;
return true;
return false;
}
return false;
}
return true;
}
return true;
}
};
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="fromUnknownFun">
/**
* A mapping that turns all unknown types in this type to fresh
* unknown variables.
*/
else return t.map(this);
}
};
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="Contains Type">
switch (t.tag) {
case UNDETVAR:
case UNBOUND: //similar to ? extends Object
case EXTENDS: {
// We should check the new upper bound against any of the
// undetvar's lower bounds.
return false;
}
break;
}
case SUPER: {
// We should check the new lower bound against any of the
// undetvar's lower bounds.
return false;
}
break;
}
}
return true;
} else {
return isSameType(t, s);
}
case ERROR:
return true;
default:
return containsType(s, t);
}
}
}
}
/**
* Check if t contains s.
*
* <p>T contains S if:
*
* <p>{@code L(T) <: L(S) && U(S) <: U(T)}
*
* <p>This relation is only used by ClassType.isSubtype(), that
* is,
*
* <p>{@code C<S> <: C<T> if T contains S.}
*
* <p>Because of F-bounds, this relation can lead to infinite
* recursion. Thus we must somehow break that recursion. Notice
* that containsType() is only called from ClassType.isSubtype().
* Since the arguments have already been checked against their
* bounds, we know:
*
* <p>{@code U(S) <: U(T) if T is "super" bound (U(T) *is* the bound)}
*
* <p>{@code L(T) <: L(S) if T is "extends" bound (L(T) is bottom)}
*
* @param t a type
* @param s a type
*/
return containsType.visit(t, s);
}
// where
WildcardType w = (WildcardType)t;
if (w.isSuperBound())
else
t = w.type;
}
return t;
}
WildcardType w = (WildcardType)t;
if (w.isExtendsBound())
else
t = w.type;
}
return t;
}
if (s.tag >= firstPartialTag)
return containedBy(s, t);
else
return isSameType(t, s);
}
// void debugContainsType(WildcardType t, Type s) {
// System.err.println();
// System.err.format(" does %s contain %s?%n", t, s);
// System.err.format(" %s U(%s) <: U(%s) %s = %s%n",
// upperBound(s), s, t, U(t),
// t.isSuperBound()
// || isSubtypeNoCapture(upperBound(s), U(t)));
// System.err.format(" %s L(%s) <: L(%s) %s = %s%n",
// L(t), t, s, lowerBound(s),
// t.isExtendsBound()
// || isSubtypeNoCapture(L(t), lowerBound(s)));
// System.err.println();
// }
if (s.tag >= firstPartialTag)
return containedBy(s, t);
else {
// debugContainsType(t, s);
return isSameWildcard(t, s)
|| isCaptureOf(s, t)
}
}
return isSameType(t, s);
else
return false;
}
return true;
}
};
return false;
}
return false;
WildcardType w = (WildcardType)s;
}
}
}
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="isCastable">
}
/**
* Is t is castable to s?<br>
* s is assumed to be an erased type.<br>
* (not defined for Method and ForAll types).
*/
if (t == s)
return true;
if (t.isPrimitive() != s.isPrimitive())
return allowBoxing && (
isConvertible(t, s, warn)
|| (allowObjectToPrimitiveCast &&
s.isPrimitive() &&
try {
checkUnsafeVarargsConversion(t, s, warn);
return isCastable.visit(t,s);
} finally {
}
} else {
return isCastable.visit(t,s);
}
}
// where
return true;
switch (t.tag) {
case DOUBLE:
case BOOLEAN:
case VOID:
return false;
case BOT:
return isSubtype(t, s);
default:
throw new AssertionError();
}
}
}
return true;
return true;
} else {
return false;
}
}
if (t.isCompound()) {
return false;
return false;
}
return true;
}
if (s.isCompound()) {
// call recursively to reuse the above code
return visitClassType((ClassType)s, t);
}
boolean upcast;
if (!isReifiable(s))
return true;
} else if (s.isRaw()) {
return true;
} else if (t.isRaw()) {
if (!isUnbounded(s))
return true;
}
// Assume |a| <: |b|
final boolean HIGH = true;
final boolean LOW = false;
final boolean DONT_REWRITE_TYPEVARS = false;
final boolean REWRITE_TYPEVARS = true;
}
}
if (upcast ? giveWarning(a, b) :
giveWarning(b, a))
return true;
}
}
if (isReifiable(s))
return isSubtypeUnchecked(a, b);
else
}
// Sidecast
} else {
// unrelated class types
return false;
}
}
}
return false;
}
switch (s.tag) {
case ERROR:
case BOT:
return true;
case TYPEVAR:
return true;
} else {
return false;
}
case CLASS:
return isSubtype(t, s);
case ARRAY:
} else {
}
default:
return false;
}
}
switch (s.tag) {
case ERROR:
case BOT:
return true;
case TYPEVAR:
if (isSubtype(t, s)) {
return true;
return true;
} else {
return false;
}
default:
}
}
return true;
}
};
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="disjointTypes">
}
return false;
}
/**
* Two types or wildcards are considered disjoint if it can be
* proven that no type can be contained in both. It is
* conservative in that it is allowed to say that two types are
* not disjoint, even though they actually are.
*
* The type C<X> is castable to C<Y> exactly if X and Y are not
* disjoint.
*/
return disjointType.visit(t, s);
}
// where
return visit(s, t);
else
return notSoftSubtypeRecursive(t, s) || notSoftSubtypeRecursive(s, t);
}
try {
return Types.this.isCastable(t, s);
} finally {
}
} else {
return true;
}
}
try {
return Types.this.notSoftSubtype(t, s);
} finally {
}
} else {
return false;
}
}
if (t.isUnbound())
return false;
if (t.isExtendsBound())
return notSoftSubtypeRecursive(s, t.type);
else // isSuperBound()
return notSoftSubtypeRecursive(t.type, s);
}
if (s.isUnbound())
return false;
if (t.isExtendsBound()) {
if (s.isExtendsBound())
else if (s.isSuperBound())
} else if (t.isSuperBound()) {
if (s.isExtendsBound())
}
return false;
}
};
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="lowerBoundArgtypes">
/**
* Returns the lower bounds of the formals of a method.
*/
}
return lowerBound(t);
}
};
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="notSoftSubtype">
/**
* This relation answers the question: is impossible that
* something of type `t' can be a subtype of `s'? This is
* different from the question "is `t' not a subtype of `s'?"
* when type variables are involved: Integer is not a subtype of T
* where <T extends Number> but it is not true that Integer cannot
* possibly be a subtype of T.
*/
if (t == s) return false;
relaxBound(s),
}
s = upperBound(s);
return !isSubtype(t, relaxBound(s));
}
t = t.getUpperBound();
t = rewriteQuantifiers(t, true, true);
}
return t;
}
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="isReifiable">
return isReifiable.visit(t);
}
// where
return true;
}
if (t.isCompound())
return false;
else {
if (!t.isParameterized())
return true;
return false;
}
return true;
}
}
}
return false;
}
};
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="Array Utils">
t = upperBound(t);
}
/**
* The element type of an array.
*/
switch (t.tag) {
case WILDCARD:
return elemtype(upperBound(t));
case ARRAY:
case FORALL:
case ERROR:
return t;
default:
return null;
}
}
elemtype :
t;
}
/**
* Mapping to take element type of an arraytype
*/
};
/**
* The number of dimensions of an array type.
*/
int result = 0;
result++;
t = elemtype(t);
}
return result;
}
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="asSuper">
/**
* Return the (most specific) base type of t that starts with the
* given symbol. If none exists, return null.
*
* @param t a type
* @param sym a symbol
*/
}
// where
return null;
}
return t;
if (x != null)
return x;
}
if (x != null)
return x;
}
}
return null;
}
}
return t;
else
}
return t;
}
};
/**
* Return the base type of t or any of its outer types that starts
* with the given symbol. If none exists, return null.
*
* @param t a type
* @param sym a symbol
*/
switch (t.tag) {
case CLASS:
do {
if (s != null) return s;
t = t.getEnclosingType();
return null;
case ARRAY:
case TYPEVAR:
case ERROR:
return t;
default:
return null;
}
}
/**
* Return the base type of t or any of its enclosing types that
* starts with the given symbol. If none exists, return null.
*
* @param t a type
* @param sym a symbol
*/
switch (t.tag) {
case CLASS:
do {
if (s != null) return s;
return null;
case ARRAY:
case TYPEVAR:
case ERROR:
return t;
default:
return null;
}
}
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="memberType">
/**
* The type of given symbol, seen as a member of t.
*
* @param t a type
* @param sym a symbol
*/
}
// where
}
}
//if t is an intersection type T = CT & I1 & I2 ... & In
//its supertypes CT, I1, ... In might contain wildcards
//so we need to go through capture conversion
if (ownerParams.nonEmpty()) {
if (baseParams.isEmpty()) {
// then base is a raw type
} else {
}
}
}
}
}
}
return t;
}
};
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="isAssignable">
}
/**
* Is t assignable to s?<br>
* Equivalent to subtype except for constant values and raw
* types.<br>
* (not defined for Method and ForAll types)
*/
return true;
switch (s.tag) {
case BYTE:
return true;
break;
case CHAR:
return true;
break;
case SHORT:
return true;
break;
case INT:
return true;
case CLASS:
switch (unboxedType(s).tag) {
case BYTE:
case CHAR:
case SHORT:
}
break;
}
}
return isConvertible(t, s, warn);
}
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="erasure">
/**
* The erasure of t {@code |t|} -- the type that results when all
* type parameters in t are deleted.
*/
return eraseNotNeeded(t)? t : erasure(t, false);
}
//where
}
//where
if (t.tag <= lastBaseTag)
return t; /* fast special case */
else
}
// where
if (t.tag <= lastBaseTag)
return t; /*fast special case*/
else
}
}
if (recurse) {
}
return erased;
}
}
return t;
}
};
};
};
}
return erasure(t, true);
}
}
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="makeCompoundType">
/**
* Make a compound type from non-empty list of types
*
* @param bounds the types from which the compound type is formed
* @param supertype is objectType if all bounds are interfaces,
* null otherwise.
*/
// error condition, recover
else
} else {
}
return bt;
}
/**
* Same as {@link #makeCompoundType(List,Type)}, except that the
* second parameter is computed directly. Note that this might
* cause a symbol completion. Hence, this version of
* makeCompoundType may not be called during a classfile read.
*/
}
/**
* A convenience wrapper for {@link #makeCompoundType(List)}; the
* arguments are converted to a list and passed to the other
* method. Note that this might cause a symbol completion.
* Hence, this version of makeCompoundType may not be called
* during a classfile read.
*/
}
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="supertype">
}
// where
// A note on wildcards: there is no good way to
// determine a supertype for a super bounded wildcard.
return null;
}
if (t.supertype_field == null) {
// An interface has no superclass; its supertype is Object.
if (t.isInterface())
if (t.supertype_field == null) {
if (t.hasErasedSupertypes()) {
}
else {
t.supertype_field = supertype;
}
}
}
return t.supertype_field;
}
/**
* The supertype is always a class type. If the type
* variable's bounds start with a class type, this is also
* the supertype. Otherwise, the supertype is
* java.lang.Object.
*/
return t.bound;
} else {
}
}
return arraySuperType();
else
}
return t;
}
};
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="interfaces">
/**
* Return the interfaces implemented by this class.
*/
return interfaces.visit(t);
}
// where
}
if (t.interfaces_field == null) {
if (t.interfaces_field == null) {
// If t.interfaces_field is null, then t must
// be a parameterized type (not to be confused
// with a generic type declaration).
// Terminology:
// Parameterized type: List<String>
// Generic type declaration: class List<E> { ... }
// So t corresponds to List<String> and
// t.tsym.type corresponds to List<E>.
// The reason t must be parameterized type is
// that completion will happen as a side
// effect of calling
// ClassSymbol.getInterfaces. Since
// t.interfaces_field is null after
// completion, we can assume that t is not the
if (t.hasErasedSupertypes()) {
t.interfaces_field =
}
else {
}
}
}
return t.interfaces_field;
}
if (t.bound.isCompound())
return interfaces(t.bound);
if (t.bound.isInterface())
}
};
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="isDerivedRaw">
result = isDerivedRawInternal(t);
}
return result;
}
if (t.isErroneous())
return false;
return
t.isRaw() ||
isDerivedRaw(interfaces(t));
}
return l.nonEmpty();
}
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="setBounds">
/**
* Set the bounds field of the given type variable to reflect a
* (possibly multiple) list of bounds.
* @param t a type variable
* @param bounds the bounds, must be nonempty
* @param supertype is objectType if all bounds are interfaces,
* null otherwise.
*/
else
t.rank_field = -1;
}
/**
* Same as {@link #setBounds(Type.TypeVar,List,Type)}, except that
* third parameter is computed directly, as follows: if all
* all bounds are interface types, the computed supertype is Object,
* otherwise the supertype is simply left null (in this case, the supertype
* is assumed to be the head of the bound list passed as second argument).
* Note that this check might cause a symbol completion. Hence, this version of
* setBounds may not be called during a classfile read.
*/
t.rank_field = -1;
}
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="getBounds">
/**
* Return list of bounds of the given type variable.
*/
else
// No superclass was given in bounds.
// In this case, supertype is Object, erasure is first interface.
return interfaces(t);
}
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="classBound">
/**
* If the given type is a (possibly selected) type variable,
* return the bounding class of this type, otherwise return the
* type itself.
*/
return classBound.visit(t);
}
// where
return t;
}
if (outer1 != t.getEnclosingType())
else
return t;
}
return classBound(supertype(t));
}
return t;
}
};
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="sub signature / override equivalence">
/**
* Returns true iff the first signature is a <em>sub
* signature</em> of the other. This is <b>not</b> an equivalence
* relation.
*
* @jls section 8.4.2.
* @see #overrideEquivalent(Type t, Type s)
* @param t first signature (possibly raw).
* @param s second signature (could be subjected to erasure).
* @return true if t is a sub signature of s.
*/
return isSubSignature(t, s, true);
}
}
/**
* Returns true iff these signatures are related by <em>override
* equivalence</em>. This is the natural extension of
* isSubSignature to an equivalence relation.
*
* @jls section 8.4.2.
* @see #isSubSignature(Type t, Type s)
* @param t a signature (possible raw, could be subjected to
* erasure).
* @param s a signature (possible raw, could be subjected to
* erasure).
* @return true if either argument is a sub signature of the other.
*/
return hasSameArgs(t, s) ||
}
// <editor-fold defaultstate="collapsed" desc="Determining method implementation in given site">
class ImplementationCache {
class Entry {
final boolean checkResult;
final int prevMark;
boolean checkResult,
int prevMark) {
this.cachedImpl = cachedImpl;
this.implFilter = scopeFilter;
this.checkResult = checkResult;
}
return this.implFilter == scopeFilter &&
this.checkResult == checkResult &&
}
}
MethodSymbol get(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter<Symbol> implFilter) {
}
if (e == null ||
return impl;
}
else {
return e.cachedImpl;
}
}
private MethodSymbol implementationInternal(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter<Symbol> implFilter) {
t = t.getUpperBound();
TypeSymbol c = t.tsym;
e = e.next(implFilter)) {
return (MethodSymbol)e.sym;
}
}
return null;
}
}
public MethodSymbol implementation(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter<Symbol> implFilter) {
}
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="compute transitive closure of all members in given site">
class Entry {
final boolean skipInterfaces;
this.skipInterfaces = skipInterfaces;
this.compoundScope = compoundScope;
}
return this.skipInterfaces == skipInterfaces;
}
}
/** members closure visitor methods **/
return null;
}
if (!skipInterface) {
for (Type i : interfaces(t)) {
}
}
}
return e.compoundScope;
}
}
}
}
// </editor-fold>
/**
* Does t have the same arguments as s? It is assumed that both
* types are (possibly polymorphic) method types. Monomorphic
* method types "have the same arguments", if their argument lists
* are equal. Polymorphic method types "have the same arguments",
* if they have the same arguments after renaming all type
* variables of one to corresponding type variables in the other,
* where correspondence is by position in the type parameter list.
*/
return hasSameArgs(t, s, true);
}
}
return hasSameArgs.visit(t, s);
}
// where
boolean strict;
}
throw new AssertionError();
}
}
return hasSameBounds(t, forAll)
}
return false;
}
};
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="subst">
}
/**
* Substitute all occurrences of a type in `from' with the
* corresponding type in `to' in 't'. Match lists `from' and `to'
* from the right: If lists have different length, discard leading
* elements of the longer list.
*/
}
while (fromLength > toLength) {
fromLength--;
}
while (fromLength < toLength) {
toLength--;
}
}
return t;
else
return visit(t);
}
return ts;
boolean wild = false;
}
return ts;
}
return t;
}
return t;
else
}
}
}
return t;
}
if (!t.isCompound()) {
return t;
else
} else {
return t;
else
}
}
return t;
} else {
}
}
return t;
else
}
//perform alpha-renaming of free-variables in 't'
//if 'to' types contain variables that are free in 't'
}
return t;
} else {
}
}
return t;
}
}
return tvars;
boolean changed = false;
// calculate new bounds
changed = true;
}
if (!changed)
return tvars;
// create new type variables without bounds
}
// the new bounds should use the new type variables in place
// of the old
}
// set the bounds of new type variables to the new bounds
}
}
return t;
else {
// create new type variable without bounds
// the new bound should use the new type variable in place
// of the old
return tv;
}
}
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="hasSameBounds">
/**
* Does t have the same bounds for quantified variables as s?
*/
s.tvars,
t.tvars))) {
}
}
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="newInstances">
/** Create new vector of type variables from list of variables
* changing all recursive bounds from old to new list.
*/
}
return tvars1;
}
};
// </editor-fold>
}
// where
throw new IllegalArgumentException("Not a method type: " + t);
}
}
}
};
}
// where
throw new IllegalArgumentException("Not a method type: " + t);
}
}
}
};
}
// where
throw new IllegalArgumentException("Not a method type: " + t);
}
}
}
};
// <editor-fold defaultstate="collapsed" desc="createErrorType">
}
return new ErrorType(c, originalType);
}
}
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="rank">
/**
* The rank of a class is the length of the longest path between
* the class and java.lang.Object in the class inheritance
* graph. Undefined for all but reference types.
*/
switch(t.tag) {
case CLASS: {
else {
l.nonEmpty();
l = l.tail) {
}
}
}
return cls.rank_field;
}
case TYPEVAR: {
l.nonEmpty();
l = l.tail) {
}
}
return tvar.rank_field;
}
case ERROR:
return 0;
default:
throw new AssertionError();
}
}
// </editor-fold>
/**
* Helper method for generating a string representation of a given type
* accordingly to a given locale
*/
}
/**
* Helper method for generating a string representation of a given type
* accordingly to a given locale
*/
}
// <editor-fold defaultstate="collapsed" desc="toString">
/**
* This toString is slightly more descriptive than the one on Type.
*
* @deprecated Types.toString(Type t, Locale l) provides better support
* for localization
*/
}
return "" + t;
}
// where
StringBuilder s = new StringBuilder();
s.append('<');
boolean first = true;
first = false;
appendTyparamString(((TypeVar)t), s);
}
s.append('>');
return s.toString();
}
return;
if (!bound.isCompound()) {
}
} else {
// No superclass was given in bounds.
// In this case, supertype is Object, erasure is first interface.
boolean first = true;
first = false;
}
}
}
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="Determining least upper bounds of types">
/**
* A cache for closures.
*
* <p>A closure is a list of all the supertypes and interfaces of
* a class or interface type, ordered by ClassSymbol.precedes
* (that is, subclasses come first, arbitrary but fixed
* otherwise).
*/
/**
* Returns the closure of a class or interface type.
*/
if (!t.isCompound()) {
} else {
}
} else {
}
}
return cl;
}
/**
* Insert a type in a closure
*/
} else {
return cl;
}
}
/**
* Form the union of two closures
*/
return cl2;
return cl1;
} else {
}
}
/**
* Intersect two closures
*/
return cl1;
}
}
}
// where
class TypePair {
}
public int hashCode() {
}
return false;
}
}
} else {
Type m;
} else {
}
}
}
}
/**
* Return the minimum type of a closure, a compound type if no
* unique minimum exists.
*/
return null;
else
return makeCompoundType(compound);
}
/**
* Return the minimum types of a closure, suitable for computing
* compoundMin or glb.
*/
if (current.isInterface())
else
if (!isSubtypeNoCapture(current, t))
candidates.append(t);
}
}
}
/**
* Return the least upper bound of pair of types. if the lub does
* not exist return null.
*/
}
/**
* Return the least upper bound (lub) of set of types. If the lub
* does not exist return the type of null (bottom).
*/
final int ARRAY_BOUND = 1;
final int CLASS_BOUND = 2;
int boundkind = 0;
switch (t.tag) {
case CLASS:
boundkind |= CLASS_BOUND;
break;
case ARRAY:
boundkind |= ARRAY_BOUND;
break;
case TYPEVAR:
do {
t = t.getUpperBound();
boundkind |= ARRAY_BOUND;
} else {
boundkind |= CLASS_BOUND;
}
break;
default:
if (t.isPrimitive())
}
}
switch (boundkind) {
case 0:
case ARRAY_BOUND:
// calculate lub(A[], B[])
if (t.isPrimitive()) {
// if a primitive type is found, then return
// arraySuperType unless all the types are the
// same
if (!isSameType(first, s)) {
// lub(int[], B[]) is Cloneable & Serializable
return arraySuperType();
}
}
// all the array types are the same, return one
// lub(int[], int[]) is int[]
return first;
}
}
// lub(A[], B[]) is lub(A, B)[]
case CLASS_BOUND:
// calculate lub(A, B)
//step 1 - compute erased candidate set (EC)
}
//step 2 - compute minimal erased candidate set (MEC)
//step 3 - for each element G in MEC, compute lci(Inv(G))
}
}
//step 4 - let MEC be { G1, G2 ... Gn }, then we have that
//lub = lci(Inv(G1)) & lci(Inv(G2)) & ... & lci(Inv(Gn))
return compoundMin(candidates);
default:
// calculate lub(A, B[])
}
// lub(A, B[]) is lub(A, arraySuperType)
}
}
// where
} else {
}
}
}
// initialized lazily to avoid problems during compiler startup
if (arraySuperType == null) {
synchronized (this) {
if (arraySuperType == null) {
// JLS 10.8: all arrays implement Cloneable and Serializable.
}
}
}
return arraySuperType;
}
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="Greatest lower bound">
if (t1.isErroneous())
return t1;
}
return t1;
}
//where
if (s == null)
return t;
else if (t.isPrimitive() || s.isPrimitive())
else if (isSubtypeNoCapture(t, s))
return t;
else if (isSubtypeNoCapture(s, t))
return s;
return syms.objectType;
} else { // length > 1
int classCount = 0;
if (!bound.isInterface())
classCount++;
if (classCount > 1)
return createErrorType(t);
}
return makeCompoundType(bounds);
}
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="hashCode">
/**
* Compute a hash code on a type.
*/
}
// where
return t.tag;
}
result *= 127;
for (Type s : t.getTypeArguments()) {
result *= 127;
}
return result;
}
result *= 127;
}
return result;
}
}
}
return System.identityHashCode(t);
}
return 0;
}
};
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="Return-Type-Substitutable">
/**
* Does t have a result that is a subtype of the result type of s,
* suitable for covariant returns? It is assumed that both types
* are (possibly polymorphic) method types. Monomorphic method
* types are handled in the obvious way. Polymorphic method types
* require renaming all type variables of one to corresponding
* type variables in the other, where correspondence is by
* position in the type parameter list. */
}
/**
* Return-Type-Substitutable.
* @jls section 8.4.5
*/
else
}
return true;
return false;
if (!allowCovariantReturns)
return false;
return true;
return false;
return true;
}
/**
* Is t an appropriate return type in an overrider for a
* method that returns s?
*/
return
isSameType(t, s) ||
!t.isPrimitive() &&
!s.isPrimitive() &&
isAssignable(t, s, warner);
}
// </editor-fold>
/**
* Return the class that boxes the given primitive.
*/
}
/**
* Return the boxed type if 't' is primitive, otherwise return 't' itself.
*/
return t.isPrimitive() ?
boxedClass(t).type :
t;
}
/**
* Return the primitive type corresponding to a boxed type.
*/
if (allowBoxing) {
}
}
}
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="Capture conversion">
/*
* JLS 5.1.10 Capture Conversion:
*
* Let G name a generic type declaration with n formal type
* parameters A1 ... An with corresponding bounds U1 ... Un. There
* exists a capture conversion from G<T1 ... Tn> to G<S1 ... Sn>,
* where, for 1 <= i <= n:
*
* + If Ti is a wildcard type argument (4.5.1) of the form ? then
* Si is a fresh type variable whose upper bound is
* Ui[A1 := S1, ..., An := Sn] and whose lower bound is the null
* type.
*
* + If Ti is a wildcard type argument of the form ? extends Bi,
* then Si is a fresh type variable whose upper bound is
* glb(Bi, Ui[A1 := S1, ..., An := Sn]) and whose lower bound is
* the null type, where glb(V1,... ,Vm) is V1 & ... & Vm. It is
* a compile-time error if for any two classes (not interfaces)
* Vi and Vj,Vi is not a subclass of Vj or vice versa.
*
* + If Ti is a wildcard type argument of the form ? super Bi,
* then Si is a fresh type variable whose upper bound is
* Ui[A1 := S1, ..., An := Sn] and whose lower bound is Bi.
*
* + Otherwise, Si = Ti.
*
* Capture conversion on any type other than a parameterized type
* (4.5) acts as an identity conversion (5.1.1). Capture
* conversions never require a special action at run time and
* therefore never throw an exception at run time.
*
* Capture conversion is not applied recursively.
*/
/**
* Capture conversion as specified by the JLS.
*/
}
}
return t;
if (capturedEncl != t.getEnclosingType()) {
}
}
return cls;
boolean captured = false;
captured = true;
case UNBOUND:
break;
case EXTENDS:
break;
case SUPER:
break;
}
}
}
return erasure(t); // some "rare" type involved
if (captured)
else
return t;
}
// where
(WildcardType)t));
} else {
}
}
}
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="Internal utility methods">
else
return ss;
}
// We are casting from type $from$ to type $to$, which are
// non-final unrelated types. This method
// tries to reject a cast by transferring type parameters
// from $to$ to $from$ by common superinterfaces.
boolean reverse = false;
reverse = true;
}
// The arguments to the supers could be unified here to
// get a more accurate analysis
while (commonSupers.nonEmpty()) {
return false;
}
if (!allowCovariantReturns)
// reject if there is a common method signature with
// incompatible return types.
return true;
}
// We are casting from type $from$ to type $to$, which are
// unrelated types one of which is final and the other of
// which is an interface. This method
// tries to reject a cast by transferring type parameters
// from the final class to the interface.
boolean reverse = false;
reverse = true;
}
return false;
if (!allowCovariantReturns)
// reject if there is a common method signature with
// incompatible return types.
if (!isReifiable(target) &&
return true;
}
return to.isParameterized() &&
(!(isUnbounded(to) ||
}
} else {
}
}
return cl;
}
return
isSameType(t, s) || // shortcut
containsType(t, s) && containsType(s, t);
}
// <editor-fold defaultstate="collapsed" desc="adapt">
/**
* Adapt a type by computing a substitution which maps a source
* type to a target type.
*
* @param source the source type
* @param target the target type
* @param from the type variables of the computed substitution
* @param to the types of the computed substitution.
*/
}
}
}
}
return null;
}
return null;
}
if (source.isExtendsBound())
else if (source.isSuperBound())
return null;
}
// Check to see if there is
// already a mapping for $source$, in which case
// the old mapping will be merged with the new
throw new AdaptFailure();
}
} else {
}
return null;
}
return null;
}
try {
} finally {
}
}
}
}
}
}
}
}
try {
//if (t.tsym.type != t)
} catch (AdaptFailure ex) {
// Adapt should never fail calculating a mapping from
// t.tsym.type to t as there can be no merge problem.
throw new AssertionError(ex);
}
}
// </editor-fold>
/**
* Rewrite all type variables (universal quantifiers) in the given
* type to wildcards (existential quantifiers). This is used to
* determine if a cast is allowed. For example, if high is true
* and {@code T <: Number}, then {@code List<T>} is rewritten to
* {@code List<? extends Number>}. Since {@code List<Integer> <:
* List<? extends Number>} a {@code List<T>} can be cast to {@code
* List<Integer>} with a warning.
* @param t a type
* @param high if true return an upper bound; otherwise a lower
* bound
* @param rewriteTypeVars only rewrite captured wildcards if false;
* otherwise rewrite all type variables
* @return the type rewritten with wildcards (existential
* quantifiers) only
*/
}
boolean high;
boolean rewriteTypeVars;
this.rewriteTypeVars = rewriteTypeVars;
}
boolean changed = false;
changed = true;
}
}
if (changed)
else
return t;
}
}
}
if (rewriteTypeVars) {
return rewriteAsWildcardType(bound, t);
}
else
return t;
}
t.getSuperBound();
}
return high ?
}
WildcardType w = (WildcardType)t;
t = high ?
w.getExtendsBound() :
w.getSuperBound();
if (t == null) {
}
}
return t;
}
}
/**
* Create a wildcard with the given upper (extends) bound; create
* an unbounded wildcard if bound is Object.
*
* @param bound the upper bound
* @param formal the formal type parameter that will be
* substituted by the wildcard
*/
formal);
} else {
return new WildcardType(bound,
formal);
}
}
/**
* Create a wildcard with the given lower (super) bound; create an
* unbounded wildcard if bound is bottom (type of {@code null}).
*
* @param bound the lower bound
* @param formal the formal type parameter that will be
* substituted by the wildcard
*/
formal);
} else {
return new WildcardType(bound,
formal);
}
}
/**
* A wrapper for a type that allows use in sets.
*/
class SingletonType {
final Type t;
this.t = t;
}
public int hashCode() {
}
return (obj instanceof SingletonType) &&
}
return t.toString();
}
}
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="Visitors">
/**
* A default visitor for types. All visitor methods except
* visitType are implemented by delegating to visitType. Concrete
* subclasses must provide an implementation of visitType and can
* override other methods as needed.
*
* @param <R> the return type of the operation implemented by this
* visitor; use Void if no return type is needed.
* @param <S> the type of the second argument (the first being the
* type itself) of the operation implemented by this visitor; use
* Void if a second argument is not needed.
*/
}
/**
* A default visitor for symbols. All visitor methods except
* visitSymbol are implemented by delegating to visitSymbol. Concrete
* subclasses must provide an implementation of visitSymbol and can
* override other methods as needed.
*
* @param <R> the return type of the operation implemented by this
* visitor; use Void if no return type is needed.
* @param <S> the type of the second argument (the first being the
* symbol itself) of the operation implemented by this visitor; use
* Void if a second argument is not needed.
*/
}
/**
* A <em>simple</em> visitor for types. This visitor is simple as
* captured wildcards, for-all types (generic methods), and
* undetermined type variables (part of inference) are hidden.
* Captured wildcards are hidden by treating them as type
* variables and the rest are hidden by visiting their qtypes.
*
* @param <R> the return type of the operation implemented by this
* visitor; use Void if no return type is needed.
* @param <S> the type of the second argument (the first being the
* type itself) of the operation implemented by this visitor; use
* Void if a second argument is not needed.
*/
return visitTypeVar(t, s);
}
}
}
}
/**
* A plain relation on types. That is a 2-ary function on the
* form Type × Type → Boolean.
* <!-- In plain text: Type x Type -> Boolean -->
*/
/**
* A convenience visitor for implementing operations that only
* require one argument (the type itself), that is, unary
* operations.
*
* @param <R> the return type of the operation implemented by this
* visitor; use Void if no return type is needed.
*/
}
/**
* A visitor for implementing a mapping from types to types. The
* default behavior of this class is to implement the identity
* mapping (mapping a type to itself). This can be overridden in
* subclasses.
*
* @param <S> the type of the second argument (the first being the
* type itself) of this mapping; use Void if a second argument is
* not needed.
*/
}
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="Annotation support">
if (c != null) {
else ;// /* fail soft */ throw new AssertionError(levelName);
}
}
return vis;
}
// </editor-fold>
}