00001 package edu.ksu.cis.bandera.abstraction;
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 java.util.*;
00036 import edu.ksu.cis.bandera.abstraction.util.*;
00037 public class CoercionManager {
00038 private Hashtable coercions;
00039 private Hashtable reverse;
00040
00041
00042
00043 public CoercionManager(Collection abstractionNames) {
00044 coercions = new Hashtable();
00045 reverse = new Hashtable();
00046
00047
00048 for (Iterator i = abstractionNames.iterator(); i.hasNext();) {
00049 Abstraction a = (Abstraction) AbstractionClassLoader.invokeMethod((String) i.next(), "v", new Class[0], null, new Object[0]);
00050 if (a instanceof IntegralAbstraction) {
00051 add(a, ConcreteIntegralAbstraction.v());
00052 } else if (a instanceof RealAbstraction) {
00053 add(a, ConcreteRealAbstraction.v());
00054 ((Set) coercions.get(ConcreteIntegralAbstraction.v())).add(a);
00055 ((Set) reverse.get(a)).add(ConcreteIntegralAbstraction.v());
00056 }
00057 }
00058
00059 ((Set) coercions.get(ConcreteIntegralAbstraction.v())).add(ConcreteRealAbstraction.v());
00060 HashSet set = new HashSet();
00061 set.add(ConcreteIntegralAbstraction.v());
00062 reverse.put(ConcreteRealAbstraction.v(), set);
00063 }
00064 public void add(edu.ksu.cis.bandera.abstraction.Abstraction ac, edu.ksu.cis.bandera.abstraction.Abstraction abs) {
00065 Set l;
00066 if ((l = (Set) coercions.get(abs)) == null) {
00067 l = new HashSet();
00068 coercions.put(abs, l);
00069 }
00070 l.add(ac);
00071 if ((l = (Set) reverse.get(ac)) == null) {
00072 l = new HashSet();
00073 reverse.put(ac, l);
00074 }
00075 l.add(abs);
00076 process();
00077 }
00078 public boolean coerciable(edu.ksu.cis.bandera.abstraction.Abstraction from, edu.ksu.cis.bandera.abstraction.Abstraction to) {
00079 if (from.equals(to)) return true;
00080 Set l = (Set) coercions.get(from);
00081 if (l == null)
00082 return false;
00083 else
00084 return l.contains(to);
00085 }
00086 public Set get(edu.ksu.cis.bandera.abstraction.Abstraction t) {
00087 Set s = (Set) coercions.get(t);
00088
00089
00090 if (s == null)
00091 {
00092 HashSet temp = new HashSet();
00093
00094 if (t instanceof ClassAbstraction)
00095 {
00096 temp.add(ClassAbstraction.v("java.lang.Object"));
00097 }
00098 return temp;
00099 }
00100
00101 else
00102 return s;
00103 }
00104
00105
00106
00107
00108
00109
00110 public edu.ksu.cis.bandera.abstraction.Abstraction lub(Set types) {
00111 boolean allCommon, commonLUB;
00112 Set s, p, t;
00113 Abstraction childBox, common;
00114 Iterator it;
00115 s = null;
00116 p = null;
00117 allCommon = true;
00118 commonLUB = true;
00119 common = null;
00120 if (types.size() == 0) {
00121 System.out.println("What do I do in lub.");
00122 return null;
00123 } else {
00124 for (it = types.iterator(); it.hasNext();) {
00125 t = new HashSet();
00126 Object o = it.next();
00127 childBox = (edu.ksu.cis.bandera.abstraction.Abstraction) o;
00128 if (childBox != null) {
00129 t.addAll(get(childBox));
00130 t.add(childBox);
00131 if (common == null)
00132 common = childBox;
00133 else
00134 if (common != childBox && !common.equals(childBox)) {
00135 allCommon = false;
00136
00137 if (common instanceof ClassAbstraction)
00138 {
00139 if (childBox instanceof ClassAbstraction || childBox instanceof ArrayAbstraction)
00140 {
00141 common = ClassAbstraction.v("java.lang.Object");
00142 } else
00143 if (!get(childBox).contains(common))
00144 if (get(common).contains(childBox))
00145 common = childBox;
00146 else
00147 commonLUB = false;
00148 } else
00149 {
00150 if (common instanceof ArrayAbstraction)
00151 {
00152 if (childBox instanceof ClassAbstraction || childBox instanceof ArrayAbstraction)
00153 {
00154 common = ClassAbstraction.v("java.lang.Object");
00155 }
00156 } else
00157 if (!get(childBox).contains(common))
00158 if (get(common).contains(childBox))
00159 common = childBox;
00160 else
00161 commonLUB = false;
00162 }
00163
00164 }
00165 } else {
00166 allCommon = false;
00167 commonLUB = false;
00168 }
00169 if (s == null) {
00170 s = new HashSet();
00171 s.addAll(t);
00172 } else
00173 s.retainAll(t);
00174 if (t.size() > 0)
00175 if (p == null) {
00176 p = new HashSet();
00177 p.addAll(t);
00178 } else
00179 p.retainAll(t);
00180 }
00181 if (s == null) {
00182 return null;
00183 } else
00184 if (s.size() == 1) {
00185 return (edu.ksu.cis.bandera.abstraction.Abstraction) s.toArray()[0];
00186 } else
00187 if (allCommon) {
00188 return common;
00189 } else
00190 if (commonLUB) {
00191 return common;
00192 } else {
00193 return null;
00194 }
00195 }
00196 }
00197 protected void process() {
00198 boolean change = true;
00199 while (change) {
00200 change = false;
00201 Iterator i = coercions.keySet().iterator();
00202 while (i.hasNext()) {
00203 Object a = i.next();
00204 Set s = (Set) coercions.get(a);
00205 if (s != null) {
00206 Iterator j = s.iterator();
00207 while (j.hasNext()) {
00208 Object b = j.next();
00209 Set t = (Set) coercions.get(b);
00210 if (t != null) {
00211 if (s.addAll(t))
00212 change = true;
00213 }
00214 }
00215 }
00216 }
00217 }
00218 Iterator i = coercions.keySet().iterator();
00219 while (i.hasNext()) {
00220 Object a = i.next();
00221 Set s = (Set) coercions.get(a);
00222 Iterator j = s.iterator();
00223 while (j.hasNext()) {
00224 Object b = j.next();
00225 Set t = (Set) reverse.get(b);
00226 t.add(a);
00227 }
00228 }
00229 }
00230 }