Wed, 16 Feb 2011 10:27:00 -0800
6990136: Cleanup use of Type.clone()
Summary: Introduced factory methods in class Types which can be used rather than clone().
Reviewed-by: jjg, mcimadamore
1.1 --- a/src/share/classes/com/sun/tools/javac/code/Type.java Tue Feb 15 08:35:05 2011 -0800 1.2 +++ b/src/share/classes/com/sun/tools/javac/code/Type.java Wed Feb 16 10:27:00 2011 -0800 1.3 @@ -270,10 +270,6 @@ 1.4 public Type getUpperBound() { return null; } 1.5 public Type getLowerBound() { return null; } 1.6 1.7 - public void setThrown(List<Type> ts) { 1.8 - throw new AssertionError(); 1.9 - } 1.10 - 1.11 /** Navigation methods, these will work for classes, type variables, 1.12 * foralls, but will return null for arrays and methods. 1.13 */ 1.14 @@ -388,14 +384,6 @@ 1.15 */ 1.16 public void complete() {} 1.17 1.18 - public Object clone() { 1.19 - try { 1.20 - return super.clone(); 1.21 - } catch (CloneNotSupportedException e) { 1.22 - throw new AssertionError(e); 1.23 - } 1.24 - } 1.25 - 1.26 public TypeSymbol asElement() { 1.27 return tsym; 1.28 } 1.29 @@ -817,8 +805,7 @@ 1.30 } 1.31 } 1.32 1.33 - public static class MethodType extends Type 1.34 - implements Cloneable, ExecutableType { 1.35 + public static class MethodType extends Type implements ExecutableType { 1.36 1.37 public List<Type> argtypes; 1.38 public Type restype; 1.39 @@ -880,10 +867,6 @@ 1.40 public Type getReturnType() { return restype; } 1.41 public List<Type> getThrownTypes() { return thrown; } 1.42 1.43 - public void setThrown(List<Type> t) { 1.44 - thrown = t; 1.45 - } 1.46 - 1.47 public boolean isErroneous() { 1.48 return 1.49 isErroneous(argtypes) || 1.50 @@ -1068,12 +1051,10 @@ 1.51 public List<Type> getThrownTypes() { return qtype.getThrownTypes(); } 1.52 public List<Type> allparams() { return qtype.allparams(); } 1.53 public Type getUpperBound() { return qtype.getUpperBound(); } 1.54 - public Object clone() { DelegatedType t = (DelegatedType)super.clone(); t.qtype = (Type)qtype.clone(); return t; } 1.55 public boolean isErroneous() { return qtype.isErroneous(); } 1.56 } 1.57 1.58 - public static class ForAll extends DelegatedType 1.59 - implements Cloneable, ExecutableType { 1.60 + public static class ForAll extends DelegatedType implements ExecutableType { 1.61 public List<Type> tvars; 1.62 1.63 public ForAll(List<Type> tvars, Type qtype) { 1.64 @@ -1092,16 +1073,6 @@ 1.65 1.66 public List<Type> getTypeArguments() { return tvars; } 1.67 1.68 - public void setThrown(List<Type> t) { 1.69 - qtype.setThrown(t); 1.70 - } 1.71 - 1.72 - public Object clone() { 1.73 - ForAll result = (ForAll)super.clone(); 1.74 - result.qtype = (Type)result.qtype.clone(); 1.75 - return result; 1.76 - } 1.77 - 1.78 public boolean isErroneous() { 1.79 return qtype.isErroneous(); 1.80 }
2.1 --- a/src/share/classes/com/sun/tools/javac/code/Types.java Tue Feb 15 08:35:05 2011 -0800 2.2 +++ b/src/share/classes/com/sun/tools/javac/code/Types.java Wed Feb 16 10:27:00 2011 -0800 2.3 @@ -2407,6 +2407,38 @@ 2.4 }; 2.5 // </editor-fold> 2.6 2.7 + public Type createMethodTypeWithParameters(Type original, List<Type> newParams) { 2.8 + return original.accept(methodWithParameters, newParams); 2.9 + } 2.10 + // where 2.11 + private final MapVisitor<List<Type>> methodWithParameters = new MapVisitor<List<Type>>() { 2.12 + public Type visitType(Type t, List<Type> newParams) { 2.13 + throw new IllegalArgumentException("Not a method type: " + t); 2.14 + } 2.15 + public Type visitMethodType(MethodType t, List<Type> newParams) { 2.16 + return new MethodType(newParams, t.restype, t.thrown, t.tsym); 2.17 + } 2.18 + public Type visitForAll(ForAll t, List<Type> newParams) { 2.19 + return new ForAll(t.tvars, t.qtype.accept(this, newParams)); 2.20 + } 2.21 + }; 2.22 + 2.23 + public Type createMethodTypeWithThrown(Type original, List<Type> newThrown) { 2.24 + return original.accept(methodWithThrown, newThrown); 2.25 + } 2.26 + // where 2.27 + private final MapVisitor<List<Type>> methodWithThrown = new MapVisitor<List<Type>>() { 2.28 + public Type visitType(Type t, List<Type> newThrown) { 2.29 + throw new IllegalArgumentException("Not a method type: " + t); 2.30 + } 2.31 + public Type visitMethodType(MethodType t, List<Type> newThrown) { 2.32 + return new MethodType(t.argtypes, t.restype, newThrown, t.tsym); 2.33 + } 2.34 + public Type visitForAll(ForAll t, List<Type> newThrown) { 2.35 + return new ForAll(t.tvars, t.qtype.accept(this, newThrown)); 2.36 + } 2.37 + }; 2.38 + 2.39 // <editor-fold defaultstate="collapsed" desc="createErrorType"> 2.40 public Type createErrorType(Type originalType) { 2.41 return new ErrorType(originalType, syms.errSymbol);
3.1 --- a/src/share/classes/com/sun/tools/javac/comp/Flow.java Tue Feb 15 08:35:05 2011 -0800 3.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Flow.java Wed Feb 16 10:27:00 2011 -0800 3.3 @@ -673,12 +673,15 @@ 3.4 // in an anonymous class, add the set of thrown exceptions to 3.5 // the throws clause of the synthetic constructor and propagate 3.6 // outwards. 3.7 + // Changing the throws clause on the fly is okay here because 3.8 + // the anonymous constructor can't be invoked anywhere else, 3.9 + // and its type hasn't been cached. 3.10 if (tree.name == names.empty) { 3.11 for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) { 3.12 if (TreeInfo.isInitialConstructor(l.head)) { 3.13 JCMethodDecl mdef = (JCMethodDecl)l.head; 3.14 mdef.thrown = make.Types(thrown); 3.15 - mdef.sym.type.setThrown(thrown); 3.16 + mdef.sym.type = types.createMethodTypeWithThrown(mdef.sym.type, thrown); 3.17 } 3.18 } 3.19 thrownPrev = chk.union(thrown, thrownPrev);
4.1 --- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java Tue Feb 15 08:35:05 2011 -0800 4.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java Wed Feb 16 10:27:00 2011 -0800 4.3 @@ -776,10 +776,12 @@ 4.4 // due to error recovery or mixing incompatible class files 4.5 return ambiguityError(m1, m2); 4.6 } 4.7 + List<Type> allThrown = chk.intersect(mt1.getThrownTypes(), mt2.getThrownTypes()); 4.8 + Type newSig = types.createMethodTypeWithThrown(mostSpecific.type, allThrown); 4.9 MethodSymbol result = new MethodSymbol( 4.10 mostSpecific.flags(), 4.11 mostSpecific.name, 4.12 - null, 4.13 + newSig, 4.14 mostSpecific.owner) { 4.15 @Override 4.16 public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult) { 4.17 @@ -789,9 +791,6 @@ 4.18 return super.implementation(origin, types, checkResult); 4.19 } 4.20 }; 4.21 - result.type = (Type)mostSpecific.type.clone(); 4.22 - result.type.setThrown(chk.intersect(mt1.getThrownTypes(), 4.23 - mt2.getThrownTypes())); 4.24 return result; 4.25 } 4.26 if (m1SignatureMoreSpecific) return m1; 4.27 @@ -852,13 +851,8 @@ 4.28 } 4.29 //append varargs element type as last synthetic formal 4.30 args.append(types.elemtype(varargsTypeTo)); 4.31 - MethodSymbol msym = new MethodSymbol(to.flags_field, 4.32 - to.name, 4.33 - (Type)to.type.clone(), //see: 6990136 4.34 - to.owner); 4.35 - MethodType mtype = msym.type.asMethodType(); 4.36 - mtype.argtypes = args.toList(); 4.37 - return msym; 4.38 + Type mtype = types.createMethodTypeWithParameters(to.type, args.toList()); 4.39 + return new MethodSymbol(to.flags_field, to.name, mtype, to.owner); 4.40 } else { 4.41 return to; 4.42 }