00001 package edu.ksu.cis.bandera.abstraction.typeinference;
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 import edu.ksu.cis.bandera.abstraction.*;
00036 import edu.ksu.cis.bandera.abstraction.util.*;
00037 import java.util.*;
00038 public class TypeDependencyGraph {
00039 protected Hashtable typeTypeVarTable = new Hashtable();
00040 protected Hashtable children;
00041 protected Hashtable parents;
00042 protected UnionFindSet ufs;
00043
00044
00045
00046 public TypeDependencyGraph() {
00047 ufs = new UnionFindSet();
00048 parents = new Hashtable();
00049 children = new Hashtable();
00050 }
00051
00052
00053
00054
00055
00056 public void add(TypeVariable o) {
00057 ufs.add(o);
00058 }
00059
00060
00061
00062
00063
00064
00065 public void addChild(TypeVariable parent, TypeVariable child) {
00066 TypeVariable p = (TypeVariable) ufs.find(parent);
00067 TypeVariable c = (TypeVariable) ufs.find(child);
00068 if (p == null || c == null) {
00069 System.out.println("Parent or child is null.");
00070 return;
00071 } else
00072 if (p != c) {
00073 Set s = (Set) children.get(p);
00074 if (s == null) {
00075 s = new HashSet();
00076 children.put(p, s);
00077 }
00078 s.add(c);
00079 s = (Set) parents.get(c);
00080 if (s == null) {
00081 s = new HashSet();
00082 parents.put(c, s);
00083 }
00084 s.add(p);
00085 }
00086 }
00087
00088
00089
00090
00091 public TypeVariable addType(Object type) {
00092 TypeVariable typeVar;
00093 if ((typeVar = (TypeVariable) typeTypeVarTable.get(type)) == null) {
00094 typeVar = new TypeVariable(type);
00095 typeVar.setAST(type);
00096 typeTypeVarTable.put(type, typeVar);
00097 add(typeVar);
00098 ufs.setAttribute(typeVar, type);
00099 }
00100 return typeVar;
00101 }
00102
00103
00104
00105
00106
00107
00108 public void combine(TypeVariable o1, TypeVariable o2) {
00109 o1 = (TypeVariable) ufs.find(o1);
00110 o2 = (TypeVariable) ufs.find(o2);
00111 if (o1 != o2) {
00112 ufs.union(o1, o2);
00113 TypeVariable o3 = (TypeVariable) ufs.find(o1);
00114 if (o3 == o1) {
00115 o3 = o2;
00116 } else
00117 if (o3 == o2) {
00118 o3 = o1;
00119 o1 = o2;
00120 } else
00121 System.out.println("How did I get here: TDG.combine");
00122 Set s1 = (Set) children.get(o1);
00123 Set s2 = (Set) children.get(o3);
00124 if (s1 == null)
00125 if (s2 == null) {
00126 s1 = new HashSet();
00127 children.put(o1, s1);
00128 s1.remove(o1);
00129 } else {
00130 children.put(o1, s2);
00131 s2.remove(o3);
00132 } else
00133 if (s2 == null) {
00134
00135 } else {
00136 s1.addAll(s2);
00137 s1.remove(o1);
00138 s1.remove(o3);
00139 }
00140 Iterator i;
00141 if (s2 != null) {
00142 i = s2.iterator();
00143 while (i.hasNext()) {
00144 s1 = (Set) parents.get(o2 = (TypeVariable) i.next());
00145 s1.remove(o3);
00146 if (o2 != o1)
00147 s1.add(o1);
00148 }
00149 }
00150 s1 = (Set) parents.get(o1);
00151 s2 = (Set) parents.get(o3);
00152 if (s1 == null)
00153 if (s2 == null) {
00154 s1 = new HashSet();
00155 parents.put(o1, s1);
00156 s1.remove(o1);
00157 } else {
00158 parents.put(o1, s2);
00159 s2.remove(o3);
00160 } else
00161 if (s2 == null) {
00162
00163 } else {
00164 s1.addAll(s2);
00165 s1.remove(o1);
00166 s1.remove(o3);
00167 }
00168 if (s2 != null) {
00169 i = s2.iterator();
00170 while (i.hasNext()) {
00171 s1 = (Set) children.get(o2 = (TypeVariable) i.next());
00172 s1.remove(o3);
00173 if (o2 != o1)
00174 s1.add(o1);
00175 }
00176 }
00177 children.remove(o3);
00178 parents.remove(o3);
00179 }
00180 }
00181
00182
00183
00184
00185
00186
00187 private Vector dfsCycle(HashSet marked, Object o, Vector path) {
00188 marked.add(o);
00189 path.add(ufs.find(o));
00190 for (Iterator i = getChildren((TypeVariable) o).iterator(); i.hasNext();) {
00191 Object child = i.next();
00192 if (path.contains(child)) return path;
00193 if (!marked.contains(child)) {
00194 Vector cycle = dfsCycle(marked, child, path);
00195 if (cycle != null) return cycle;
00196 }
00197 }
00198 path.remove(path.size() - 1);
00199 return null;
00200 }
00201
00202
00203
00204
00205
00206
00207
00208
00209 public boolean equals(Object obj) {
00210
00211
00212
00213 return super.equals(obj);
00214 }
00215
00216
00217
00218
00219
00220
00221 public Set getChildren(TypeVariable o) {
00222 Set s = (Set) children.get(ufs.find(o));
00223 if (s == null)
00224 s = new HashSet();
00225 return s;
00226 }
00227
00228
00229
00230
00231
00232 public Set getNotSingleConnected() {
00233 UnionFindSet u = new UnionFindSet();
00234 for (Enumeration e = children.keys(); e.hasMoreElements();) {
00235 Object key = e.nextElement();
00236 u.add(key);
00237 for (Iterator i = ((Set) children.get(key)).iterator(); i.hasNext();) {
00238 Object data = i.next();
00239 u.add(data);
00240 u.union(key, data);
00241 }
00242 }
00243 return u;
00244 }
00245
00246
00247
00248
00249
00250
00251 public Set getParents(TypeVariable o) {
00252 Set s = (Set) parents.get((TypeVariable) ufs.find(o));
00253 if (s == null)
00254 s = new HashSet();
00255 return s;
00256 }
00257
00258
00259
00260
00261
00262
00263 public Object getType(TypeVariable o) {
00264 return ufs.getAttribute(o);
00265 }
00266
00267
00268
00269
00270
00271 public TypeVariable getTypeVariable(Object t) {
00272 return (TypeVariable) typeTypeVarTable.get(t);
00273 }
00274
00275
00276
00277
00278
00279
00280
00281 public int hashCode() {
00282
00283
00284
00285 return super.hashCode();
00286 }
00287
00288
00289
00290
00291
00292
00293 public boolean isLeaf(TypeVariable o) {
00294 Set s = (Set) children.get(o);
00295 return s == null || s.size() == 0;
00296 }
00297
00298
00299
00300
00301
00302
00303 public boolean isParent(TypeVariable o) {
00304 Set s = (Set) parents.get(o);
00305 return s == null || s.size() == 0;
00306 }
00307
00308
00309
00310
00311
00312 public void quickCombine(TypeVariable tv1, TypeVariable tv2) {
00313 ufs.union(tv1, tv2);
00314 }
00315
00316
00317
00318 public void removeCycles() {
00319 int count = 0;
00320 for (Iterator i = getNotSingleConnected().iterator(); i.hasNext();) {
00321 HashSet marked = new HashSet();
00322 for (Iterator j = ((Set) i.next()).iterator(); j.hasNext();) {
00323 Object o = j.next();
00324 if (!marked.contains(o)) {
00325 boolean f = true;
00326 while (f) {
00327 HashSet localMarked = new HashSet();
00328 Vector cycle = dfsCycle(localMarked, o, new Vector());
00329 if (cycle != null) {
00330 if (cycle.size() > 1) {
00331 f = true;
00332 count++;
00333 o = cycle.remove(0);
00334 for (Iterator k = cycle.iterator(); k.hasNext();) {
00335 combine((TypeVariable) o, (TypeVariable) k.next());
00336 }
00337 } else {
00338 f = false;
00339 marked.addAll(localMarked);
00340 }
00341 } else {
00342 f = false;
00343 marked.addAll(localMarked);
00344 }
00345 }
00346 }
00347 }
00348 }
00349
00350 }
00351
00352
00353
00354
00355 public String toString() {
00356 return ufs.toString();
00357 }
00358 }