Tue, 27 May 2014 17:30:48 -0600
8042338: Refactor Types.upperBound to treat wildcards and variables separately
Reviewed-by: vromero
1.1 --- a/src/share/classes/com/sun/tools/javac/api/JavacTrees.java Tue May 27 21:15:06 2014 +0100 1.2 +++ b/src/share/classes/com/sun/tools/javac/api/JavacTrees.java Tue May 27 17:30:48 2014 -0600 1.3 @@ -407,7 +407,7 @@ 1.4 paramTypes = lb.toList(); 1.5 } 1.6 1.7 - ClassSymbol sym = (ClassSymbol) types.upperBound(tsym.type).tsym; 1.8 + ClassSymbol sym = (ClassSymbol) types.cvarUpperBound(tsym.type).tsym; 1.9 1.10 Symbol msym = (memberName == sym.name) 1.11 ? findConstructor(sym, paramTypes)
2.1 --- a/src/share/classes/com/sun/tools/javac/code/Types.java Tue May 27 21:15:06 2014 +0100 2.2 +++ b/src/share/classes/com/sun/tools/javac/code/Types.java Tue May 27 17:30:48 2014 -0600 2.3 @@ -122,37 +122,34 @@ 2.4 } 2.5 // </editor-fold> 2.6 2.7 - // <editor-fold defaultstate="collapsed" desc="upperBound"> 2.8 - /** 2.9 - * The "rvalue conversion".<br> 2.10 - * The upper bound of most types is the type 2.11 - * itself. Wildcards, on the other hand have upper 2.12 - * and lower bounds. 2.13 - * @param t a type 2.14 - * @return the upper bound of the given type 2.15 - */ 2.16 - public Type upperBound(Type t) { 2.17 - return upperBound.visit(t).unannotatedType(); 2.18 - } 2.19 - // where 2.20 - private final MapVisitor<Void> upperBound = new MapVisitor<Void>() { 2.21 - 2.22 - @Override 2.23 - public Type visitWildcardType(WildcardType t, Void ignored) { 2.24 - if (t.isSuperBound()) 2.25 - return t.bound == null ? syms.objectType : t.bound.bound; 2.26 - else 2.27 - return visit(t.type); 2.28 - } 2.29 - 2.30 - @Override 2.31 - public Type visitCapturedType(CapturedType t, Void ignored) { 2.32 - return visit(t.bound); 2.33 - } 2.34 - }; 2.35 - // </editor-fold> 2.36 - 2.37 - // <editor-fold defaultstate="collapsed" desc="wildLowerBound"> 2.38 + // <editor-fold defaultstate="collapsed" desc="bounds"> 2.39 + /** 2.40 + * Get a wildcard's upper bound, returning non-wildcards unchanged. 2.41 + * @param t a type argument, either a wildcard or a type 2.42 + */ 2.43 + public Type wildUpperBound(Type t) { 2.44 + if (t.hasTag(WILDCARD)) { 2.45 + WildcardType w = (WildcardType) t.unannotatedType(); 2.46 + if (w.isSuperBound()) 2.47 + return w.bound == null ? syms.objectType : w.bound.bound; 2.48 + else 2.49 + return wildUpperBound(w.type); 2.50 + } 2.51 + else return t; 2.52 + } 2.53 + 2.54 + /** 2.55 + * Get a capture variable's upper bound, returning other types unchanged. 2.56 + * @param t a type 2.57 + */ 2.58 + public Type cvarUpperBound(Type t) { 2.59 + if (t.hasTag(TYPEVAR)) { 2.60 + TypeVar v = (TypeVar) t.unannotatedType(); 2.61 + return v.isCaptured() ? cvarUpperBound(v.bound) : v; 2.62 + } 2.63 + else return t; 2.64 + } 2.65 + 2.66 /** 2.67 * Get a wildcard's lower bound, returning non-wildcards unchanged. 2.68 * @param t a type argument, either a wildcard or a type 2.69 @@ -164,9 +161,7 @@ 2.70 } 2.71 else return t; 2.72 } 2.73 - // </editor-fold> 2.74 - 2.75 - // <editor-fold defaultstate="collapsed" desc="cvarLowerBound"> 2.76 + 2.77 /** 2.78 * Get a capture variable's lower bound, returning other types unchanged. 2.79 * @param t a type 2.80 @@ -904,7 +899,7 @@ 2.81 syms.boundClass); 2.82 changed = true; 2.83 } else if (s != orig) { 2.84 - s = new WildcardType(upperBound(s), 2.85 + s = new WildcardType(wildUpperBound(s), 2.86 BoundKind.EXTENDS, 2.87 syms.boundClass); 2.88 changed = true; 2.89 @@ -1113,7 +1108,7 @@ 2.90 //check that u == t, where u has been set by Type.withTypeVar 2.91 return s.isSuperBound() && 2.92 !s.isExtendsBound() && 2.93 - visit(t, upperBound(s)); 2.94 + visit(t, wildUpperBound(s)); 2.95 } 2.96 } 2.97 default: 2.98 @@ -1140,7 +1135,7 @@ 2.99 return visit(s, t); 2.100 2.101 if (s.isSuperBound() && !s.isExtendsBound()) 2.102 - return visit(t, upperBound(s)) && visit(t, wildLowerBound(s)); 2.103 + return visit(t, wildUpperBound(s)) && visit(t, wildLowerBound(s)); 2.104 2.105 if (t.isCompound() && s.isCompound()) { 2.106 if (!visit(supertype(t), supertype(s))) 2.107 @@ -1290,7 +1285,7 @@ 2.108 switch(wt.kind) { 2.109 case UNBOUND: //similar to ? extends Object 2.110 case EXTENDS: { 2.111 - Type bound = upperBound(s); 2.112 + Type bound = wildUpperBound(s); 2.113 undetvar.addBound(InferenceBound.UPPER, bound, this); 2.114 break; 2.115 } 2.116 @@ -1351,28 +1346,6 @@ 2.117 // where 2.118 private TypeRelation containsType = new TypeRelation() { 2.119 2.120 - private Type U(Type t) { 2.121 - while (t.hasTag(WILDCARD)) { 2.122 - WildcardType w = (WildcardType)t.unannotatedType(); 2.123 - if (w.isSuperBound()) 2.124 - return w.bound == null ? syms.objectType : w.bound.bound; 2.125 - else 2.126 - t = w.type; 2.127 - } 2.128 - return t; 2.129 - } 2.130 - 2.131 - private Type L(Type t) { 2.132 - while (t.hasTag(WILDCARD)) { 2.133 - WildcardType w = (WildcardType)t.unannotatedType(); 2.134 - if (w.isExtendsBound()) 2.135 - return syms.botType; 2.136 - else 2.137 - t = w.type; 2.138 - } 2.139 - return t; 2.140 - } 2.141 - 2.142 public Boolean visitType(Type t, Type s) { 2.143 if (s.isPartial()) 2.144 return containedBy(s, t); 2.145 @@ -1384,13 +1357,13 @@ 2.146 // System.err.println(); 2.147 // System.err.format(" does %s contain %s?%n", t, s); 2.148 // System.err.format(" %s U(%s) <: U(%s) %s = %s%n", 2.149 -// upperBound(s), s, t, U(t), 2.150 +// wildUpperBound(s), s, t, wildUpperBound(t), 2.151 // t.isSuperBound() 2.152 -// || isSubtypeNoCapture(upperBound(s), U(t))); 2.153 +// || isSubtypeNoCapture(wildUpperBound(s), wildUpperBound(t))); 2.154 // System.err.format(" %s L(%s) <: L(%s) %s = %s%n", 2.155 -// L(t), t, s, wildLowerBound(s), 2.156 +// wildLowerBound(t), t, s, wildLowerBound(s), 2.157 // t.isExtendsBound() 2.158 -// || isSubtypeNoCapture(L(t), wildLowerBound(s))); 2.159 +// || isSubtypeNoCapture(wildLowerBound(t), wildLowerBound(s))); 2.160 // System.err.println(); 2.161 // } 2.162 2.163 @@ -1402,8 +1375,9 @@ 2.164 // debugContainsType(t, s); 2.165 return isSameWildcard(t, s) 2.166 || isCaptureOf(s, t) 2.167 - || ((t.isExtendsBound() || isSubtypeNoCapture(L(t), wildLowerBound(s))) && 2.168 - (t.isSuperBound() || isSubtypeNoCapture(upperBound(s), U(t)))); 2.169 + || ((t.isExtendsBound() || isSubtypeNoCapture(wildLowerBound(t), wildLowerBound(s))) && 2.170 + // TODO: JDK-8039214, cvarUpperBound call here is incorrect 2.171 + (t.isSuperBound() || isSubtypeNoCapture(cvarUpperBound(wildUpperBound(s)), wildUpperBound(t)))); 2.172 } 2.173 } 2.174 2.175 @@ -1521,7 +1495,7 @@ 2.176 2.177 @Override 2.178 public Boolean visitWildcardType(WildcardType t, Type s) { 2.179 - return isCastable(upperBound(t), s, warnStack.head); 2.180 + return isCastable(wildUpperBound(t), s, warnStack.head); 2.181 } 2.182 2.183 @Override 2.184 @@ -1762,12 +1736,12 @@ 2.185 2.186 if (t.isExtendsBound()) { 2.187 if (s.isExtendsBound()) 2.188 - return !isCastableRecursive(t.type, upperBound(s)); 2.189 + return !isCastableRecursive(t.type, wildUpperBound(s)); 2.190 else if (s.isSuperBound()) 2.191 return notSoftSubtypeRecursive(wildLowerBound(s), t.type); 2.192 } else if (t.isSuperBound()) { 2.193 if (s.isExtendsBound()) 2.194 - return notSoftSubtypeRecursive(t.type, upperBound(s)); 2.195 + return notSoftSubtypeRecursive(t.type, wildUpperBound(s)); 2.196 } 2.197 return false; 2.198 } 2.199 @@ -1803,7 +1777,7 @@ 2.200 noWarnings); 2.201 } 2.202 if (!s.hasTag(WILDCARD)) 2.203 - s = upperBound(s); 2.204 + s = cvarUpperBound(s); 2.205 2.206 return !isSubtype(t, relaxBound(s)); 2.207 } 2.208 @@ -1860,7 +1834,7 @@ 2.209 // <editor-fold defaultstate="collapsed" desc="Array Utils"> 2.210 public boolean isArray(Type t) { 2.211 while (t.hasTag(WILDCARD)) 2.212 - t = upperBound(t); 2.213 + t = wildUpperBound(t); 2.214 return t.hasTag(ARRAY); 2.215 } 2.216 2.217 @@ -1870,7 +1844,7 @@ 2.218 public Type elemtype(Type t) { 2.219 switch (t.getTag()) { 2.220 case WILDCARD: 2.221 - return elemtype(upperBound(t)); 2.222 + return elemtype(wildUpperBound(t)); 2.223 case ARRAY: 2.224 t = t.unannotatedType(); 2.225 return ((ArrayType)t).elemtype; 2.226 @@ -2073,7 +2047,7 @@ 2.227 2.228 @Override 2.229 public Type visitWildcardType(WildcardType t, Symbol sym) { 2.230 - return memberType(upperBound(t), sym); 2.231 + return memberType(wildUpperBound(t), sym); 2.232 } 2.233 2.234 @Override 2.235 @@ -2192,7 +2166,7 @@ 2.236 2.237 @Override 2.238 public Type visitWildcardType(WildcardType t, Boolean recurse) { 2.239 - return erasure(upperBound(t), recurse); 2.240 + return erasure(wildUpperBound(t), recurse); 2.241 } 2.242 2.243 @Override 2.244 @@ -2401,8 +2375,7 @@ 2.245 if (t.hasErasedSupertypes()) { 2.246 t.interfaces_field = erasureRecursive(interfaces); 2.247 } else if (formals.nonEmpty()) { 2.248 - t.interfaces_field = 2.249 - upperBounds(subst(interfaces, formals, actuals)); 2.250 + t.interfaces_field = subst(interfaces, formals, actuals); 2.251 } 2.252 else { 2.253 t.interfaces_field = interfaces; 2.254 @@ -2971,7 +2944,7 @@ 2.255 return new ClassType(outer1, typarams1, t.tsym); 2.256 } else { 2.257 Type st = subst(supertype(t)); 2.258 - List<Type> is = upperBounds(subst(interfaces(t))); 2.259 + List<Type> is = subst(interfaces(t)); 2.260 if (st == supertype(t) && is == interfaces(t)) 2.261 return t; 2.262 else 2.263 @@ -2988,7 +2961,7 @@ 2.264 return t; 2.265 } else { 2.266 if (t.isExtendsBound() && bound.isExtendsBound()) 2.267 - bound = upperBound(bound); 2.268 + bound = wildUpperBound(bound); 2.269 return new WildcardType(bound, t.kind, syms.boundClass, t.bound); 2.270 } 2.271 } 2.272 @@ -3438,8 +3411,8 @@ 2.273 TypePair pair = new TypePair(c1, c2); 2.274 Type m; 2.275 if (mergeCache.add(pair)) { 2.276 - m = new WildcardType(lub(upperBound(act1.head), 2.277 - upperBound(act2.head)), 2.278 + m = new WildcardType(lub(wildUpperBound(act1.head), 2.279 + wildUpperBound(act2.head)), 2.280 BoundKind.EXTENDS, 2.281 syms.boundClass); 2.282 mergeCache.remove(pair); 2.283 @@ -4015,16 +3988,6 @@ 2.284 // </editor-fold> 2.285 2.286 // <editor-fold defaultstate="collapsed" desc="Internal utility methods"> 2.287 - private List<Type> upperBounds(List<Type> ss) { 2.288 - if (ss.isEmpty()) return ss; 2.289 - Type head = upperBound(ss.head); 2.290 - List<Type> tail = upperBounds(ss.tail); 2.291 - if (head != ss.head || tail != ss.tail) 2.292 - return tail.prepend(head); 2.293 - else 2.294 - return ss; 2.295 - } 2.296 - 2.297 private boolean sideCast(Type from, Type to, Warner warn) { 2.298 // We are casting from type $from$ to type $to$, which are 2.299 // non-final unrelated types. This method 2.300 @@ -4181,7 +4144,7 @@ 2.301 @Override 2.302 public Void visitWildcardType(WildcardType source, Type target) throws AdaptFailure { 2.303 if (source.isExtendsBound()) 2.304 - adaptRecursive(upperBound(source), upperBound(target)); 2.305 + adaptRecursive(wildUpperBound(source), wildUpperBound(target)); 2.306 else if (source.isSuperBound()) 2.307 adaptRecursive(wildLowerBound(source), wildLowerBound(target)); 2.308 return null; 2.309 @@ -4198,7 +4161,7 @@ 2.310 val = isSubtype(wildLowerBound(val), wildLowerBound(target)) 2.311 ? target : val; 2.312 } else if (val.isExtendsBound() && target.isExtendsBound()) { 2.313 - val = isSubtype(upperBound(val), upperBound(target)) 2.314 + val = isSubtype(wildUpperBound(val), wildUpperBound(target)) 2.315 ? val : target; 2.316 } else if (!isSameType(val, target)) { 2.317 throw new AdaptFailure(); 2.318 @@ -4309,7 +4272,7 @@ 2.319 } 2.320 2.321 public Type visitType(Type t, Void s) { 2.322 - return high ? upperBound(t) : t; 2.323 + return t; 2.324 } 2.325 2.326 @Override
3.1 --- a/src/share/classes/com/sun/tools/javac/comp/Attr.java Tue May 27 21:15:06 2014 +0100 3.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java Tue May 27 17:30:48 2014 -0600 3.3 @@ -1175,7 +1175,7 @@ 3.4 //the Formal Parameter of a for-each loop is not in the scope when 3.5 //attributing the for-each expression; we mimick this by attributing 3.6 //the for-each expression first (against original scope). 3.7 - Type exprType = types.upperBound(attribExpr(tree.expr, loopEnv)); 3.8 + Type exprType = types.cvarUpperBound(attribExpr(tree.expr, loopEnv)); 3.9 attribStat(tree.var, loopEnv); 3.10 chk.checkNonVoid(tree.pos(), exprType); 3.11 Type elemtype = types.elemtype(exprType); // perhaps expr is an array? 3.12 @@ -1192,7 +1192,7 @@ 3.13 List<Type> iterableParams = base.allparams(); 3.14 elemtype = iterableParams.isEmpty() 3.15 ? syms.objectType 3.16 - : types.upperBound(iterableParams.head); 3.17 + : types.wildUpperBound(iterableParams.head); 3.18 } 3.19 } 3.20 chk.checkType(tree.expr.pos(), elemtype, tree.var.sym.type);
4.1 --- a/src/share/classes/com/sun/tools/javac/comp/Check.java Tue May 27 21:15:06 2014 +0100 4.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Check.java Tue May 27 17:30:48 2014 -0600 4.3 @@ -618,10 +618,10 @@ 4.4 if (a.isUnbound()) { 4.5 return true; 4.6 } else if (!a.hasTag(WILDCARD)) { 4.7 - a = types.upperBound(a); 4.8 + a = types.cvarUpperBound(a); 4.9 return types.isSubtype(a, bound); 4.10 } else if (a.isExtendsBound()) { 4.11 - return types.isCastable(bound, types.upperBound(a), types.noWarnings); 4.12 + return types.isCastable(bound, types.wildUpperBound(a), types.noWarnings); 4.13 } else if (a.isSuperBound()) { 4.14 return !types.notSoftSubtype(types.wildLowerBound(a), bound); 4.15 }
5.1 --- a/src/share/classes/com/sun/tools/javac/comp/Lower.java Tue May 27 21:15:06 2014 +0100 5.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Lower.java Tue May 27 17:30:48 2014 -0600 5.3 @@ -3472,7 +3472,7 @@ 5.4 private void visitIterableForeachLoop(JCEnhancedForLoop tree) { 5.5 make_at(tree.expr.pos()); 5.6 Type iteratorTarget = syms.objectType; 5.7 - Type iterableType = types.asSuper(types.upperBound(tree.expr.type), 5.8 + Type iterableType = types.asSuper(types.cvarUpperBound(tree.expr.type), 5.9 syms.iterableType.tsym); 5.10 if (iterableType.getTypeArguments().nonEmpty()) 5.11 iteratorTarget = types.erasure(iterableType.getTypeArguments().head); 5.12 @@ -3506,7 +3506,7 @@ 5.13 List.<Type>nil()); 5.14 JCExpression vardefinit = make.App(make.Select(make.Ident(itvar), next)); 5.15 if (tree.var.type.isPrimitive()) 5.16 - vardefinit = make.TypeCast(types.upperBound(iteratorTarget), vardefinit); 5.17 + vardefinit = make.TypeCast(types.cvarUpperBound(iteratorTarget), vardefinit); 5.18 else 5.19 vardefinit = make.TypeCast(tree.var.type, vardefinit); 5.20 JCVariableDecl indexDef = (JCVariableDecl)make.VarDef(tree.var.mods,
6.1 --- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java Tue May 27 21:15:06 2014 +0100 6.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java Tue May 27 17:30:48 2014 -0600 6.3 @@ -348,7 +348,7 @@ 6.4 6.5 boolean isAccessible(Env<AttrContext> env, Type t, boolean checkInner) { 6.6 return (t.hasTag(ARRAY)) 6.7 - ? isAccessible(env, types.upperBound(types.elemtype(t))) 6.8 + ? isAccessible(env, types.cvarUpperBound(types.elemtype(t))) 6.9 : isAccessible(env, t.tsym, checkInner); 6.10 } 6.11 6.12 @@ -1011,7 +1011,7 @@ 6.13 */ 6.14 private Type U(Type found) { 6.15 return found == pt ? 6.16 - found : types.upperBound(found); 6.17 + found : types.cvarUpperBound(found); 6.18 } 6.19 6.20 @Override