1 package polyglot.ext.param.types; 2 3 import polyglot.ext.jl.types.*; 4 import polyglot.types.*; 5 import polyglot.types.Package; 6 import polyglot.util.*; 7 import java.util.*; 8 import java.io.IOException ; 9 10 import polyglot.ext.param.Topics; 11 import polyglot.main.Report; 12 13 18 public class Subst_c implements Subst 19 { 20 21 protected Map subst; 22 23 24 protected transient Map cache; 25 26 protected transient ParamTypeSystem ts; 27 28 public Subst_c(ParamTypeSystem ts, Map subst, Map cache) 29 { 30 this.ts = ts; 31 this.subst = subst; 32 this.cache = new HashMap(); 33 this.cache.putAll(cache); 34 } 35 36 public ParamTypeSystem typeSystem() { 37 return ts; 38 } 39 40 44 public Iterator entries() { 45 return substitutions().entrySet().iterator(); 46 } 47 48 51 public Map substitutions() { 52 return Collections.unmodifiableMap(subst); 53 } 54 55 56 protected Type uncachedSubstType(Type t) { 57 if (t.isArray()) { 58 ArrayType at = t.toArray(); 59 return at.base(substType(at.base())); 60 } 61 62 if (t instanceof SubstType) { 64 Type tbase = ((SubstType) t).base(); 65 Map tsubst = ((SubstType) t).subst().substitutions(); 66 67 Map newSubst = new HashMap(); 68 69 for (Iterator i = tsubst.entrySet().iterator(); i.hasNext(); ) { 70 Map.Entry e = (Map.Entry) i.next(); 71 Object formal = e.getKey(); 72 Object actual = e.getValue(); 73 74 Object existent = getSubstValueAsKey(actual); 75 if (existent != null) { 76 newSubst.put(formal, existent); 83 } 84 else { 85 newSubst.put(formal, actual); 86 } 87 } 88 89 newSubst.putAll(subst); 92 93 return ts.subst(tbase, newSubst, cache); 96 } 97 98 if (t instanceof ClassType) { 99 return substClassType((ClassType) t); 100 } 101 102 return t; 103 } 104 105 114 protected Object getSubstValueAsKey(Object v) { 115 return substitutions().get(v); 116 } 117 118 120 public ClassType substClassType(ClassType t) { 121 return new SubstClassType_c(ts, t.position(), t, this); 122 } 123 124 125 public Type substType(Type t) { 126 if (t == null || t == this) 127 return t; 128 129 Type cached = (Type) cache.get(t); 130 131 if (cached == null) { 132 cached = uncachedSubstType(t); 133 cache.put(t, cached); 134 135 if (Report.should_report(Topics.subst, 2)) 136 Report.report(2, "substType(" + 137 t + ": " + t.getClass().getName() + ") = " + 138 cached + ": " + cached.getClass().getName()); 139 } 140 141 return cached; 142 } 143 144 145 public PClass substPClass(PClass pclazz) { 146 MuPClass newPclazz = ts.mutablePClass(pclazz.position()); 147 newPclazz.formals(pclazz.formals()); 148 newPclazz.clazz((ClassType) substType(pclazz.clazz())); 149 return newPclazz; 150 } 151 152 153 public FieldInstance substField(FieldInstance fi) { 154 ReferenceType ct = (ReferenceType) substType(fi.container()); 155 Type t = substType(fi.type()); 156 return fi.type(t).container(ct); 157 } 158 159 160 public MethodInstance substMethod(MethodInstance mi) { 161 ReferenceType ct = (ReferenceType) substType(mi.container()); 162 163 Type rt = substType(mi.returnType()); 164 165 List formalTypes = mi.formalTypes(); 166 formalTypes = substTypeList(formalTypes); 167 168 List throwTypes = mi.throwTypes(); 169 throwTypes = substTypeList(throwTypes); 170 171 return (MethodInstance) mi.returnType(rt).formalTypes(formalTypes).throwTypes(throwTypes).container(ct); 172 } 173 174 175 public ConstructorInstance substConstructor(ConstructorInstance ci) { 176 ClassType ct = (ClassType) substType(ci.container()); 177 178 List formalTypes = ci.formalTypes(); 179 formalTypes = substTypeList(formalTypes); 180 181 List throwTypes = ci.throwTypes(); 182 throwTypes = substTypeList(throwTypes); 183 184 return (ConstructorInstance) ci.formalTypes(formalTypes).throwTypes(throwTypes).container(ct); 185 } 186 187 188 public List substTypeList(List list) { 189 return new CachingTransformingList(list, new TypeXform()); 190 } 191 192 193 public List substMethodList(List list) { 194 return new CachingTransformingList(list, new MethodXform()); 195 } 196 197 198 public List substConstructorList(List list) { 199 return new CachingTransformingList(list, new ConstructorXform()); 200 } 201 202 203 public List substFieldList(List list) { 204 return new CachingTransformingList(list, new FieldXform()); 205 } 206 207 210 211 public class TypeXform implements Transformation { 212 public Object transform(Object o) { 213 if (! (o instanceof Type)) { 214 throw new InternalCompilerError(o + " is not a type."); 215 } 216 217 return substType((Type) o); 218 } 219 } 220 221 222 public class FieldXform implements Transformation { 223 public Object transform(Object o) { 224 if (! (o instanceof FieldInstance)) { 225 throw new InternalCompilerError(o + " is not a field."); 226 } 227 228 return substField((FieldInstance) o); 229 } 230 } 231 232 233 public class MethodXform implements Transformation { 234 public Object transform(Object o) { 235 if (! (o instanceof MethodInstance)) { 236 throw new InternalCompilerError(o + " is not a method."); 237 } 238 239 return substMethod((MethodInstance) o); 240 } 241 } 242 243 244 public class ConstructorXform implements Transformation { 245 public Object transform(Object o) { 246 if (! (o instanceof ConstructorInstance)) { 247 throw new InternalCompilerError(o + " is not a constructor."); 248 } 249 250 return substConstructor((ConstructorInstance) o); 251 } 252 } 253 254 257 public boolean equals(Object o) { 258 if (o instanceof Subst) { 259 return subst.equals(((Subst) o).substitutions()); 260 } 261 262 return false; 263 } 264 265 public int hashCode() { 266 return subst.hashCode(); 267 } 268 269 272 public String toString() { 273 String str = "["; 274 for (Iterator iter = subst.keySet().iterator(); iter.hasNext(); ) { 275 Object key = iter.next(); 276 str += "<" + key + ": " + subst.get(key) + ">"; 277 if (iter.hasNext()) 278 str += ", "; 279 } 280 return str + "]"; 281 } 282 283 private void writeObject(java.io.ObjectOutputStream out) 284 throws IOException 285 { 286 out.defaultWriteObject(); 287 } 288 289 private void readObject(java.io.ObjectInputStream in) 290 throws IOException , ClassNotFoundException 291 { 292 if (in instanceof TypeInputStream) { 293 this.ts = (ParamTypeSystem) ((TypeInputStream) in).getTypeSystem(); 294 } 295 296 this.cache = new HashMap(); 297 298 in.defaultReadObject(); 299 } 300 301 } 302 | Popular Tags |