Main Page   Packages   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members  

TypeDependencyGraph.java

00001 package edu.ksu.cis.bandera.abstraction.typeinference;
00002 
00003 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00004  * Bandera, a Java(TM) analysis and transformation toolkit           *
00005  * Copyright (C) 1998, 1999, 2000   Shawn Laubach (laubach@acm.org)  *
00006  * All rights reserved.                                              *
00007  *                                                                   *
00008  * This work was done as a project in the SAnToS Laboratory,         *
00009  * Department of Computing and Information Sciences, Kansas State    *
00010  * University, USA (http://www.cis.ksu.edu/santos).                  *
00011  * It is understood that any modification not identified as such is  *
00012  * not covered by the preceding statement.                           *
00013  *                                                                   *
00014  * This work is free software; you can redistribute it and/or        *
00015  * modify it under the terms of the GNU Library General Public       *
00016  * License as published by the Free Software Foundation; either      *
00017  * version 2 of the License, or (at your option) any later version.  *
00018  *                                                                   *
00019  * This work is distributed in the hope that it will be useful,      *
00020  * but WITHOUT ANY WARRANTY; without even the implied warranty of    *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU *
00022  * Library General Public License for more details.                  *
00023  *                                                                   *
00024  * You should have received a copy of the GNU Library General Public *
00025  * License along with this toolkit; if not, write to the             *
00026  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,      *
00027  * Boston, MA  02111-1307, USA.                                      *
00028  *                                                                   *
00029  * Java is a trademark of Sun Microsystems, Inc.                     *
00030  *                                                                   *
00031  * To submit a bug report, send a comment, or get the latest news on *
00032  * this project and other SAnToS projects, please visit the web-site *
00033  *                http://www.cis.ksu.edu/santos                      *
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  * Graph constructor comment.
00045  */
00046 public TypeDependencyGraph() {
00047     ufs = new UnionFindSet();
00048     parents = new Hashtable();
00049     children = new Hashtable();
00050 }
00051 /**
00052  * Insert the method's description here.
00053  * Creation date: (8/14/00 8:24:55 PM)
00054  * @param o java.lang.Object
00055  */
00056 public void add(TypeVariable o) {
00057     ufs.add(o);
00058 }
00059 /**
00060  * Insert the method's description here.
00061  * Creation date: (8/16/00 1:33:59 PM)
00062  * @param parent java.lang.Object
00063  * @param child java.lang.Object
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  * Insert the method's description here.
00089  * Creation date: (8/17/00 3:19:02 PM)
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  * Insert the method's description here.
00104  * Creation date: (8/16/00 1:37:04 PM)
00105  * @param o1 java.lang.Object
00106  * @param o2 java.lang.Object
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                     // Do Nothing
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                     // Do Nothing
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  * @param marked java.util.HashSet
00184  * @param o java.lang.Object
00185  * @param cycle java.util.Vector
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  * Compares two objects for equality. Returns a boolean that indicates
00203  * whether this object is equivalent to the specified object. This method
00204  * is used when an object is stored in a hashtable.
00205  * @param obj the Object to compare with
00206  * @return true if these Objects are equal; false otherwise.
00207  * @see java.util.Hashtable
00208  */
00209 public boolean equals(Object obj) {
00210     // Insert code to compare the receiver and obj here.
00211     // This implementation forwards the message to super.  You may replace or supplement this.
00212     // NOTE: obj might be an instance of any class
00213     return super.equals(obj);
00214 }
00215 /**
00216  * Insert the method's description here.
00217  * Creation date: (8/14/00 8:31:35 PM)
00218  * @return java.util.Set
00219  * @param o java.lang.Object
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  * Insert the method's description here.
00229  * Creation date: (8/17/00 3:38:19 PM)
00230  * @return java.util.Set
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  * Insert the method's description here.
00247  * Creation date: (8/14/00 8:31:35 PM)
00248  * @return java.util.Set
00249  * @param o java.lang.Object
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  * Insert the method's description here.
00259  * Creation date: (8/17/00 3:32:00 PM)
00260  * @return ca.mcgill.sable.soot.Type
00261  * @param o java.lang.Object
00262  */
00263 public Object getType(TypeVariable o) {
00264     return ufs.getAttribute(o);
00265 }
00266 /**
00267  * 
00268  * @return edu.ksu.cis.bandera.abps.typing.TypeVariable
00269  * @param t ca.mcgill.sable.soot.Type
00270  */
00271 public TypeVariable getTypeVariable(Object t) {
00272     return (TypeVariable) typeTypeVarTable.get(t);
00273 }
00274 /**
00275  * Generates a hash code for the receiver.
00276  * This method is supported primarily for
00277  * hash tables, such as those provided in java.util.
00278  * @return an integer hash code for the receiver
00279  * @see java.util.Hashtable
00280  */
00281 public int hashCode() {
00282     // Insert code to generate a hash code for the receiver here.
00283     // This implementation forwards the message to super.  You may replace or supplement this.
00284     // NOTE: if two objects are equal (equals(Object) returns true) they must have the same hash code
00285     return super.hashCode();
00286 }
00287 /**
00288  * Insert the method's description here.
00289  * Creation date: (8/15/00 12:20:55 PM)
00290  * @return boolean
00291  * @param o java.lang.Object
00292  */
00293 public boolean isLeaf(TypeVariable o) {
00294     Set s = (Set) children.get(o);
00295     return s == null || s.size() == 0;
00296 }
00297 /**
00298  * Insert the method's description here.
00299  * Creation date: (8/15/00 12:20:55 PM)
00300  * @return boolean
00301  * @param o java.lang.Object
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  * @param tv1 edu.ksu.cis.bandera.abps.typing.TypeVariable
00310  * @param tv2 edu.ksu.cis.bandera.abps.typing.TypeVariable
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     //System.out.println("  Cycles removed: " + count);
00350 }
00351 /**
00352  * Returns a String that represents the value of this object.
00353  * @return a string representation of the receiver
00354  */
00355 public String toString() {
00356     return ufs.toString();
00357 }
00358 }

Generated at Thu Feb 7 06:58:43 2002 for Bandera by doxygen1.2.10 written by Dimitri van Heesch, © 1997-2001