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

TypeInference.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  * Modifications by Robby (robby@cis.ksu.edu) are                    *
00009  * Copyright (C) 2000 Robby.  All rights reserved.                   *
00010  *                                                                   *
00011  * This work was done as a project in the SAnToS Laboratory,         *
00012  * Department of Computing and Information Sciences, Kansas State    *
00013  * University, USA (http://www.cis.ksu.edu/santos).                  *
00014  * It is understood that any modification not identified as such is  *
00015  * not covered by the preceding statement.                           *
00016  *                                                                   *
00017  * This work is free software; you can redistribute it and/or        *
00018  * modify it under the terms of the GNU Library General Public       *
00019  * License as published by the Free Software Foundation; either      *
00020  * version 2 of the License, or (at your option) any later version.  *
00021  *                                                                   *
00022  * This work is distributed in the hope that it will be useful,      *
00023  * but WITHOUT ANY WARRANTY; without even the implied warranty of    *
00024  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU *
00025  * Library General Public License for more details.                  *
00026  *                                                                   *
00027  * You should have received a copy of the GNU Library General Public *
00028  * License along with this toolkit; if not, write to the             *
00029  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,      *
00030  * Boston, MA  02111-1307, USA.                                      *
00031  *                                                                   *
00032  * Java is a trademark of Sun Microsystems, Inc.                     *
00033  *                                                                   *
00034  * To submit a bug report, send a comment, or get the latest news on *
00035  * this project and other SAnToS projects, please visit the web-site *
00036  *                http://www.cis.ksu.edu/santos                      *
00037  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00038 import java.util.*;
00039 import ca.mcgill.sable.soot.*;
00040 import ca.mcgill.sable.soot.jimple.*;
00041 import edu.ksu.cis.bandera.jext.*;
00042 import edu.ksu.cis.bandera.abstraction.*;
00043 import edu.ksu.cis.bandera.abstraction.gui.*;
00044 import edu.ksu.cis.bandera.abstraction.util.*;
00045 public class TypeInference extends IRNodes {
00046     private static final Jimple jimple = Jimple.v();
00047     private CoercionManager coercionManager;
00048     private TypeTable nodes;
00049     private List constraints;
00050     private List params;
00051     private LeftAssignExprSwitch lswitch;
00052     private TypeStructure returnValue;
00053     private Hashtable method2params = new Hashtable();
00054     private Hashtable method2return = new Hashtable();
00055     private Hashtable local2method = new Hashtable();
00056     private SootMethod currentMethod;
00057     private RefHashTable ast2TypeStruct = new RefHashTable();
00058     private TypeDependencyGraph tdg = new TypeDependencyGraph();
00059     private Hashtable errors = new Hashtable();
00060     private HashSet methodsInheritance = new HashSet();
00061     private Hashtable interfaceMethodMethod = new Hashtable();
00062     private Vector conflicts = new Vector();
00063 /**
00064  * Insert the method's description here.
00065  * Creation date: (1/14/00 1:31:44 PM)
00066  */
00067 public TypeInference() {
00068     nodes = new TypeTable();
00069     constraints = new Vector();
00070     params = new Vector();
00071     this.coercionManager = new CoercionManager(AbstractionLibraryManager.getAbstractions());
00072 }
00073 public void caseAddExpr(AddExpr v) {
00074     doOp(v);
00075 }
00076 public void caseAndExpr(AndExpr v) {
00077     doOp(v);
00078 }
00079 public void caseArrayRef(ArrayRef v) {
00080     TypeStructure varnode = getTypeStructure(v);
00081     ArrayTypeStructure var = (ArrayTypeStructure) getTypeStructure(v.getBase());
00082     TypeStructure index = var.getIndex();
00083     v.getIndex().apply(this);
00084     constraints.addAll(index.genEqualConstraints((TypeStructure) getResult()));
00085     TypeStructure base = var.getElements();
00086     constraints.addAll(varnode.genEqualConstraints(base));
00087     TypeStructure ts = getCoercedTypeStructure(v);
00088     constraints.addAll(ts.genCoerceConstraints(varnode));
00089     setResult(varnode);
00090 }
00091 public void caseAssignStmt(AssignStmt stmt) {
00092     doDefinitionStmt(stmt);
00093 }
00094 /**
00095  * This method was created in VisualAge.
00096  * @param v ca.mcgill.sable.soot.jimple.CastExpr
00097  */
00098 public void caseCastExpr(CastExpr v) {
00099     v.getOp().apply(this);
00100     TypeStructure opts = (TypeStructure) getResult();
00101     TypeStructure ts = getTypeStructure(v);
00102     if (v.getType() instanceof BaseType)
00103         constraints.addAll(ts.genEqualConstraints(opts));
00104     setResult(ts);
00105 }
00106 /**
00107  * Insert the method's description here.
00108  * Creation date: (5/23/00 9:31:52 AM)
00109  * @param v ca.mcgill.sable.soot.jimple.CaughtExceptionRef
00110  */
00111 public void caseCaughtExceptionRef(CaughtExceptionRef v) {
00112     TypeStructure ts = getTypeStructure(v);
00113     setResult(ts);
00114 }
00115 /**
00116  * Insert the method's description here.
00117  * Creation date: (5/31/00 1:48:07 PM)
00118  * @param v edu.ksu.cis.bandera.jext.ChooseExpr
00119  */
00120 public void caseChooseExpr(ChooseExpr v) {
00121     BaseTypeStructure ts = (BaseTypeStructure) getTypeStructure(v);
00122     Abstraction t = ConcreteIntegralAbstraction.v();
00123     tdg.addType(t);
00124     tdg.combine(tdg.getTypeVariable(t), ts.getVar());
00125     setResult(ts);
00126 }
00127 public void caseCmpExpr(CmpExpr v) {
00128     doOp(v);
00129 }
00130 public void caseCmpgExpr(CmpgExpr v) {
00131     doOp(v);
00132 }
00133 public void caseCmplExpr(CmplExpr v) {
00134     doOp(v);
00135 }
00136 public void caseDivExpr(DivExpr v) {
00137     doOp(v);
00138 }
00139 public void caseDoubleConstant(DoubleConstant v) {
00140     TypeStructure cts = getCoercedTypeStructure(v);
00141     TypeStructure ts = getTypeStructure(v);
00142     constraints.addAll(cts.genCoerceConstraints(ts));
00143     setResult(cts);
00144 }
00145 public void caseEnterMonitorStmt(EnterMonitorStmt stmt) {
00146     stmt.getOp().apply(this);
00147     setResult(null);
00148 }
00149 public void caseEqExpr(EqExpr v) {
00150     doTest(v);
00151 }
00152 public void caseExitMonitorStmt(ExitMonitorStmt stmt) {
00153     stmt.getOp().apply(this);
00154     setResult(null);
00155 }
00156 public void caseFloatConstant(FloatConstant v) {
00157     TypeStructure cts = getCoercedTypeStructure(v);
00158     TypeStructure ts = getTypeStructure(v);
00159     constraints.addAll(cts.genCoerceConstraints(ts));
00160     setResult(cts);
00161 }
00162 public void caseGeExpr(GeExpr v) {
00163     doTest(v);
00164 }
00165 public void caseGotoStmt(GotoStmt stmt) {
00166     setResult(null);
00167 }
00168 public void caseGtExpr(GtExpr v) {
00169     doTest(v);
00170 }
00171 public void caseIdentityStmt(IdentityStmt stmt) {
00172     doDefinitionStmt(stmt);
00173 }
00174 public void caseIfStmt(IfStmt stmt) {
00175     stmt.getCondition().apply(this);
00176 }
00177 /**
00178  * This method was created in VisualAge.
00179  * @param v ca.mcgill.sable.soot.jimple.InstanceFieldRef
00180  */
00181 public void caseInstanceFieldRef(InstanceFieldRef v) {
00182     doFieldRef(v);
00183 }
00184 public void caseIntConstant(IntConstant v) {
00185     TypeStructure cts = getCoercedTypeStructure(v);
00186     TypeStructure ts = getTypeStructure(v);
00187     constraints.addAll(cts.genCoerceConstraints(ts));
00188     setResult(cts);
00189 }
00190 /**
00191  * 
00192  * @param v ca.mcgill.sable.soot.jimple.InterfaceInvokeExpr
00193  */
00194 public void caseInterfaceInvokeExpr(InterfaceInvokeExpr v) {
00195     SootMethod sm = v.getMethod();
00196     v.setMethod((SootMethod) interfaceMethodMethod.get(sm));
00197     doInvokeExpr(v);
00198     v.setMethod(sm);
00199 }
00200 /**
00201  * Insert the method's description here.
00202  * Creation date: (5/25/00 2:25:00 PM)
00203  * @param s ca.mcgill.sable.soot.jimple.InvokeStmt
00204  */
00205 public void caseInvokeStmt(InvokeStmt s) {
00206     s.getInvokeExpr().apply(this);
00207 }
00208 public void caseLeExpr(LeExpr v) {
00209     doTest(v);
00210 }
00211 public void caseLengthExpr(LengthExpr v) {
00212     ArrayTypeStructure var = (ArrayTypeStructure) getTypeStructure(v.getOp());
00213     TypeStructure varnode = getTypeStructure(v);
00214     constraints.addAll(varnode.genEqualConstraints(var.getIndex()));
00215     setResult(varnode);
00216 }
00217 public void caseLocal(Local v) {
00218     local2method.put(v, currentMethod);
00219     TypeStructure node = getCoercedTypeStructure(v);
00220     TypeStructure varnode = getTypeStructure(v);
00221     constraints.addAll(node.genCoerceConstraints(varnode));
00222     setResult(node);
00223 }
00224 public void caseLongConstant(LongConstant v) {
00225     TypeStructure cts = getCoercedTypeStructure(v);
00226     TypeStructure ts = getTypeStructure(v);
00227     constraints.addAll(cts.genCoerceConstraints(ts));
00228     setResult(cts);
00229 }
00230 /**
00231  * 
00232  * @param stmt ca.mcgill.sable.soot.jimple.LookupSwitchStmt
00233  */
00234 public void caseLookupSwitchStmt(LookupSwitchStmt stmt) {
00235     stmt.getKey().apply(this);
00236 }
00237 public void caseLtExpr(LtExpr v) {
00238     doTest(v);
00239 }
00240 public void caseMulExpr(MulExpr v) {
00241     doOp(v);
00242 }
00243 public void caseNeExpr(NeExpr v) {
00244     doTest(v);
00245 }
00246 public void caseNegExpr(NegExpr v) {
00247     v.getOp().apply(this);
00248     TypeStructure op = (TypeStructure) getResult();
00249     TypeStructure varnode = getTypeStructure(v);
00250     constraints.addAll(varnode.genEqualConstraints(op));
00251     setResult(varnode);
00252 }
00253 /**
00254  * This method was created in VisualAge.
00255  * @param v ca.mcgill.sable.soot.jimple.NewArrayExpr
00256  */
00257 public void caseNewArrayExpr(NewArrayExpr v) {
00258     ArrayTypeStructure node = (ArrayTypeStructure) getTypeStructure(v);
00259     v.getSize().apply(this);
00260     TypeStructure index = node.getIndex();
00261     constraints.addAll(index.genEqualConstraints((TypeStructure) getResult()));
00262     setResult(node);
00263 }
00264 /**
00265  * This method was created in VisualAge.
00266  * @param v ca.mcgill.sable.soot.jimple.NewExpr
00267  */
00268 public void caseNewExpr(NewExpr v) {
00269     TypeStructure varnode = getTypeStructure(v);
00270     setResult(varnode);
00271 }
00272 public void caseNewMultiArrayExpr(NewMultiArrayExpr v) {
00273     defaultCase(v);
00274 }
00275 public void caseNopStmt(NopStmt stmt) {
00276     setResult(null);
00277 }
00278 public void caseNullConstant(NullConstant v) {
00279     setResult(getTypeStructure(NullConstant.v()));
00280 }
00281 public void caseOrExpr(OrExpr v) {
00282     doOp(v);
00283 }
00284 public void caseParameterRef(ParameterRef v) {
00285     SootMethod method = v.getMethod();
00286     List l;
00287     if ((l = (Vector) method2params.get(method)) == null) {
00288         l = new Vector();
00289         method2params.put(method, l);
00290     }
00291     if (!l.contains(v))
00292         l.add(v);
00293     TypeStructure varnode = getTypeStructure(v);
00294     constraints.addAll(varnode.genEqualConstraints((TypeStructure) params.get(v.getIndex() + 1)));
00295     setResult(varnode);
00296 }
00297 public void caseRemExpr(RemExpr v) {
00298     doOp(v);
00299 }
00300 public void caseReturnStmt(ReturnStmt stmt) {
00301     if (returnValue != null) {
00302         stmt.getReturnValue().apply(this);
00303         constraints.addAll(returnValue.genCoerceConstraints((TypeStructure) getResult()));
00304     }
00305     setResult(null);
00306 }
00307 /**
00308  * Insert the method's description here.
00309  * Creation date: (5/24/00 2:58:48 PM)
00310  * @param s ca.mcgill.sable.soot.jimple.ReturnVoidStmt
00311  */
00312 public void caseReturnVoidStmt(ReturnVoidStmt s) {
00313     setResult(null);
00314 }
00315 public void caseShlExpr(ShlExpr v) {
00316     doOp(v);
00317 }
00318 public void caseShrExpr(ShrExpr v) {
00319     doOp(v);
00320 }
00321 /**
00322  * This method was created in VisualAge.
00323  * @param v ca.mcgill.sable.soot.jimple.VirtualInvokeExpr
00324  */
00325 public void caseSpecialInvokeExpr(SpecialInvokeExpr v) {
00326     doInvokeExpr(v);
00327 }
00328 /**
00329  * Insert the method's description here.
00330  * Creation date: (1/19/00 10:46:59 PM)
00331  * @param v ca.mcgill.sable.soot.jimple.StaticFieldRef
00332  */
00333 public void caseStaticFieldRef(StaticFieldRef v) {
00334     doFieldRef(v);
00335 }
00336 /**
00337  * This method was created in VisualAge.
00338  * @param v ca.mcgill.sable.soot.jimple.StaticInvokeExpr
00339  */
00340 public void caseStaticInvokeExpr(StaticInvokeExpr v) {
00341     doInvokeExpr(v);
00342 }
00343 public void caseStringConstant(StringConstant v) {
00344     TypeStructure varnode = getTypeStructure(v);
00345     setResult(varnode);
00346 }
00347 public void caseSubExpr(SubExpr v) {
00348     doOp(v);
00349 }
00350 public void caseThisRef(ThisRef v) {
00351     TypeStructure ts = getTypeStructure(v);
00352     setResult(ts);
00353 }
00354 public void caseThrowStmt(ThrowStmt stmt) {
00355     setResult(null);
00356 }
00357 public void caseUshrExpr(UshrExpr v) {
00358     doOp(v);
00359 }
00360 /**
00361  * This method was created in VisualAge.
00362  * @param v ca.mcgill.sable.soot.jimple.VirtualInvokeExpr
00363  */
00364 public void caseVirtualInvokeExpr(VirtualInvokeExpr v) {
00365     SootMethod sm = v.getMethod();
00366     if (interfaceMethodMethod.get(sm) != null) {
00367         v.setMethod((SootMethod) interfaceMethodMethod.get(sm));
00368     }
00369     doInvokeExpr(v);
00370     v.setMethod(sm);
00371 }
00372 public void caseXorExpr(XorExpr v) {
00373     doOp(v);
00374 }
00375 /**
00376  * Insert the method's description here.
00377  * Creation date: (1/14/00 12:05:12 PM)
00378  * @param method ca.mcgill.sable.soot.SootMethod
00379  * @param params ca.mcgill.sable.util.List
00380  * @param vars ca.mcgill.sable.util.Map
00381  */
00382 public void createConstraints(SootMethod method, List params, TypeStructure ret) {
00383     System.out.print(".");
00384     if (method2params.get(method) != null) {
00385         List p = (List) method2params.get(method);
00386         Iterator i = p.iterator();
00387         while (i.hasNext()) {
00388             ParameterRef param = (ParameterRef) i.next();
00389             TypeStructure varnode = getTypeStructure(param);
00390             constraints.addAll(varnode.genEqualConstraints((TypeStructure) params.get(param.getIndex() + 1)));
00391         }
00392         if ((ret != null) && !(method.getReturnType() instanceof VoidType))
00393             constraints.addAll(ret.genEqualConstraints((TypeStructure) method2return.get(method)));
00394         return;
00395     }
00396     if ((ret != null) && !(method.getReturnType() instanceof VoidType))
00397         method2return.put(method, ret);
00398     SootMethod oldMethod = currentMethod;
00399     currentMethod = method;
00400     lswitch = new LeftAssignExprSwitch(constraints, this, null, null);
00401     TypeStructure oldRet = returnValue;
00402     returnValue = ret;
00403     this.params = params;
00404     try {   // robbyjo's patch
00405         JimpleBody body = (JimpleBody) method.getBody(Jimple.v());
00406         StmtList stmts = body.getStmtList();
00407         ca.mcgill.sable.util.Iterator i = stmts.iterator();
00408         Stmt current;
00409         while (i.hasNext()) {
00410             current = (Stmt) i.next();
00411             current.apply(this);
00412         }
00413     } catch(Exception e)  // robbyjo's patch
00414     {
00415     }
00416     returnValue = oldRet;
00417     currentMethod = oldMethod;
00418 }
00419 /**
00420  * 
00421  * @param sm ca.mcgill.sable.soot.SootMethod
00422  */
00423 private void createInheritanceConstraints(SootMethod sm) {
00424     if (methodsInheritance.contains(sm) || !sm.isBodyStored(jimple) || sm.isStatic() || "<init>".equals(sm.getName()) || "<clinit>".equals(sm.getName())) return;
00425     HashSet overwrittenMethods = new HashSet();
00426     SootClass sc = sm.getDeclaringClass();
00427     ca.mcgill.sable.util.List parmTypes = sm.getParameterTypes();
00428     String name = sm.getName();
00429     SootMethod origSootMethod = sm;
00430     do {
00431         overwrittenMethods.add(sm);
00432         sm = null;
00433         while (sc.hasSuperClass() && (sm == null)) {
00434             for (ca.mcgill.sable.util.Iterator i = sc.getInterfaces().iterator(); i.hasNext();) {
00435                 SootClass scInterface = (SootClass) i.next();
00436                 if (scInterface.declaresMethod(name, parmTypes)) {
00437                     interfaceMethodMethod.put(scInterface.getMethod(name, parmTypes), sc.getMethod(name, parmTypes));
00438                 }
00439             }
00440             sc = sc.getSuperClass();
00441             if (sc.declaresMethod(name, parmTypes)) {
00442                 sm = sc.getMethod(name, parmTypes);
00443                 if (Modifier.isAbstract(sm.getModifiers())) {
00444                     interfaceMethodMethod.put(sm, origSootMethod);
00445                     sm = null;
00446                 } else if (!sm.isBodyStored(jimple) || sm.isStatic() || "<init>".equals(sm.getName()) || "<clinit>".equals(sm.getName())) sm = null;
00447             } else sm = null;
00448         }
00449     } while (sm != null && !methodsInheritance.contains(sm));
00450     if (sm != null) overwrittenMethods.add(sm);
00451 
00452     methodsInheritance.addAll(overwrittenMethods);
00453     Iterator i = overwrittenMethods.iterator();
00454     sm = (SootMethod) i.next();
00455     TypeStructure[] args = new TypeStructure[sm.getParameterCount()];
00456     TypeStructure ret = createInheritanceConstraintsMethod(sm, args);
00457     while (i.hasNext()) {
00458         sm = (SootMethod) i.next();
00459         TypeStructure[] tempArgs = new TypeStructure[sm.getParameterCount()];
00460         TypeStructure tempRet = createInheritanceConstraintsMethod(sm, tempArgs);
00461         for (int j = 0; j < args.length; j++) {
00462             constraints.addAll(args[j].genEqualConstraints(tempArgs[j]));
00463         }
00464         if (ret != null)
00465             constraints.addAll(ret.genEqualConstraints(tempRet));
00466     }
00467 }
00468 /**
00469  * 
00470  * @return edu.ksu.cis.bandera.abps.typing.TypeStructure
00471  * @param sm ca.mcgill.sable.soot.SootMethod
00472  * @param args edu.ksu.cis.bandera.abps.typing.TypeStructure[]
00473  */
00474 private TypeStructure createInheritanceConstraintsMethod(SootMethod sm, TypeStructure[] args) {
00475     Object[] stmts = ((JimpleBody) sm.getBody(jimple)).getStmtList().toArray();
00476     Vector returnTypeStructures = new Vector();
00477 
00478     for (int i = 0; i < stmts.length; i++) {
00479         if (stmts[i] instanceof ReturnStmt) {
00480             returnTypeStructures.add(getTypeStructure((((ReturnStmt) stmts[i]).getReturnValue())));
00481         } else if (stmts[i] instanceof IdentityStmt) {
00482             IdentityStmt is = (IdentityStmt) stmts[i];
00483             if (is.getRightOp() instanceof ParameterRef) {
00484                 args[((ParameterRef) is.getRightOp()).getIndex()] = getTypeStructure(is.getLeftOp());
00485             }
00486         }
00487     }   
00488 
00489     if (returnTypeStructures.size() == 0) 
00490         return null;
00491         
00492     TypeStructure ts = (TypeStructure) returnTypeStructures.remove(0);
00493     for (Iterator i = returnTypeStructures.iterator(); i.hasNext();) {
00494         constraints.addAll(ts.genEqualConstraints((TypeStructure) i.next()));
00495     }
00496     method2return.put(sm, ts);
00497     return ts;
00498 }
00499 public void defaultCase(Object v) {
00500     System.out.println("Default Case:  " + v + "\t" + v.getClass());
00501     if (v instanceof Expr)
00502         throw new RuntimeException("Unhandled expression " + v + ":" + v.getClass() + " in type inference.");
00503     System.out.println("Unknown in type inference:  " + v.getClass());
00504 }
00505 /**
00506  * Insert the method's description here.
00507  * Creation date: (8/18/00 9:11:50 AM)
00508  * @param stmt ca.mcgill.sable.soot.jimple.DefinitionStmt
00509  */
00510 public void doDefinitionStmt(DefinitionStmt stmt) {
00511     stmt.getLeftOp().apply(lswitch);
00512     TypeStructure left = (TypeStructure) lswitch.getResult();
00513     stmt.getRightOp().apply(this);
00514     TypeStructure right = (TypeStructure) getResult();
00515     constraints.addAll(left.genEqualConstraints(right));
00516 }
00517 /**
00518  * Insert the method's description here.
00519  * Creation date: (8/18/00 9:13:47 AM)
00520  * @param v ca.mcgill.sable.soot.jimple.FieldRef
00521  */
00522 public void doFieldRef(FieldRef v) {
00523     TypeStructure fts = getTypeStructure(v.getField());
00524     TypeStructure ts = getTypeStructure(v);
00525     constraints.addAll(fts.genEqualConstraints(ts));
00526     setResult(ts);
00527 }
00528 /**
00529  * Insert the method's description here.
00530  * Creation date: (8/18/00 9:22:23 AM)
00531  * @param v ca.mcgill.sable.soot.jimple.InvokeExpr
00532  */
00533 public void doInvokeExpr(InvokeExpr v) {
00534     TypeStructure varnode;
00535     if (v.getMethod().getReturnType() instanceof RefType) {
00536         varnode = getTypeStructure(v);
00537     } else
00538         if (!(v.getMethod().getReturnType() instanceof VoidType)) {
00539             varnode = getTypeStructure(v);
00540         } else {
00541             varnode = null;
00542         }
00543     if (!Util.hasJavaPrefix(v.getMethod().getDeclaringClass().toString()) && !"Bandera".equals(v.getMethod().getDeclaringClass().toString())) {
00544         Vector p = new Vector();
00545         if (v instanceof NonStaticInvokeExpr) {
00546             ((NonStaticInvokeExpr) v).getBase().apply(this);
00547             p.add(getResult());
00548         } else {
00549             p.add(new Object());
00550         }
00551         for (int i = 0; i < v.getArgCount(); i++) {
00552             v.getArg(i).apply(this);
00553             p.add(getResult());
00554         }
00555         createConstraints(v.getMethod(), p, varnode);
00556     }
00557     setResult(varnode);
00558 }
00559 public void doOp(BinopExpr v) {
00560     v.getOp1().apply(this);
00561     TypeStructure left = (TypeStructure) getResult();
00562     v.getOp2().apply(this);
00563     TypeStructure right = (TypeStructure) getResult();
00564     TypeStructure ts = getTypeStructure(v);
00565     constraints.addAll(ts.genEqualConstraints(left));
00566     constraints.addAll(ts.genEqualConstraints(right));
00567     constraints.addAll(left.genEqualConstraints(right));
00568     setResult(ts);
00569 }
00570 /**
00571  * This method was created in VisualAge.
00572  * @param v ConditionalExpr
00573  */
00574 public void doTest(ConditionExpr v) {
00575     v.getOp1().apply(this);
00576     TypeStructure left = (TypeStructure) getResult();
00577     v.getOp2().apply(this);
00578     TypeStructure right = (TypeStructure) getResult();
00579     //Type t = edu.ksu.cis.bandera.abps.lib.BooleanAbstraction.v().getType();
00580     //tdg.addType(t);
00581     TypeStructure ts = getTypeStructure(v);
00582     //constraints.addAll(getTypeStructure(t).genEqualConstraints(ts));
00583     constraints.addAll(left.genEqualConstraints(right));
00584     if ((left instanceof BaseTypeStructure)
00585             && (right instanceof BaseTypeStructure)
00586             && (ts instanceof BaseTypeStructure)) {
00587         constraints.addAll(left.genEqualConstraints(ts));
00588         constraints.addAll(right.genEqualConstraints(ts));
00589     }
00590     setResult(ts);
00591 }
00592 /**
00593  * 
00594  * @return edu.ksu.cis.bandera.abstraction.Abstraction
00595  * @param t ca.mcgill.sable.soot.Type
00596  */
00597 public Abstraction getAbstraction(Type vType) {
00598     if (vType instanceof NullType) {
00599         return ClassAbstraction.v("java.lang.Object");
00600     } else if (vType instanceof ArrayType) {
00601         return ArrayAbstraction.v(getAbstraction(((ArrayType) vType).baseType), ConcreteIntegralAbstraction.v());
00602     } else if (vType instanceof RefType) {
00603         return ClassAbstraction.v(((RefType) vType).className);
00604     } else if ((vType instanceof FloatType) || (vType instanceof DoubleType)) {
00605         return ConcreteRealAbstraction.v();
00606     } else if (vType instanceof BaseType) {
00607         return ConcreteIntegralAbstraction.v();
00608     } else return null;
00609 }
00610 /**
00611  * Insert the method's description here.
00612  * Creation date: (8/17/00 9:13:15 PM)
00613  * @return edu.ksu.cis.bandera.abps.typing.TypeVariable
00614  * @param v ca.mcgill.sable.soot.jimple.Value
00615  */
00616 public TypeStructure getCoercedTypeStructure(Value v) {
00617     TypeStructure ats = getTypeStructure(v.getType());
00618     setAST(ats, "a(" + v + ")");
00619     return ats;
00620 }
00621 /**
00622  * Insert the method's description here.
00623  * Creation date: (8/17/00 9:13:15 PM)
00624  * @return edu.ksu.cis.bandera.abps.typing.TypeVariable
00625  * @param v ca.mcgill.sable.soot.jimple.Value
00626  */
00627 public TypeStructure getCoercedTypeStructure(SootField f) {
00628     TypeStructure ats = getTypeStructure(f.getType());
00629     setAST(ats, "a(" + f + ")");
00630     return ats;
00631 }
00632 /**
00633  * 
00634  * @return java.util.Hashtable
00635  */
00636 public java.util.Hashtable getErrors() {
00637     return errors;
00638 }
00639 /**
00640  * 
00641  * @return java.util.Hashtable
00642  */
00643 public java.util.Hashtable getInterfaceMethodMethod() {
00644     return interfaceMethodMethod;
00645 }
00646 /**
00647  * 
00648  * @return ca.mcgill.sable.soot.Type
00649  * @param ts edu.ksu.cis.bandera.abps.typing.TypeStructure
00650  */
00651 public Object getType(TypeStructure ts) {
00652     Object t;
00653     if (ts instanceof ObjectTypeStructure) {
00654         t = tdg.getType(((ObjectTypeStructure) ts).getVar());
00655     } else
00656         if (ts instanceof BaseTypeStructure) {
00657             t = tdg.getType(((BaseTypeStructure) ts).getVar());
00658         } else {
00659             Abstraction components = (Abstraction) getType(((ArrayTypeStructure) ts).getElements());
00660             IntegralAbstraction index = (IntegralAbstraction) getType(((ArrayTypeStructure) ts).getIndex());
00661             t = ArrayAbstraction.v(components, index);
00662         }
00663     return t;
00664 }
00665 /**
00666  * Insert the method's description here.
00667  * Creation date: (8/18/00 10:10:53 AM)
00668  * @return ca.mcgill.sable.soot.Type
00669  * @param f ca.mcgill.sable.soot.SootField
00670  */
00671 public Object getType(Object o) {
00672     if (o instanceof SootField) {
00673         return ((SootField) o).getType();
00674     } else
00675         if (o instanceof Value) {
00676             return ((Value) o).getType();
00677         } else
00678             System.out.println("Unknown type " + o);
00679     return null;
00680 }
00681 /**
00682  * Insert the method's description here.
00683  * Creation date: (8/17/00 9:13:15 PM)
00684  * @return edu.ksu.cis.bandera.abps.typing.TypeVariable
00685  * @param v ca.mcgill.sable.soot.jimple.Value
00686  */
00687 public TypeStructure getTypeStructure(Value v) {
00688     TypeStructure ats = (TypeStructure) ast2TypeStruct.get(v);
00689     if (ats == null) {
00690         ats = getTypeStructure(v.getType());
00691         ast2TypeStruct.put(v, ats);
00692         setAST(ats, v);
00693     }
00694     return ats;
00695 }
00696 /**
00697  * Insert the method's description here.
00698  * Creation date: (8/17/00 9:13:15 PM)
00699  * @return edu.ksu.cis.bandera.abps.typing.TypeVariable
00700  * @param v ca.mcgill.sable.soot.jimple.Value
00701  */
00702 public TypeStructure getTypeStructure(SootField f) {
00703     TypeStructure ats = (TypeStructure) ast2TypeStruct.get(f);
00704     if (ats == null) {
00705         ats = getTypeStructure(f.getType());
00706         ast2TypeStruct.put(f, ats);
00707         setAST(ats, f);
00708     }
00709     return ats;
00710 }
00711 /**
00712  * Insert the method's description here.
00713  * Creation date: (8/21/00 3:32:04 PM)
00714  * @return edu.ksu.cis.bandera.abps.typing.TypeStructure
00715  * @param t ca.mcgill.sable.soot.Type
00716  */
00717 public TypeStructure getTypeStructure(TypeVariable tv) {
00718     TypeStructure ats;
00719     if (tv.getType() instanceof ArrayType) {
00720         System.out.println("What am I doing here?");
00721         ats = null;
00722     } else
00723         if (tv.getType() instanceof RefType || tv.getType() instanceof NullType) {
00724             ats = new ObjectTypeStructure(tv);
00725             tdg.add(tv);
00726         } else
00727             if (tv.getType() instanceof ArrayAbstraction) {
00728                 ats = new ObjectTypeStructure(tv);
00729                 tdg.add(tv);
00730             } else {
00731                 ats = new BaseTypeStructure(tv);
00732                 tdg.add(tv);
00733             }
00734     return ats;
00735 }
00736 /**
00737  * Insert the method's description here.
00738  * Creation date: (8/21/00 3:32:04 PM)
00739  * @return edu.ksu.cis.bandera.abps.typing.TypeStructure
00740  * @param t ca.mcgill.sable.soot.Type
00741  */
00742 public TypeStructure getTypeStructure(Object t) {
00743     TypeStructure ats;
00744     if (t instanceof ArrayType) {
00745         ArrayType at = (ArrayType) t;
00746         TypeStructure index = getTypeStructure(ConcreteIntegralAbstraction.v());
00747         TypeStructure elements = getTypeStructure(at.baseType);
00748         ats = new ArrayTypeStructure(elements, index);
00749     } else
00750         if (t instanceof RefType || t instanceof NullType) {
00751             TypeVariable tv = new TypeVariable(t);
00752             ats = new ObjectTypeStructure(tv);
00753             tdg.add(tv);
00754         } else
00755             if (t instanceof ArrayAbstraction) {
00756                 TypeVariable tv = new TypeVariable(t);
00757                 ats = new ObjectTypeStructure(tv);
00758                 tdg.add(tv);
00759             } else {
00760                 TypeVariable tv = new TypeVariable(t);
00761                 ats = new BaseTypeStructure(tv);
00762                 tdg.add(tv);
00763             }
00764     return ats;
00765 }
00766 /**
00767  * Insert the method's description here.
00768  * Creation date: (8/22/00 3:53:25 PM)
00769  * @param ts edu.ksu.cis.bandera.abps.typing.TypeStructure
00770  * @param ast java.lang.Object
00771  */
00772 public void setAST(TypeStructure ts, Object ast) {
00773     if (ts instanceof BaseTypeStructure)
00774          ((BaseTypeStructure) ts).getVar().setAST(ast);
00775     else
00776         if (ts instanceof ObjectTypeStructure)
00777              ((ObjectTypeStructure) ts).getVar().setAST(ast);
00778         else {
00779             ArrayTypeStructure ats = (ArrayTypeStructure) ts;
00780             setAST(ats.getIndex(), ast);
00781             setAST(ats.getElements(), ast);
00782         }
00783 }
00784 /**
00785  * 
00786  * @param newErrors java.util.Hashtable
00787  */
00788 public void setErrors(java.util.Hashtable newErrors) {
00789     errors = newErrors;
00790 }
00791 public int solveCoercions() {
00792     System.out.println("\tRemoving Cycles.");
00793     tdg.removeCycles();
00794     System.out.println("\tGet Connected.");
00795     Set connected = tdg.getNotSingleConnected();
00796     System.out.println("Bubbling Data.");
00797     Iterator i = connected.iterator();
00798     while (i.hasNext()) {
00799         boolean types = false;
00800         Vector q = new Vector();
00801         Set vars = new HashSet();
00802         Set roots = (Set) i.next();
00803         q.addAll(roots);
00804         TypeVariable o;
00805         while (q.size() > 0 && !types) {
00806             o = (TypeVariable) q.remove(0);
00807             if (!vars.contains(o)) {
00808                 vars.add(o);
00809                 if (tdg.getType(o) != null) {
00810                     types = true;
00811                 } else
00812                     q.addAll(tdg.getChildren(o));
00813             }
00814         }
00815         if (!types) {
00816             if (vars.size() > 0) {
00817                 Object vType = ((TypeVariable) vars.toArray()[0]).getType();
00818                 if (vType instanceof RefType) {
00819                     Object t = ClassAbstraction.v(((RefType) vType).className);
00820                     tdg.addType(t);
00821                     Vector v = new Vector(vars);
00822                     while (v.size() > 0)
00823                         tdg.combine(tdg.getTypeVariable(t), (TypeVariable) v.remove(0));
00824                 } else
00825                     if (vType instanceof NullType) {
00826                         tdg.addType(vType);
00827                         Vector v = new Vector(vars);
00828                         while (v.size() > 0)
00829                             tdg.combine(tdg.getTypeVariable(vType), (TypeVariable) v.remove(0));
00830                     } else
00831                         if ((vType instanceof FloatType) || (vType instanceof DoubleType)) {
00832                             Object t = ConcreteRealAbstraction.v();
00833                             tdg.addType(t);
00834                             Vector v = new Vector(vars);
00835                             while (v.size() > 0)
00836                                 tdg.combine(tdg.getTypeVariable(t), (TypeVariable) v.remove(0));
00837                         } else
00838                             if (vType instanceof BaseType) {
00839                                 Object t = ConcreteIntegralAbstraction.v();
00840                                 tdg.addType(t);
00841                                 Vector v = new Vector(vars);
00842                                 while (v.size() > 0)
00843                                     tdg.combine(tdg.getTypeVariable(t), (TypeVariable) v.remove(0));
00844                             } else {
00845                                 tdg.addType(vType);
00846                                 Vector v = new Vector(vars);
00847                                 while (v.size() > 0)
00848                                     tdg.combine(tdg.getTypeVariable(vType), (TypeVariable) v.remove(0));
00849                             }
00850             }
00851         } else {
00852             Set children;
00853             Iterator j;
00854             Vector v;
00855             Object t, t2;
00856             Vector list = new Vector(roots);
00857             Stack s = new Stack();
00858             Stack c = new Stack();
00859             while (list.size() > 0) {
00860                 o = (TypeVariable) list.remove(0);
00861                 s.push(o);
00862                 c.push(new Vector(tdg.getChildren(o)));
00863                 while (!s.empty()) {
00864                     o = (TypeVariable) s.peek();
00865                     v = (Vector) c.peek();
00866                     if (tdg.isLeaf(o)) {
00867                         t = tdg.getType(o);
00868                         if (t == null) {
00869                             t = o.getType();
00870                             if ((t instanceof FloatType) || (t instanceof DoubleType)) {
00871                                 t = ConcreteRealAbstraction.v();
00872                                 tdg.addType(t);
00873                                 tdg.combine(tdg.getTypeVariable(t), (TypeVariable) o);
00874                             } else
00875                                 if (t instanceof BaseType) {
00876                                     t = ConcreteIntegralAbstraction.v();
00877                                     tdg.addType(t);
00878                                     tdg.combine(tdg.getTypeVariable(t), (TypeVariable) o);
00879                                 } else
00880                                     if (t instanceof RefType) {
00881                                         t = ClassAbstraction.v(((RefType) t).className);
00882                                         tdg.addType(t);
00883                                         tdg.combine(tdg.getTypeVariable(t), (TypeVariable) o);
00884                                     } else
00885                                         if (t instanceof ArrayType) {
00886                                             System.out.println("What to do in arrays.");
00887                                         } else {
00888                                             System.out.println("I shouldn't be printing this.");
00889                                         }
00890                         }
00891                         s.pop();
00892                         c.pop();
00893                     } else
00894                         if (v.size() > 0) {
00895                             o = (TypeVariable) v.remove(0);
00896                             s.push(o);
00897                             c.push(new Vector(tdg.getChildren(o)));
00898                         } else {
00899                             // No more
00900                             s.pop();
00901                             c.pop();
00902                             children = new HashSet();
00903                             j = tdg.getChildren(o).iterator();
00904                             while (j.hasNext()) {
00905                                 t = tdg.getType((TypeVariable) j.next());
00906                                 if (t == null)
00907                                     System.out.println("Error:  No type here.");
00908                                 else
00909                                     children.add(t);
00910                             }
00911                             t = tdg.getType(o);
00912                             t2 = coercionManager.lub(children);
00913                             if (t2 == null) {
00914                                 System.out.println("Error lub for " + children + "\n\tt=" + t);
00915                                 System.out.println("\t" + o + "\t" + tdg.getChildren(o));
00916                             } else
00917                                 if (t == null) {
00918                                     tdg.addType(t2);
00919                                     tdg.combine(tdg.getTypeVariable(t2), (TypeVariable) o);
00920                                 } else
00921                                     if (!coercionManager.coerciable((Abstraction) t2, (Abstraction) t)) {
00922                                         System.out.println("Trying to coerce " + t2 + " to " + t + " which I say is impossible.");
00923                                         conflicts.add(t2 + " to " + t);
00924                                     }
00925                         }
00926                 }
00927             }
00928         }
00929     }
00930     return 0;
00931 }
00932 public void solveConstraints() {
00933     List con = new Vector();
00934     Constraint c;
00935     for (Iterator i = constraints.iterator(); i.hasNext();) {
00936         c = (Constraint) i.next();
00937         if (c instanceof EqualConstraint) {
00938             EqualConstraint e = (EqualConstraint) c;
00939             TypeVariable l = e.getLeft();
00940             TypeVariable r = e.getRight();
00941             tdg.quickCombine(l, r);
00942         } else {
00943             con.add(c);
00944         }
00945     }
00946     for (Iterator i = con.iterator(); i.hasNext();) {
00947         c = (Constraint) i.next();
00948         if (c instanceof CoerceConstraint) {
00949             CoerceConstraint a = (CoerceConstraint) c;
00950             TypeVariable l = a.getLeft();
00951             TypeVariable r = a.getRight();
00952             tdg.addChild(l, r);
00953         } else {
00954             System.out.println("Warning: *** unknown constraint in TypeInference.solveConstraints() ***");
00955         }
00956     }
00957     constraints = con;
00958 }
00959 /**
00960  * This method was created in VisualAge.
00961  * @return boolean
00962  * @param options Options
00963  */
00964 public TypeTable type(SootClassManager scm, Hashtable options) {
00965     for (Enumeration e = options.keys(); e.hasMoreElements();) {
00966         Object o = e.nextElement();
00967         if (o instanceof SootField) {
00968             SootField sf = (SootField) o;
00969             TypeStructure n = getTypeStructure(sf);
00970             TypeVariable tv = tdg.addType(options.get(sf));
00971             constraints.addAll(n.genEqualConstraints(getTypeStructure(tv)));
00972         }
00973     }
00974     for (Enumeration e = options.keys(); e.hasMoreElements();) {
00975         Object o = e.nextElement();
00976         if (o instanceof LocalMethod) {
00977             LocalMethod lm = (LocalMethod) o;
00978             TypeStructure n = getTypeStructure(lm.getLocal());
00979             Object t = options.get(new LocalMethod(lm.getMethod(), lm.getLocal()));
00980             TypeVariable tv = tdg.addType(t);
00981             constraints.addAll(n.genEqualConstraints(getTypeStructure(tv)));
00982         }
00983     }
00984     for (Enumeration e = options.keys(); e.hasMoreElements();) {
00985         Object o = e.nextElement();
00986         if (o instanceof SootClass) {
00987             SootClass sc = (SootClass) o;
00988             for (ca.mcgill.sable.util.Iterator i = sc.getMethods().iterator(); i.hasNext();) {
00989                 SootMethod sm = (SootMethod) i.next();
00990                 createInheritanceConstraints(sm);
00991             }
00992         }
00993     }
00994     for (Enumeration e = options.keys(); e.hasMoreElements();) {
00995         Object o = e.nextElement();
00996         if (o instanceof SootClass) {
00997             SootClass sc = (SootClass) o;
00998             for (ca.mcgill.sable.util.Iterator i = sc.getMethods().iterator(); i.hasNext();) {
00999                 SootMethod sm = (SootMethod) i.next();
01000                 Vector p = new Vector();
01001                 if (sm.isStatic()) {
01002                     p.add(new Object());
01003                 } else {
01004                     Object t = ClassAbstraction.v(sm.getDeclaringClass().getName());
01005                     TypeStructure v = getTypeStructure(t);
01006                     tdg.addType(t);
01007                     p.add(v);
01008                 }
01009                 for (ca.mcgill.sable.util.Iterator j = sm.getParameterTypes().iterator(); j.hasNext();) {
01010                     p.add(getTypeStructure(j.next()));
01011                 }
01012                 createConstraints(sm, p, getTypeStructure(sm.getReturnType()));
01013             }
01014         }
01015     }
01016     //status();
01017     System.out.println("Solving Constraints.");
01018     solveConstraints();
01019     System.out.println("Solving Coercions.");
01020     solveCoercions();
01021     //status();
01022     System.out.println("Assign Types.");
01023     List unknowns = new Vector();
01024     Iterator i = ast2TypeStruct.keySet().iterator();
01025     Object t;
01026     Object n;
01027     TypeStructure tv;
01028     while (i.hasNext()) {
01029         n = i.next();
01030         tv = (TypeStructure) ast2TypeStruct.get(n);
01031         t = getType(tv);
01032         if (t == null) {
01033             Type vType = n instanceof Value? ((Value) n).getType() : ((SootField) n).getType();
01034             Abstraction a = getAbstraction(vType);
01035             if (a != null)
01036                 nodes.put(n, a);
01037             else
01038                 unknowns.add(n);
01039             /*
01040             if (tv instanceof ArrayTypeStructure) {
01041                 ArrayTypeStructure atv = (ArrayTypeStructure) tv;
01042                 Object index = tdg.getType(((BaseTypeStructure) atv.getIndex()).getVar());
01043                 Object components = null;
01044                 if (atv.getElements() instanceof BaseTypeStructure)
01045                     components = tdg.getType(((BaseTypeStructure) atv.getIndex()).getVar());
01046                 else
01047                     if (atv.getElements() instanceof ObjectTypeStructure)
01048                         components = tdg.getType(((ObjectTypeStructure) atv.getIndex()).getVar());
01049                     else
01050                         System.out.println("Don't handle Array Structs here yet.  Can you help me.  Search for 12345654321 in the code.");
01051                 if (index == null || components == null) {
01052                     unknowns.add(n);
01053                 } else {
01054                     ArrayAbstraction aat = ArrayAbstraction.v((Abstraction) components, (IntegralAbstraction) index);
01055                     nodes.put(n, aat);
01056                 }
01057             } else {
01058                 unknowns.add(n);
01059             }
01060             */
01061         } else {
01062             if (t instanceof ArrayAbstraction) {
01063                 ArrayType vType = (ArrayType) (n instanceof Value? ((Value) n).getType() : ((SootField) n).getType());
01064                 ArrayAbstraction aa = (ArrayAbstraction) t;
01065                 IntegralAbstraction indexAbstraction = aa.getIndexAbstraction();
01066                 if (indexAbstraction == null) indexAbstraction = ConcreteIntegralAbstraction.v();
01067                 Abstraction elementAbstraction = aa.getElementAbstraction();
01068                 if (elementAbstraction == null) elementAbstraction = getAbstraction(vType.baseType);
01069                 t = ArrayAbstraction.v(elementAbstraction, indexAbstraction);
01070             }
01071             nodes.put(n, t);
01072         }
01073     }
01074     //status();
01075     //System.out.println(unknowns);
01076 
01077     if (unknowns.size() != 0) {
01078         errors.put("Unknowns", unknowns);
01079     }
01080     if (conflicts.size() != 0) {
01081         errors.put("Conflicts", conflicts);
01082     }
01083     //Iterator it = unknowns.iterator();
01084     //while (it.hasNext())
01085     //System.out.println(ufs.find(it.next()));
01086     //System.out.println(nodes);
01087     return nodes;
01088 }
01089 }

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