提交 f1f97dad 编写于 作者: D dlsmith

8042338: Refactor Types.upperBound to treat wildcards and variables separately

Reviewed-by: vromero
上级 06a965cc
......@@ -407,7 +407,7 @@ public class JavacTrees extends DocTrees {
paramTypes = lb.toList();
}
ClassSymbol sym = (ClassSymbol) types.upperBound(tsym.type).tsym;
ClassSymbol sym = (ClassSymbol) types.cvarUpperBound(tsym.type).tsym;
Symbol msym = (memberName == sym.name)
? findConstructor(sym, paramTypes)
......
......@@ -122,37 +122,34 @@ public class Types {
}
// </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
*/
public Type upperBound(Type t) {
return upperBound.visit(t).unannotatedType();
}
// where
private final MapVisitor<Void> upperBound = new MapVisitor<Void>() {
// <editor-fold defaultstate="collapsed" desc="bounds">
/**
* Get a wildcard's upper bound, returning non-wildcards unchanged.
* @param t a type argument, either a wildcard or a type
*/
public Type wildUpperBound(Type t) {
if (t.hasTag(WILDCARD)) {
WildcardType w = (WildcardType) t.unannotatedType();
if (w.isSuperBound())
return w.bound == null ? syms.objectType : w.bound.bound;
else
return wildUpperBound(w.type);
}
else return t;
}
/**
* Get a capture variable's upper bound, returning other types unchanged.
* @param t a type
*/
public Type cvarUpperBound(Type t) {
if (t.hasTag(TYPEVAR)) {
TypeVar v = (TypeVar) t.unannotatedType();
return v.isCaptured() ? cvarUpperBound(v.bound) : v;
}
else return t;
}
@Override
public Type visitWildcardType(WildcardType t, Void ignored) {
if (t.isSuperBound())
return t.bound == null ? syms.objectType : t.bound.bound;
else
return visit(t.type);
}
@Override
public Type visitCapturedType(CapturedType t, Void ignored) {
return visit(t.bound);
}
};
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="wildLowerBound">
/**
* Get a wildcard's lower bound, returning non-wildcards unchanged.
* @param t a type argument, either a wildcard or a type
......@@ -164,9 +161,7 @@ public class Types {
}
else return t;
}
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="cvarLowerBound">
/**
* Get a capture variable's lower bound, returning other types unchanged.
* @param t a type
......@@ -904,7 +899,7 @@ public class Types {
syms.boundClass);
changed = true;
} else if (s != orig) {
s = new WildcardType(upperBound(s),
s = new WildcardType(wildUpperBound(s),
BoundKind.EXTENDS,
syms.boundClass);
changed = true;
......@@ -1113,7 +1108,7 @@ public class Types {
//check that u == t, where u has been set by Type.withTypeVar
return s.isSuperBound() &&
!s.isExtendsBound() &&
visit(t, upperBound(s));
visit(t, wildUpperBound(s));
}
}
default:
......@@ -1140,7 +1135,7 @@ public class Types {
return visit(s, t);
if (s.isSuperBound() && !s.isExtendsBound())
return visit(t, upperBound(s)) && visit(t, wildLowerBound(s));
return visit(t, wildUpperBound(s)) && visit(t, wildLowerBound(s));
if (t.isCompound() && s.isCompound()) {
if (!visit(supertype(t), supertype(s)))
......@@ -1290,7 +1285,7 @@ public class Types {
switch(wt.kind) {
case UNBOUND: //similar to ? extends Object
case EXTENDS: {
Type bound = upperBound(s);
Type bound = wildUpperBound(s);
undetvar.addBound(InferenceBound.UPPER, bound, this);
break;
}
......@@ -1351,28 +1346,6 @@ public class Types {
// where
private TypeRelation containsType = new TypeRelation() {
private Type U(Type t) {
while (t.hasTag(WILDCARD)) {
WildcardType w = (WildcardType)t.unannotatedType();
if (w.isSuperBound())
return w.bound == null ? syms.objectType : w.bound.bound;
else
t = w.type;
}
return t;
}
private Type L(Type t) {
while (t.hasTag(WILDCARD)) {
WildcardType w = (WildcardType)t.unannotatedType();
if (w.isExtendsBound())
return syms.botType;
else
t = w.type;
}
return t;
}
public Boolean visitType(Type t, Type s) {
if (s.isPartial())
return containedBy(s, t);
......@@ -1384,13 +1357,13 @@ public class Types {
// 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),
// wildUpperBound(s), s, t, wildUpperBound(t),
// t.isSuperBound()
// || isSubtypeNoCapture(upperBound(s), U(t)));
// || isSubtypeNoCapture(wildUpperBound(s), wildUpperBound(t)));
// System.err.format(" %s L(%s) <: L(%s) %s = %s%n",
// L(t), t, s, wildLowerBound(s),
// wildLowerBound(t), t, s, wildLowerBound(s),
// t.isExtendsBound()
// || isSubtypeNoCapture(L(t), wildLowerBound(s)));
// || isSubtypeNoCapture(wildLowerBound(t), wildLowerBound(s)));
// System.err.println();
// }
......@@ -1402,8 +1375,9 @@ public class Types {
// debugContainsType(t, s);
return isSameWildcard(t, s)
|| isCaptureOf(s, t)
|| ((t.isExtendsBound() || isSubtypeNoCapture(L(t), wildLowerBound(s))) &&
(t.isSuperBound() || isSubtypeNoCapture(upperBound(s), U(t))));
|| ((t.isExtendsBound() || isSubtypeNoCapture(wildLowerBound(t), wildLowerBound(s))) &&
// TODO: JDK-8039214, cvarUpperBound call here is incorrect
(t.isSuperBound() || isSubtypeNoCapture(cvarUpperBound(wildUpperBound(s)), wildUpperBound(t))));
}
}
......@@ -1521,7 +1495,7 @@ public class Types {
@Override
public Boolean visitWildcardType(WildcardType t, Type s) {
return isCastable(upperBound(t), s, warnStack.head);
return isCastable(wildUpperBound(t), s, warnStack.head);
}
@Override
......@@ -1762,12 +1736,12 @@ public class Types {
if (t.isExtendsBound()) {
if (s.isExtendsBound())
return !isCastableRecursive(t.type, upperBound(s));
return !isCastableRecursive(t.type, wildUpperBound(s));
else if (s.isSuperBound())
return notSoftSubtypeRecursive(wildLowerBound(s), t.type);
} else if (t.isSuperBound()) {
if (s.isExtendsBound())
return notSoftSubtypeRecursive(t.type, upperBound(s));
return notSoftSubtypeRecursive(t.type, wildUpperBound(s));
}
return false;
}
......@@ -1803,7 +1777,7 @@ public class Types {
noWarnings);
}
if (!s.hasTag(WILDCARD))
s = upperBound(s);
s = cvarUpperBound(s);
return !isSubtype(t, relaxBound(s));
}
......@@ -1860,7 +1834,7 @@ public class Types {
// <editor-fold defaultstate="collapsed" desc="Array Utils">
public boolean isArray(Type t) {
while (t.hasTag(WILDCARD))
t = upperBound(t);
t = wildUpperBound(t);
return t.hasTag(ARRAY);
}
......@@ -1870,7 +1844,7 @@ public class Types {
public Type elemtype(Type t) {
switch (t.getTag()) {
case WILDCARD:
return elemtype(upperBound(t));
return elemtype(wildUpperBound(t));
case ARRAY:
t = t.unannotatedType();
return ((ArrayType)t).elemtype;
......@@ -2073,7 +2047,7 @@ public class Types {
@Override
public Type visitWildcardType(WildcardType t, Symbol sym) {
return memberType(upperBound(t), sym);
return memberType(wildUpperBound(t), sym);
}
@Override
......@@ -2192,7 +2166,7 @@ public class Types {
@Override
public Type visitWildcardType(WildcardType t, Boolean recurse) {
return erasure(upperBound(t), recurse);
return erasure(wildUpperBound(t), recurse);
}
@Override
......@@ -2401,8 +2375,7 @@ public class Types {
if (t.hasErasedSupertypes()) {
t.interfaces_field = erasureRecursive(interfaces);
} else if (formals.nonEmpty()) {
t.interfaces_field =
upperBounds(subst(interfaces, formals, actuals));
t.interfaces_field = subst(interfaces, formals, actuals);
}
else {
t.interfaces_field = interfaces;
......@@ -2971,7 +2944,7 @@ public class Types {
return new ClassType(outer1, typarams1, t.tsym);
} else {
Type st = subst(supertype(t));
List<Type> is = upperBounds(subst(interfaces(t)));
List<Type> is = subst(interfaces(t));
if (st == supertype(t) && is == interfaces(t))
return t;
else
......@@ -2988,7 +2961,7 @@ public class Types {
return t;
} else {
if (t.isExtendsBound() && bound.isExtendsBound())
bound = upperBound(bound);
bound = wildUpperBound(bound);
return new WildcardType(bound, t.kind, syms.boundClass, t.bound);
}
}
......@@ -3438,8 +3411,8 @@ public class Types {
TypePair pair = new TypePair(c1, c2);
Type m;
if (mergeCache.add(pair)) {
m = new WildcardType(lub(upperBound(act1.head),
upperBound(act2.head)),
m = new WildcardType(lub(wildUpperBound(act1.head),
wildUpperBound(act2.head)),
BoundKind.EXTENDS,
syms.boundClass);
mergeCache.remove(pair);
......@@ -4015,16 +3988,6 @@ public class Types {
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="Internal utility methods">
private List<Type> upperBounds(List<Type> ss) {
if (ss.isEmpty()) return ss;
Type head = upperBound(ss.head);
List<Type> tail = upperBounds(ss.tail);
if (head != ss.head || tail != ss.tail)
return tail.prepend(head);
else
return ss;
}
private boolean sideCast(Type from, Type to, Warner warn) {
// We are casting from type $from$ to type $to$, which are
// non-final unrelated types. This method
......@@ -4181,7 +4144,7 @@ public class Types {
@Override
public Void visitWildcardType(WildcardType source, Type target) throws AdaptFailure {
if (source.isExtendsBound())
adaptRecursive(upperBound(source), upperBound(target));
adaptRecursive(wildUpperBound(source), wildUpperBound(target));
else if (source.isSuperBound())
adaptRecursive(wildLowerBound(source), wildLowerBound(target));
return null;
......@@ -4198,7 +4161,7 @@ public class Types {
val = isSubtype(wildLowerBound(val), wildLowerBound(target))
? target : val;
} else if (val.isExtendsBound() && target.isExtendsBound()) {
val = isSubtype(upperBound(val), upperBound(target))
val = isSubtype(wildUpperBound(val), wildUpperBound(target))
? val : target;
} else if (!isSameType(val, target)) {
throw new AdaptFailure();
......@@ -4309,7 +4272,7 @@ public class Types {
}
public Type visitType(Type t, Void s) {
return high ? upperBound(t) : t;
return t;
}
@Override
......
......@@ -1175,7 +1175,7 @@ public class Attr extends JCTree.Visitor {
//the Formal Parameter of a for-each loop is not in the scope when
//attributing the for-each expression; we mimick this by attributing
//the for-each expression first (against original scope).
Type exprType = types.upperBound(attribExpr(tree.expr, loopEnv));
Type exprType = types.cvarUpperBound(attribExpr(tree.expr, loopEnv));
attribStat(tree.var, loopEnv);
chk.checkNonVoid(tree.pos(), exprType);
Type elemtype = types.elemtype(exprType); // perhaps expr is an array?
......@@ -1192,7 +1192,7 @@ public class Attr extends JCTree.Visitor {
List<Type> iterableParams = base.allparams();
elemtype = iterableParams.isEmpty()
? syms.objectType
: types.upperBound(iterableParams.head);
: types.wildUpperBound(iterableParams.head);
}
}
chk.checkType(tree.expr.pos(), elemtype, tree.var.sym.type);
......
......@@ -618,10 +618,10 @@ public class Check {
if (a.isUnbound()) {
return true;
} else if (!a.hasTag(WILDCARD)) {
a = types.upperBound(a);
a = types.cvarUpperBound(a);
return types.isSubtype(a, bound);
} else if (a.isExtendsBound()) {
return types.isCastable(bound, types.upperBound(a), types.noWarnings);
return types.isCastable(bound, types.wildUpperBound(a), types.noWarnings);
} else if (a.isSuperBound()) {
return !types.notSoftSubtype(types.wildLowerBound(a), bound);
}
......
......@@ -3472,7 +3472,7 @@ public class Lower extends TreeTranslator {
private void visitIterableForeachLoop(JCEnhancedForLoop tree) {
make_at(tree.expr.pos());
Type iteratorTarget = syms.objectType;
Type iterableType = types.asSuper(types.upperBound(tree.expr.type),
Type iterableType = types.asSuper(types.cvarUpperBound(tree.expr.type),
syms.iterableType.tsym);
if (iterableType.getTypeArguments().nonEmpty())
iteratorTarget = types.erasure(iterableType.getTypeArguments().head);
......@@ -3506,7 +3506,7 @@ public class Lower extends TreeTranslator {
List.<Type>nil());
JCExpression vardefinit = make.App(make.Select(make.Ident(itvar), next));
if (tree.var.type.isPrimitive())
vardefinit = make.TypeCast(types.upperBound(iteratorTarget), vardefinit);
vardefinit = make.TypeCast(types.cvarUpperBound(iteratorTarget), vardefinit);
else
vardefinit = make.TypeCast(tree.var.type, vardefinit);
JCVariableDecl indexDef = (JCVariableDecl)make.VarDef(tree.var.mods,
......
......@@ -348,7 +348,7 @@ public class Resolve {
boolean isAccessible(Env<AttrContext> env, Type t, boolean checkInner) {
return (t.hasTag(ARRAY))
? isAccessible(env, types.upperBound(types.elemtype(t)))
? isAccessible(env, types.cvarUpperBound(types.elemtype(t)))
: isAccessible(env, t.tsym, checkInner);
}
......@@ -1011,7 +1011,7 @@ public class Resolve {
*/
private Type U(Type found) {
return found == pt ?
found : types.upperBound(found);
found : types.cvarUpperBound(found);
}
@Override
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册