6990136: Cleanup use of Type.clone()
authordlsmith
Wed, 16 Feb 2011 10:27:00 -0800
changeset 8430 be3e5581ea25
parent 8429 510df4cd65d7
child 8431 21758b2bba40
6990136: Cleanup use of Type.clone() Summary: Introduced factory methods in class Types which can be used rather than clone(). Reviewed-by: jjg, mcimadamore
langtools/src/share/classes/com/sun/tools/javac/code/Type.java
langtools/src/share/classes/com/sun/tools/javac/code/Types.java
langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java
langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java
--- 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;
         }