6990136: Cleanup use of Type.clone()
Summary: Introduced factory methods in class Types which can be used rather than clone().
Reviewed-by: jjg, mcimadamore
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Type.java Tue Feb 15 08:35:05 2011 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Type.java Wed Feb 16 10:27:00 2011 -0800
@@ -270,10 +270,6 @@
public Type getUpperBound() { return null; }
public Type getLowerBound() { return null; }
- public void setThrown(List<Type> ts) {
- throw new AssertionError();
- }
-
/** Navigation methods, these will work for classes, type variables,
* foralls, but will return null for arrays and methods.
*/
@@ -388,14 +384,6 @@
*/
public void complete() {}
- public Object clone() {
- try {
- return super.clone();
- } catch (CloneNotSupportedException e) {
- throw new AssertionError(e);
- }
- }
-
public TypeSymbol asElement() {
return tsym;
}
@@ -817,8 +805,7 @@
}
}
- public static class MethodType extends Type
- implements Cloneable, ExecutableType {
+ public static class MethodType extends Type implements ExecutableType {
public List<Type> argtypes;
public Type restype;
@@ -880,10 +867,6 @@
public Type getReturnType() { return restype; }
public List<Type> getThrownTypes() { return thrown; }
- public void setThrown(List<Type> t) {
- thrown = t;
- }
-
public boolean isErroneous() {
return
isErroneous(argtypes) ||
@@ -1068,12 +1051,10 @@
public List<Type> getThrownTypes() { return qtype.getThrownTypes(); }
public List<Type> allparams() { return qtype.allparams(); }
public Type getUpperBound() { return qtype.getUpperBound(); }
- public Object clone() { DelegatedType t = (DelegatedType)super.clone(); t.qtype = (Type)qtype.clone(); return t; }
public boolean isErroneous() { return qtype.isErroneous(); }
}
- public static class ForAll extends DelegatedType
- implements Cloneable, ExecutableType {
+ public static class ForAll extends DelegatedType implements ExecutableType {
public List<Type> tvars;
public ForAll(List<Type> tvars, Type qtype) {
@@ -1092,16 +1073,6 @@
public List<Type> getTypeArguments() { return tvars; }
- public void setThrown(List<Type> t) {
- qtype.setThrown(t);
- }
-
- public Object clone() {
- ForAll result = (ForAll)super.clone();
- result.qtype = (Type)result.qtype.clone();
- return result;
- }
-
public boolean isErroneous() {
return qtype.isErroneous();
}
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Tue Feb 15 08:35:05 2011 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Wed Feb 16 10:27:00 2011 -0800
@@ -2407,6 +2407,38 @@
};
// </editor-fold>
+ public Type createMethodTypeWithParameters(Type original, List<Type> newParams) {
+ return original.accept(methodWithParameters, newParams);
+ }
+ // where
+ private final MapVisitor<List<Type>> methodWithParameters = new MapVisitor<List<Type>>() {
+ public Type visitType(Type t, List<Type> newParams) {
+ throw new IllegalArgumentException("Not a method type: " + t);
+ }
+ public Type visitMethodType(MethodType t, List<Type> newParams) {
+ return new MethodType(newParams, t.restype, t.thrown, t.tsym);
+ }
+ public Type visitForAll(ForAll t, List<Type> newParams) {
+ return new ForAll(t.tvars, t.qtype.accept(this, newParams));
+ }
+ };
+
+ public Type createMethodTypeWithThrown(Type original, List<Type> newThrown) {
+ return original.accept(methodWithThrown, newThrown);
+ }
+ // where
+ private final MapVisitor<List<Type>> methodWithThrown = new MapVisitor<List<Type>>() {
+ public Type visitType(Type t, List<Type> newThrown) {
+ throw new IllegalArgumentException("Not a method type: " + t);
+ }
+ public Type visitMethodType(MethodType t, List<Type> newThrown) {
+ return new MethodType(t.argtypes, t.restype, newThrown, t.tsym);
+ }
+ public Type visitForAll(ForAll t, List<Type> newThrown) {
+ return new ForAll(t.tvars, t.qtype.accept(this, newThrown));
+ }
+ };
+
// <editor-fold defaultstate="collapsed" desc="createErrorType">
public Type createErrorType(Type originalType) {
return new ErrorType(originalType, syms.errSymbol);
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java Tue Feb 15 08:35:05 2011 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java Wed Feb 16 10:27:00 2011 -0800
@@ -673,12 +673,15 @@
// in an anonymous class, add the set of thrown exceptions to
// the throws clause of the synthetic constructor and propagate
// outwards.
+ // Changing the throws clause on the fly is okay here because
+ // the anonymous constructor can't be invoked anywhere else,
+ // and its type hasn't been cached.
if (tree.name == names.empty) {
for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
if (TreeInfo.isInitialConstructor(l.head)) {
JCMethodDecl mdef = (JCMethodDecl)l.head;
mdef.thrown = make.Types(thrown);
- mdef.sym.type.setThrown(thrown);
+ mdef.sym.type = types.createMethodTypeWithThrown(mdef.sym.type, thrown);
}
}
thrownPrev = chk.union(thrown, thrownPrev);
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java Tue Feb 15 08:35:05 2011 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java Wed Feb 16 10:27:00 2011 -0800
@@ -776,10 +776,12 @@
// due to error recovery or mixing incompatible class files
return ambiguityError(m1, m2);
}
+ List<Type> allThrown = chk.intersect(mt1.getThrownTypes(), mt2.getThrownTypes());
+ Type newSig = types.createMethodTypeWithThrown(mostSpecific.type, allThrown);
MethodSymbol result = new MethodSymbol(
mostSpecific.flags(),
mostSpecific.name,
- null,
+ newSig,
mostSpecific.owner) {
@Override
public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult) {
@@ -789,9 +791,6 @@
return super.implementation(origin, types, checkResult);
}
};
- result.type = (Type)mostSpecific.type.clone();
- result.type.setThrown(chk.intersect(mt1.getThrownTypes(),
- mt2.getThrownTypes()));
return result;
}
if (m1SignatureMoreSpecific) return m1;
@@ -852,13 +851,8 @@
}
//append varargs element type as last synthetic formal
args.append(types.elemtype(varargsTypeTo));
- MethodSymbol msym = new MethodSymbol(to.flags_field,
- to.name,
- (Type)to.type.clone(), //see: 6990136
- to.owner);
- MethodType mtype = msym.type.asMethodType();
- mtype.argtypes = args.toList();
- return msym;
+ Type mtype = types.createMethodTypeWithParameters(to.type, args.toList());
+ return new MethodSymbol(to.flags_field, to.name, mtype, to.owner);
} else {
return to;
}