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

JIJCCodeGenerator.java

00001 package edu.ksu.cis.bandera.jjjc.codegenerator;
00002 
00003 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00004  * Bandera, a Java(TM) analysis and transformation toolkit           *
00005  * Copyright (C) 1999, 2000   Robby (robby@cis.ksu.edu)              *
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.jjjc.decompiler.*;
00036 import edu.ksu.cis.bandera.jext.*;
00037 import edu.ksu.cis.bandera.specification.datastructure.*;
00038 import java.util.*;
00039 import java.math.*;
00040 import edu.ksu.cis.bandera.annotation.*;
00041 import edu.ksu.cis.bandera.jjjc.analysis.*;
00042 import edu.ksu.cis.bandera.jjjc.node.*;
00043 import edu.ksu.cis.bandera.jjjc.optimizer.*;
00044 import edu.ksu.cis.bandera.jjjc.symboltable.*;
00045 import edu.ksu.cis.bandera.jjjc.symboltable.Package;
00046 import edu.ksu.cis.bandera.jjjc.exception.*;
00047 import edu.ksu.cis.bandera.jjjc.util.*;
00048 import edu.ksu.cis.bandera.jjjc.*;
00049 import edu.ksu.cis.bandera.jjjc.doc.*;
00050 import ca.mcgill.sable.util.*;
00051 import ca.mcgill.sable.soot.*;
00052 import ca.mcgill.sable.soot.jimple.*;
00053 import ca.mcgill.sable.util.List;
00054 import ca.mcgill.sable.util.LinkedList;
00055 import ca.mcgill.sable.util.Iterator;
00056 import edu.ksu.cis.bandera.specification.assertion.*;
00057 import edu.ksu.cis.bandera.specification.predicate.*;
00058 
00059 public class JIJCCodeGenerator extends DepthFirstAdapter {
00060     private SootClassManager scm = null;
00061     private AnnotationManager am = null;
00062     private Hashtable docComments = null;
00063     private Vector exceptions = new Vector();
00064     private SymbolTable symbolTable = null;
00065     private Jimple jimple = Jimple.v();
00066     private SootClass currentSootClass = null;
00067     private SootMethod currentSootMethod = null;
00068     private ClassOrInterfaceType currentClassOrInterfaceType = null;
00069     private Vector compiledClasses = new Vector();
00070     private edu.ksu.cis.bandera.jjjc.symboltable.Type integralConstantType = null;
00071     private boolean assignExp = false;
00072     private boolean isInterface = false;
00073 
00074   // annotations
00075   private Vector synchAnnotations = new Vector();
00076   private BlockStmtAnnotation currentAnnotation = null;
00077   private LocalDeclarationStmtAnnotation localAnnotation = null;
00078   private Node fieldNode = null;
00079 
00080     // boolean exp
00081     public Stmt trueBranch = null;
00082     public Stmt falseBranch = null;
00083 
00084     // new for each method & constructor body
00085     private NameGenerator nameGen = null;
00086     private NameGenerator qtNameGen = null; //This line is robbyjo's patch
00087     private Hashtable currentLocals = null;
00088     private Hashtable currentLocalNames = null;
00089     private Hashtable currentLocalNamesIterator = null;
00090     private Vector currentStmts = null;
00091     private Value currentValue = null;
00092     private ca.mcgill.sable.soot.Type currentType = null;
00093     private Local currentThisLocal = null;
00094     private JimpleBody currentBody = null;
00095     private String currentName = null;
00096     private Vector currentTraps = null;
00097 
00098     // initializers
00099     private Hashtable staticLocals = null;
00100     private Vector staticStmts = null;
00101     private Hashtable instanceLocals = null;
00102     private Vector instanceStmts = null;
00103     private SootMethod clinit = null;
00104     private JimpleBody clinitBody = null;
00105     private SootMethod init = null;
00106     private JimpleBody initBody = null;
00107     private int staticInitializers = 0;
00108     private int instanceInitializers = 0;
00109 
00110     // switch
00111     private LinkedList currentLookupValues = null;
00112     private LinkedList currentTargets = null;
00113     private Stmt currentDefaultStmt = null;
00114     private boolean defaultSwitch = false;
00115 
00116     // try catch /finally
00117     private TryStmtAnnotation currentTryAnnotation = null;
00118     private Stmt beginTrapStmt = null;
00119     private Stmt endTrapStmt = null;
00120     private Stmt endTryStmt = null;
00121     private boolean catchHasEnd;
00122 
00123     // label
00124     private LinkedList labels = null;
00125     private Hashtable currentLabels = null;
00126     private Stmt currentBreakTarget = null;
00127     private Stmt currentContinueTarget = null;
00128 
00129     // for
00130     private Hashtable forLocals = null;
00131     private ca.mcgill.sable.soot.Type forInitType = null;
00132     private int forInitModifiers = 0;
00133 
00134     // break/continue
00135     private Vector finallyAndSynch = new Vector();
00136     private Object lastFinallySynchBeforeControl = null;
00137 
00138     private ca.mcgill.sable.soot.SootMethod assertMethod;
00139     private ca.mcgill.sable.soot.SootMethod chooseMethod;
00140 
00141     private int methodLine;
00142 /**
00143  * 
00144  * @param symbolTable edu.ksu.cis.bandera.jjjc.symboltable.SymbolTable
00145  * @param sootClassManager ca.mcgill.sable.soot.SootClassManager
00146  * @param docComments java.util.Hashtable
00147  */
00148 public JIJCCodeGenerator(SymbolTable symbolTable, SootClassManager sootClassManager,
00149         AnnotationManager annotationManager, Hashtable docComments) {
00150     this.symbolTable = symbolTable;
00151     this.scm = sootClassManager;
00152     this.am = annotationManager;
00153     this.docComments = docComments;
00154 
00155     symbolTable.setCurrentPackage(null);
00156     symbolTable.setCurrentClassOrInterfaceType(null);
00157     while (symbolTable.getNumScopeLevels() > 0) {
00158         symbolTable.exitScope();
00159     }
00160     if (!scm.managesClass("Bandera")) {
00161         SootClass sc = new SootClass("Bandera", Modifier.PUBLIC);
00162         
00163         LinkedList parms = new LinkedList();
00164         chooseMethod = new SootMethod("choose", parms, ca.mcgill.sable.soot.BooleanType.v(),
00165                 Modifier.PUBLIC | Modifier.STATIC);
00166 
00167         sc.addMethod(chooseMethod);
00168 
00169         parms = new LinkedList();
00170         parms.addLast(ca.mcgill.sable.soot.BooleanType.v());
00171         assertMethod = new SootMethod("assert", parms, ca.mcgill.sable.soot.VoidType.v(),
00172                 Modifier.PUBLIC | Modifier.STATIC);
00173 
00174         sc.addMethod(assertMethod);
00175 
00176         scm.addClass(sc);
00177     } else {
00178         SootClass sc = scm.getClass("Bandera");
00179         chooseMethod = sc.getMethod("choose");
00180         assertMethod = sc.getMethod("assert");
00181     }
00182 }
00183 /**
00184  * 
00185  * @param annotation edu.ksu.cis.bandera.annotation.Annotation
00186  * @param body ca.mcgill.sable.soot.jimple.JimpleBody
00187  */
00188 private void addRetIfNecessary(JimpleBody body, ca.mcgill.sable.soot.Type retType) {
00189     if (body.declaresLocal("$ret")) return;
00190 
00191     Local ret = jimple.newLocal("$ret", retType);
00192     body.addLocal(ret);
00193 
00194     Object[] stmts = body.getStmtList().toArray();
00195     for (int i = 0; i < stmts.length; i++) {
00196         if (stmts[i] instanceof ReturnStmt) {
00197             ReturnStmt rs = (ReturnStmt) stmts[i];
00198             Local lcl = (Local) rs.getReturnValue();
00199             for (int j = i - 1; j >= 0; j--) {
00200                 if (stmts[j] instanceof AssignStmt) {
00201                     AssignStmt as = (AssignStmt) stmts[j];
00202                     if (as.getLeftOp() == lcl) {
00203                         as.setLeftOp(ret);
00204                         break;
00205                     }
00206                 }
00207             }
00208             rs.setReturnValue(ret);
00209         }
00210     }
00211     return;
00212 }
00213 /**
00214  * 
00215  * @param node edu.ksu.cis.bandera.jjjc.node.AAbstractMethodDeclarationInterfaceMemberDeclaration
00216  */
00217 public void caseAAbstractMethodDeclarationInterfaceMemberDeclaration(AAbstractMethodDeclarationInterfaceMemberDeclaration node) {
00218     currentSootMethod = null;
00219     currentAnnotation = new MethodDeclarationAnnotation(node);
00220     LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
00221     currentAnnotation.setFirstLine(lc.getFirstLine());
00222     currentAnnotation.setFirstColumn(lc.getFirstColumn());
00223     currentAnnotation.setLastLine(lc.getLastLine());
00224     currentAnnotation.setLastColumn(lc.getLastColumn());
00225 
00226     isInterface = true;
00227     node.getMethodHeader().apply(this);
00228     isInterface = false;
00229 
00230     am.addAnnotation(currentSootClass, currentSootMethod, currentAnnotation);
00231     currentAnnotation = null;
00232 }
00233 /**
00234  * 
00235  * @param node edu.ksu.cis.bandera.jjjc.node.AArrayInitializer
00236  */
00237 public void caseAArrayInitializer(AArrayInitializer node) {
00238     Object temp[] = node.getVariableInitializer().toArray();
00239     
00240     Value leftValue = currentValue;
00241     
00242     if (!(leftValue instanceof Local)) {
00243         Local lcl = declareLocal(nameGen.newName(), leftValue.getType(), 0);
00244         currentStmts.addElement(jimple.newAssignStmt(lcl, leftValue));
00245         leftValue = lcl;
00246     }
00247     
00248     ca.mcgill.sable.soot.ArrayType type = (ca.mcgill.sable.soot.ArrayType) leftValue.getType();
00249     Value v = jimple.newNewArrayExpr(ca.mcgill.sable.soot.ArrayType.v(type.baseType, type.numDimensions - 1),
00250             IntConstant.v(temp.length));
00251     
00252     currentStmts.addElement(jimple.newAssignStmt(leftValue, v));
00253     
00254     for (int i = 0; i < temp.length; i++) {
00255         if (temp[i] instanceof AArrayVariableInitializer) {
00256             currentValue = declareLocal(nameGen.newName(), ca.mcgill.sable.soot.ArrayType.v(type.baseType, type.numDimensions - 1), 0);
00257         }
00258         ((PVariableInitializer) temp[i]).apply(this);
00259         currentStmts.addElement(jimple.newAssignStmt(jimple.newArrayRef(leftValue, IntConstant.v(i)), currentValue));
00260     }
00261     currentValue = leftValue;
00262 }
00263 /**
00264  * 
00265  * @param node edu.ksu.cis.bandera.jjjc.node.AAssignedVariableDeclarator
00266  */
00267 public void caseAAssignedVariableDeclarator(AAssignedVariableDeclarator node) {
00268     node.getVariableDeclaratorId().apply(this);
00269     if (currentType instanceof ca.mcgill.sable.soot.BooleanType) {
00270         if (symbolTable.getNumScopeLevels() > 0) {
00271             Local lcl = declareLocal(currentName, currentType, 0);
00272             if (currentAnnotation == null) {
00273                 forLocals.put(currentName, lcl);
00274             } else {
00275                 localAnnotation.addDeclaredLocal(currentName, lcl);
00276             }
00277             currentValue = lcl;
00278             Stmt endStmt = jimple.newNopStmt();
00279             Stmt prevTrueBranch = trueBranch;
00280             Stmt prevFalseBranch = falseBranch;
00281             trueBranch = jimple.newAssignStmt(lcl, IntConstant.v(1));
00282             falseBranch = jimple.newAssignStmt(lcl, IntConstant.v(0));
00283             Node n = (Node) node.getVariableInitializer().clone();
00284             PushComplement.push(n);
00285             n.apply(new BooleanExpression(this, trueBranch, falseBranch));
00286             currentStmts.addElement(falseBranch);
00287             currentStmts.addElement(jimple.newGotoStmt(endStmt));
00288             currentStmts.addElement(trueBranch);
00289             currentStmts.addElement(endStmt);
00290             trueBranch = prevTrueBranch;
00291             falseBranch = prevFalseBranch;
00292         } else {
00293             int start = currentStmts.size();
00294             String fieldName = currentName;
00295             nameFieldOrLocalExp(true, currentName);
00296             Value field = currentValue;
00297             Stmt endStmt = jimple.newNopStmt();
00298             Stmt prevTrueBranch = trueBranch;
00299             Stmt prevFalseBranch = falseBranch;
00300             trueBranch = jimple.newAssignStmt(field, IntConstant.v(1));
00301             falseBranch = jimple.newAssignStmt(field, IntConstant.v(0));
00302             Node n = (Node) node.getVariableInitializer().clone();
00303             PushComplement.push(n);
00304             n.apply(new BooleanExpression(this, trueBranch, falseBranch));
00305             currentStmts.addElement(falseBranch);
00306             currentStmts.addElement(jimple.newGotoStmt(endStmt));
00307             currentStmts.addElement(trueBranch);
00308             currentStmts.addElement(endStmt);
00309             trueBranch = prevTrueBranch;
00310             falseBranch = prevFalseBranch;
00311             
00312             int end = currentStmts.size();
00313             FieldDeclarationAnnotation ann = new FieldDeclarationAnnotation(fieldNode);
00314             LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
00315             ann.setFirstLine(lc.getFirstLine());
00316             ann.setFirstColumn(lc.getFirstColumn());
00317             ann.setLastLine(lc.getLastLine());
00318             ann.setLastColumn(lc.getLastColumn());
00319     
00320             for (int i = start; i < end; i++) {
00321                 ann.addStmt((Stmt) currentStmts.elementAt(i));
00322             }
00323 
00324             try {
00325                 SootField sf = getSootField(currentSootClass.getName(), fieldName);
00326                 am.addAnnotation(currentSootClass, sf, ann);
00327                 ann.setSootField(sf);
00328                 ann.setField(currentClassOrInterfaceType.getField(new Name(fieldName)));
00329                 am.putFilenameLinePairAnnotation(
00330                         new FilenameLinePair(currentClassOrInterfaceType.getPath(),
00331                             LineExtractor.extractLine(node.getVariableDeclaratorId())),
00332                         ann);
00333             } catch (CompilerException e) {}
00334         }
00335     } else {
00336         if (symbolTable.getNumScopeLevels() > 0) {
00337             Local lcl = declareLocal(currentName, currentType, 0);
00338             if (currentAnnotation == null) {
00339                 forLocals.put(currentName, lcl);
00340             } else {
00341                 localAnnotation.addDeclaredLocal(currentName, lcl);
00342             }
00343             currentValue = lcl;
00344             node.getVariableInitializer().apply(this);
00345             currentStmts.addElement(jimple.newAssignStmt(lcl, currentValue));
00346         } else {
00347             int start = currentStmts.size();
00348 
00349             String fieldName = currentName;
00350             
00351             nameFieldOrLocalExp(true, currentName);
00352             Value field = currentValue;
00353             node.getVariableInitializer().apply(this);
00354             currentStmts.addElement(jimple.newAssignStmt(field, currentValue));
00355             
00356             int end = currentStmts.size();
00357             FieldDeclarationAnnotation ann = new FieldDeclarationAnnotation(fieldNode);
00358     
00359             for (int i = start; i < end; i++) {
00360                 ann.addStmt((Stmt) currentStmts.elementAt(i));
00361             }
00362             
00363             try {
00364                 SootField sf = getSootField(currentSootClass.getName(), fieldName);
00365                 am.addAnnotation(currentSootClass, sf, ann);
00366                 ann.setSootField(sf);
00367                 ann.setField(currentClassOrInterfaceType.getField(new Name(fieldName)));
00368                 am.putFilenameLinePairAnnotation(
00369                         new FilenameLinePair(currentClassOrInterfaceType.getPath(),
00370                             LineExtractor.extractLine(node.getVariableDeclaratorId())),
00371                         ann);
00372             } catch (CompilerException e) {}
00373         }
00374     }
00375 }
00376 /**
00377  * 
00378  * @param node edu.ksu.cis.bandera.jjjc.node.AAssignmentExp
00379  */
00380 public void caseAAssignmentExp(AAssignmentExp node) {
00381     String operator = node.getAssignmentOperator().toString().trim();
00382     node.getLeftHandSide().apply(this);
00383     Value firstValue = currentValue;
00384 
00385     if ((firstValue instanceof ca.mcgill.sable.soot.BooleanType) && "=".equals(operator)) {
00386         Stmt endStmt = jimple.newNopStmt();
00387         Stmt prevTrueBranch = trueBranch;
00388         Stmt prevFalseBranch = falseBranch;
00389         trueBranch = jimple.newAssignStmt(firstValue, IntConstant.v(1));
00390         falseBranch = jimple.newAssignStmt(firstValue, IntConstant.v(0));
00391         Node n = (Node) node.getExp().clone();
00392         PushComplement.push(n);
00393         if (node.getExp() instanceof AUnaryExp)
00394             if ("!".equals(((AUnaryExp) node.getExp()).getUnaryOperator().toString().trim()))
00395                 n = ((AUnaryExp) n).getExp();
00396         n.apply(new BooleanExpression(this, trueBranch, falseBranch));
00397         currentStmts.addElement(falseBranch);
00398         currentStmts.addElement(jimple.newGotoStmt(endStmt));
00399         currentStmts.addElement(trueBranch);
00400         currentStmts.addElement(endStmt);
00401         currentValue = firstValue;
00402         trueBranch = prevTrueBranch;
00403         falseBranch = prevFalseBranch;
00404         if (!(currentValue instanceof Local) || !(currentValue instanceof Constant)) {
00405             Local lcl = declareLocal(nameGen.newName(), currentValue.getType(), 0);
00406             currentStmts.addElement(jimple.newAssignStmt(lcl, currentValue));
00407             currentValue = lcl;
00408         }
00409         return;
00410     }
00411         
00412     node.getExp().apply(this);
00413     Value secondValue = currentValue;
00414     currentValue = null;
00415     if ("=".equals(operator)) {
00416         currentStmts.addElement(jimple.newAssignStmt(firstValue, secondValue));
00417         currentValue = firstValue;
00418         if (!(currentValue instanceof Local) || !(currentValue instanceof Constant)) {
00419             Local lcl = declareLocal(nameGen.newName(), currentValue.getType(), 0);
00420             currentStmts.addElement(jimple.newAssignStmt(lcl, currentValue));
00421             currentValue = lcl;
00422         }
00423     } else {
00424         operator = operator.substring(0, operator.length() - 1);
00425         Value resultValue = firstValue;
00426         if (!(firstValue instanceof Local)) {
00427             Local lcl = declareLocal(nameGen.newName(), firstValue.getType(), 0);
00428             currentStmts.addElement(jimple.newAssignStmt(lcl, firstValue));
00429             firstValue = lcl;
00430         }
00431         try {
00432             numericOperation(operator, firstValue, secondValue);
00433             if (currentValue == null) {
00434                 exceptions.addElement(new CompilerException("Cannot resolve " + node.getLeftHandSide().toString()));
00435                 return;
00436             }
00437             currentStmts.addElement(jimple.newAssignStmt(resultValue, currentValue));
00438             currentValue = resultValue;
00439             if (!(currentValue instanceof Local) || !(currentValue instanceof Constant)) {
00440                 Local lcl = declareLocal(nameGen.newName(), currentValue.getType(), 0);
00441                 currentStmts.addElement(jimple.newAssignStmt(lcl, currentValue));
00442                 currentValue = lcl;
00443             }
00444         } catch (CompilerException e) {
00445             exceptions.addElement(e);
00446         }
00447     }
00448 }
00449 /**
00450  * 
00451  * @param node edu.ksu.cis.bandera.jjjc.node.ABinaryExp
00452  */
00453 public void caseABinaryExp(ABinaryExp node) {
00454     node = (ABinaryExp) node.clone();
00455     TrivialExpression.optimize(node);
00456     
00457     PBinaryOperator op = node.getBinaryOperator();
00458     Stmt prevTrueBranch = trueBranch;
00459     Stmt prevFalseBranch = falseBranch;
00460 
00461     if ((op instanceof AOrBinaryOperator) || (op instanceof AAndBinaryOperator)) {
00462         Local lcl = null;
00463         if (trueBranch == null) {
00464             lcl = declareLocal(nameGen.newName(), ca.mcgill.sable.soot.BooleanType.v(), 0);
00465             trueBranch = jimple.newAssignStmt(lcl, IntConstant.v(1));
00466             falseBranch = jimple.newAssignStmt(lcl, IntConstant.v(0));
00467         }
00468 
00469         Node n = (Node) node.clone();
00470         PushComplement.push(n);
00471         n.apply(new BooleanExpression(this, trueBranch, falseBranch));
00472 
00473         if (lcl != null) {
00474             Stmt endStmt = jimple.newNopStmt();
00475             currentStmts.addElement(falseBranch);
00476             currentStmts.addElement(jimple.newGotoStmt(endStmt));
00477             currentStmts.addElement(trueBranch);
00478             currentStmts.addElement(endStmt);
00479             trueBranch = prevTrueBranch;
00480             falseBranch = prevFalseBranch;
00481             currentValue = lcl;
00482         }
00483         return;
00484     } 
00485         
00486     node.getFirst().apply(this);
00487     Value firstValue = currentValue;
00488     if (!(firstValue instanceof Local) && !(firstValue instanceof Constant)) {
00489         Local lcl = declareLocal(nameGen.newName(), firstValue.getType(), 0);
00490         currentStmts.addElement(jimple.newAssignStmt(lcl, firstValue));
00491         firstValue = lcl;
00492     }
00493     node.getSecond().apply(this);
00494     Value secondValue = currentValue;
00495     currentValue = null;
00496     if (!(secondValue instanceof Local) && !(secondValue instanceof Constant)) {
00497         Local lcl = declareLocal(nameGen.newName(), secondValue.getType(), 0);
00498         currentStmts.addElement(jimple.newAssignStmt(lcl, secondValue));
00499         secondValue = lcl;
00500     }
00501 
00502     if (op instanceof AGtBinaryOperator || op instanceof ALtBinaryOperator || op instanceof ALteqBinaryOperator || op instanceof AGteqBinaryOperator || op instanceof AEqBinaryOperator || op instanceof ANeqBinaryOperator) {
00503         // >  <  <=  >=  == !=
00504         Local lcl = null;
00505         if (trueBranch == null) {
00506             lcl = declareLocal(nameGen.newName(), ca.mcgill.sable.soot.BooleanType.v(), 0);
00507             trueBranch = jimple.newAssignStmt(lcl, IntConstant.v(1));
00508             falseBranch = jimple.newAssignStmt(lcl, IntConstant.v(0));
00509         }
00510 
00511         if ((firstValue.getType() instanceof ca.mcgill.sable.soot.DoubleType)
00512                 || (secondValue.getType() instanceof ca.mcgill.sable.soot.DoubleType)
00513                 || (firstValue.getType() instanceof ca.mcgill.sable.soot.FloatType)
00514                 || (secondValue.getType() instanceof ca.mcgill.sable.soot.FloatType)) {
00515             if (op instanceof AGtBinaryOperator) {
00516                 currentValue = jimple.newCmpgExpr(firstValue, secondValue);
00517             } else if (op instanceof ALtBinaryOperator) {
00518                 currentValue = jimple.newCmplExpr(firstValue, secondValue);
00519             } else if (op instanceof ALteqBinaryOperator) {
00520                 currentValue = jimple.newCmplExpr(firstValue, secondValue);
00521             } else if (op instanceof AGteqBinaryOperator) {
00522                 currentValue = jimple.newCmpgExpr(firstValue, secondValue);
00523             } else if (op instanceof AEqBinaryOperator) {
00524                 currentValue = jimple.newCmplExpr(firstValue, secondValue);
00525             } else if (op instanceof ANeqBinaryOperator) {
00526                 currentValue = jimple.newCmplExpr(firstValue, secondValue);
00527             }
00528             Local local = declareLocal(nameGen.newName(), ca.mcgill.sable.soot.IntType.v(), 0);
00529             currentStmts.addElement(jimple.newAssignStmt(local, currentValue));
00530             firstValue = local;
00531             secondValue = IntConstant.v(0);
00532         }
00533                 
00534         if (op instanceof AGtBinaryOperator) {
00535             currentValue = jimple.newGtExpr(firstValue, secondValue);
00536         } else if (op instanceof ALtBinaryOperator) {
00537             currentValue = jimple.newLtExpr(firstValue, secondValue);
00538         } else if (op instanceof ALteqBinaryOperator) {
00539             currentValue = jimple.newLeExpr(firstValue, secondValue);
00540         } else if (op instanceof AGteqBinaryOperator) {
00541             currentValue = jimple.newGeExpr(firstValue, secondValue);
00542         } else if (op instanceof AEqBinaryOperator) {
00543             currentValue = jimple.newEqExpr(firstValue, secondValue);
00544         } else if (op instanceof ANeqBinaryOperator) {
00545             currentValue = jimple.newNeExpr(firstValue, secondValue);
00546         }
00547         
00548         currentStmts.addElement(jimple.newIfStmt(currentValue, trueBranch));
00549 
00550         if (lcl != null) {
00551             Stmt endStmt = jimple.newNopStmt();
00552             currentStmts.addElement(falseBranch);
00553             currentStmts.addElement(jimple.newGotoStmt(endStmt));
00554             currentStmts.addElement(trueBranch);
00555             currentStmts.addElement(endStmt);
00556             trueBranch = prevTrueBranch;
00557             falseBranch = prevFalseBranch;
00558             currentValue = lcl;
00559         }
00560     } else if (op instanceof APlusBinaryOperator || op instanceof AMinusBinaryOperator || op instanceof AModBinaryOperator || op instanceof ADivBinaryOperator || op instanceof AStarBinaryOperator || op instanceof ABitXorBinaryOperator || op instanceof ABitAndBinaryOperator || op instanceof AShiftLeftBinaryOperator || op instanceof ASignedShiftRightBinaryOperator || op instanceof AUnsignedShiftRightBinaryOperator || op instanceof ABitOrBinaryOperator) {
00561         //  +  -  %  /  *  ^  &  <<  >>  >>>  |
00562         try {
00563             numericOperation(op.toString().trim(), firstValue, secondValue);
00564         } catch (CompilerException e) {
00565             exceptions.addElement(e);
00566         }   
00567     } else {
00568         exceptions.addElement(new CompilerException("Unknown binary operator " + op));
00569         currentValue = null;
00570     }
00571 }
00572 /**
00573  * 
00574  * @param node edu.ksu.cis.bandera.jjjc.node.ABlock
00575  */
00576 public void caseABlock(ABlock node) {
00577     if (!(node.parent() instanceof ABlockMethodBody)) {
00578         symbolTable.enterScope();
00579     }
00580     labelEnterBlock();
00581     for (Iterator i = node.getBlockedStmt().iterator(); i.hasNext();) {
00582         ((PBlockedStmt) i.next()).apply(this);
00583     }
00584     labelExitBlock();
00585     if (!(node.parent() instanceof ABlockMethodBody)) {
00586         symbolTable.exitScope();
00587     }
00588 }
00589 /**
00590  * 
00591  * @param node edu.ksu.cis.bandera.jjjc.node.ABlockClassBodyDeclaration
00592  */
00593 public void caseABlockClassBodyDeclaration(ABlockClassBodyDeclaration node) {
00594     if (init == null) {
00595         try {
00596             init = getSootMethod(currentSootClass.getName(), "<init>", new Vector());
00597             init.setReturnType(ca.mcgill.sable.soot.VoidType.v());
00598             init.setModifiers(Modifier.PUBLIC);
00599             initBody = (JimpleBody) jimple.newBody(init);
00600         } catch (CompilerException e) {
00601             exceptions.addElement(e);
00602             return;
00603         }
00604     }
00605     currentSootMethod = init;
00606     currentBody = initBody;
00607     currentLocalNames = new Hashtable();
00608     currentLocalNamesIterator = new Hashtable();
00609     currentLocals = instanceLocals;
00610     currentStmts = instanceStmts;
00611     currentValue = null;
00612     currentType = null;
00613     currentName = null;
00614     labels = new LinkedList();
00615     currentAnnotation = new InstanceInitializerAnnotation(node);
00616     LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
00617     currentAnnotation.setFirstLine(lc.getFirstLine());
00618     currentAnnotation.setFirstColumn(lc.getFirstColumn());
00619     currentAnnotation.setLastLine(lc.getLastLine());
00620     currentAnnotation.setLastColumn(lc.getLastColumn());
00621     currentTraps = new Vector();
00622 
00623     node.getBlock().apply(this);
00624 
00625     for (Enumeration e = currentTraps.elements(); e.hasMoreElements();) {
00626         initBody.addTrap((JTrap) e.nextElement());
00627     }
00628     
00629     currentLocals = null;
00630     currentLocalNames = null;
00631     currentLocalNamesIterator = null;
00632     currentStmts = null;
00633     currentValue = null;
00634     currentType = null;
00635     currentName = null;
00636     currentBody = null;
00637     labels = null;
00638     currentTraps = null;
00639     currentSootMethod = null;
00640 
00641     am.addAnnotation(currentSootClass, "instance initializer " + instanceInitializers++, currentAnnotation);
00642     currentAnnotation = null;
00643 }
00644 /**
00645  * 
00646  * @param node edu.ksu.cis.bandera.jjjc.node.ABlockMethodBody
00647  */
00648 public void caseABlockMethodBody(ABlockMethodBody node) {
00649     node.getBlock().apply(this);
00650 }
00651 /**
00652  * 
00653  * @param node edu.ksu.cis.bandera.jjjc.node.ABlockStmt
00654  */
00655 public void caseABlockStmt(ABlockStmt node) {
00656     if(node.getBlock() != null) {
00657         BlockStmtAnnotation prevAnnotation = currentAnnotation;
00658         currentAnnotation = new BlockStmtAnnotation(node);
00659         LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
00660         currentAnnotation.setFirstLine(lc.getFirstLine());
00661         currentAnnotation.setFirstColumn(lc.getFirstColumn());
00662         currentAnnotation.setLastLine(lc.getLastLine());
00663         currentAnnotation.setLastColumn(lc.getLastColumn());
00664         am.putFilenameLinePairAnnotation(
00665                 new FilenameLinePair(currentClassOrInterfaceType.getPath(),
00666                         LineExtractor.extractLine(node)),
00667                 currentAnnotation);
00668         node.getBlock().apply(this);
00669         if (prevAnnotation != null) {
00670             prevAnnotation.addAnnotation(currentAnnotation);
00671             currentAnnotation = prevAnnotation;
00672         }
00673     }
00674 }
00675 /**
00676  * 
00677  * @param node edu.ksu.cis.bandera.jjjc.node.ABooleanPrimitiveType
00678  */
00679 public void caseABooleanPrimitiveType(ABooleanPrimitiveType node) {
00680     currentType = ca.mcgill.sable.soot.BooleanType.v();
00681 }
00682 /**
00683  * 
00684  * @param node edu.ksu.cis.bandera.jjjc.node.ABreakStmt
00685  */
00686 public void caseABreakStmt(ABreakStmt node) {
00687     int start = currentStmts.size();
00688     
00689     if (node.getId() != null) {
00690         Unit target = getLabelUnit(node.getId().toString().trim());
00691       if (target == null) {
00692             exceptions.addElement(new CompilerException("Invalid break statement..."));
00693             return;
00694       }
00695       Object lastFinallySynchBeforeControl = ((Vector) getLabelObject(target)).firstElement();
00696         for (Enumeration e = synchAnnotations.elements(); e.hasMoreElements();) {
00697             Object o = e.nextElement();
00698             if (o == lastFinallySynchBeforeControl) break;
00699             if (o instanceof Node) {
00700                 ((Node) o).apply(this);
00701             } else {
00702                 SynchronizedStmtAnnotation sann = (SynchronizedStmtAnnotation) o;
00703                 Stmt exitMon = jimple.newExitMonitorStmt(sann.getLockValue());
00704                 sann.addExitMonitor(exitMon);
00705               currentStmts.addElement(exitMon);
00706             }
00707         }
00708         currentStmts.addElement(jimple.newGotoStmt(target));
00709     } else {
00710       if (currentBreakTarget == null) {
00711             exceptions.addElement(new CompilerException("Invalid break statement..."));
00712             return;
00713       }
00714         for (Enumeration e = synchAnnotations.elements(); e.hasMoreElements();) {
00715             Object o = e.nextElement();
00716             if (o == lastFinallySynchBeforeControl) break;
00717             if (o instanceof Node) {
00718                 ((Node) o).apply(this);
00719             } else {
00720                 SynchronizedStmtAnnotation sann = (SynchronizedStmtAnnotation) o;
00721                 Stmt exitMon = jimple.newExitMonitorStmt(sann.getLockValue());
00722                 sann.addExitMonitor(exitMon);
00723               currentStmts.addElement(exitMon);
00724             }
00725         }
00726         currentStmts.addElement(jimple.newGotoStmt(currentBreakTarget));
00727     }
00728     
00729     int end = currentStmts.size();
00730     BreakStmtAnnotation ann = new BreakStmtAnnotation(node);
00731     LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
00732     ann.setFirstLine(lc.getFirstLine());
00733     ann.setFirstColumn(lc.getFirstColumn());
00734     ann.setLastLine(lc.getLastLine());
00735     ann.setLastColumn(lc.getLastColumn());
00736     am.putFilenameLinePairAnnotation(
00737             new FilenameLinePair(currentClassOrInterfaceType.getPath(),
00738                     LineExtractor.extractLine(node)),
00739             ann);
00740     
00741     for (int i = start; i < end; i++) {
00742         ann.addStmt((Stmt) currentStmts.elementAt(i));
00743     }
00744     currentAnnotation.addAnnotation(ann); 
00745 }
00746 /**
00747  * 
00748  * @param node edu.ksu.cis.bandera.jjjc.node.ABytePrimitiveType
00749  */
00750 public void caseABytePrimitiveType(ABytePrimitiveType node) {
00751     currentType = ca.mcgill.sable.soot.ByteType.v();
00752 }
00753 /**
00754  * 
00755  * @param node edu.ksu.cis.bandera.jjjc.node.ACaseSwitchLabel
00756  */
00757 public void caseACaseSwitchLabel(ACaseSwitchLabel node) {
00758     Value tempValue = currentValue;
00759     TrivialExpression.optimize(node.getExp(), true);
00760     node.getExp().apply(this);
00761     if ((currentValue == null) || !isNumberConstant(currentValue)) {
00762         exceptions.addElement(new CompilerException("Cannot have " + node.getExp().toString() + " as a switch case"));
00763         return;
00764     }
00765     if (currentValue instanceof LongConstant) {
00766         currentValue = IntConstant.v((int) ((LongConstant) currentValue).value);
00767     }
00768     currentLookupValues.addLast(new Integer(((IntConstant) currentValue).value));
00769     currentValue = tempValue;
00770 }
00771 /**
00772  * 
00773  * @param node edu.ksu.cis.bandera.jjjc.node.ACatchClause
00774  */
00775 public void caseACatchClause(ACatchClause node) {
00776     BlockStmtAnnotation prevAnnotation = currentAnnotation;
00777     try {
00778         symbolTable.enterScope();
00779         labelEnterBlock();
00780         PFormalParameter formalParameter = (PFormalParameter) node.getFormalParameter();
00781         formalParameter.apply(this);
00782         Local tempLocal = declareLocal(((AVariableDeclaratorId)
00783                 ((AFormalParameter) formalParameter).getVariableDeclaratorId()).getId().toString().trim(), currentType, 0);
00784         
00785         Stmt handlerStmt = jimple.newIdentityStmt(tempLocal, jimple.newCaughtExceptionRef(currentBody));
00786         currentStmts.addElement(handlerStmt);
00787 
00788         currentAnnotation = new CatchAnnotation(node);
00789         LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
00790         currentAnnotation.setFirstLine(lc.getFirstLine());
00791         currentAnnotation.setFirstColumn(lc.getFirstColumn());
00792         currentAnnotation.setLastLine(lc.getLastLine());
00793         currentAnnotation.setLastColumn(lc.getLastColumn());
00794         am.putFilenameLinePairAnnotation(
00795                 new FilenameLinePair(currentClassOrInterfaceType.getPath(),
00796                         LineExtractor.extractLine(node)),
00797                 currentAnnotation);
00798         node.getBlock().apply(this);
00799 
00800         SequentialAnnotation sann = new SequentialAnnotation(null);
00801         sann.addStmt(handlerStmt);
00802         currentAnnotation.insertAnnotationAt(sann, 0);
00803         
00804         Stmt lastStmt = (Stmt) currentStmts.lastElement();
00805 
00806         
00807         if (!((lastStmt instanceof ReturnStmt) || (lastStmt instanceof ReturnVoidStmt)
00808             || (lastStmt instanceof ThrowStmt) || (lastStmt instanceof GotoStmt))) {
00809             sann = new SequentialAnnotation(null);
00810             Stmt endCatchStmt = jimple.newGotoStmt(endTryStmt);
00811             sann.addStmt(endCatchStmt);
00812             currentStmts.addElement(endCatchStmt);
00813             currentAnnotation.addAnnotation(sann);
00814         } else {
00815             catchHasEnd = false;
00816         }
00817 
00818         
00819         String className = ((ca.mcgill.sable.soot.RefType) tempLocal.getType()).className;
00820         SootClass sc = getSootClass(className);
00821         ClassOrInterfaceType exceptionType = symbolTable.resolveClassOrInterfaceType(new Name(className));
00822         Name throwableName = new Name("java.lang.Throwable");
00823         if (!(exceptionType.hasSuperClass(throwableName) || throwableName.equals(exceptionType.getName()))) {
00824             throw new NotThrowableException("Cannot have an unthrowable exception type named '" + className + "'");
00825         }
00826         currentTraps.addElement(jimple.newTrap(sc, beginTrapStmt, endTrapStmt, handlerStmt));
00827         symbolTable.exitScope();
00828         labelExitBlock();
00829         currentTryAnnotation.addCatchClauseAnnotation(currentAnnotation);
00830     } catch (CompilerException e) {
00831         exceptions.addElement(e);
00832     }
00833     currentAnnotation = prevAnnotation;
00834 }
00835 /**
00836  * 
00837  * @param node edu.ksu.cis.bandera.jjjc.node.ACharacterLiteralLiteral
00838  */
00839 public void caseACharacterLiteralLiteral(ACharacterLiteralLiteral node) {
00840     String literal = node.toString().trim();
00841     literal = literal.substring(1, literal.length() - 1);
00842     int value = 0;
00843 
00844     if (literal.startsWith("\\")) {
00845         switch (literal.charAt(1)) {
00846             case 'b': value = '\b';
00847                 break;
00848             case 't': value = '\t';
00849                 break;
00850             case 'n': value = '\n';
00851                 break;
00852             case 'f': value = '\f';
00853                 break;
00854             case 'r': value = '\r';
00855                 break;
00856             case '\"': value = '\"';
00857                 break;
00858             case '\'': value = '\'';
00859                 break;
00860             case '\\': value = '\\';
00861                 break;
00862             default: value = Integer.valueOf(literal.substring(1), 8).intValue();
00863         }
00864     } else if (literal.startsWith("\\u")) {
00865         value = Integer.valueOf(literal.substring(2), 16).intValue();
00866     } else value = literal.charAt(0);
00867     
00868     currentValue = IntConstant.v(value);
00869     integralConstantType = edu.ksu.cis.bandera.jjjc.symboltable.CharType.TYPE;
00870 }
00871 /**
00872  * 
00873  * @param node edu.ksu.cis.bandera.jjjc.node.ACharPrimitiveType
00874  */
00875 public void caseACharPrimitiveType(ACharPrimitiveType node) {
00876     currentType = ca.mcgill.sable.soot.CharType.v();
00877 }
00878 /**
00879  * 
00880  * @param node edu.ksu.cis.bandera.jjjc.node.AClassBody
00881  */
00882 public void caseAClassBody(AClassBody node) {
00883     // prepare variables for field processing
00884     nameGen = new NameGenerator();
00885     currentLocalNames = new Hashtable();
00886     currentLocalNamesIterator = new Hashtable();
00887     currentLocals = new Hashtable();
00888     currentStmts = new Vector();
00889     currentValue = null;
00890     currentType = null;
00891     currentName = null;
00892     staticLocals = new Hashtable();
00893     staticStmts = new Vector();
00894     instanceLocals = new Hashtable();
00895     instanceStmts = new Vector();
00896     currentThisLocal = jimple.newLocal(nameGen.newName(), ca.mcgill.sable.soot.RefType.v(currentSootClass.getName()));
00897     instanceLocals.put(currentThisLocal.getName(), currentThisLocal);
00898     instanceStmts.addElement(jimple.newIdentityStmt(currentThisLocal, jimple.newThisRef(currentSootClass)));
00899     LinkedList ClassBodyDeclList = node.getClassBodyDeclaration();
00900     PClassBodyDeclaration classBodyDecl;
00901     if (ClassBodyDeclList.size() > 0) {
00902         classBodyDecl = (PClassBodyDeclaration) ClassBodyDeclList.getFirst();
00903         for (Iterator i = ClassBodyDeclList.iterator(); i.hasNext();) {
00904             classBodyDecl = (PClassBodyDeclaration) i.next();
00905             if (classBodyDecl instanceof AFieldClassBodyDeclaration)
00906                 classBodyDecl.apply(this);
00907         }
00908         for (Iterator i = ClassBodyDeclList.iterator(); i.hasNext();) {
00909             classBodyDecl = (PClassBodyDeclaration) i.next();
00910             if (classBodyDecl instanceof AStaticInitializerClassBodyDeclaration)
00911                 classBodyDecl.apply(this);
00912         }
00913         for (Iterator i = ClassBodyDeclList.iterator(); i.hasNext();) {
00914             classBodyDecl = (PClassBodyDeclaration) i.next();
00915             if (classBodyDecl instanceof ABlockClassBodyDeclaration)
00916                 classBodyDecl.apply(this);
00917         }
00918     }
00919     nameGen = null;
00920     boolean generateConstructor = false;
00921     Local thisLocal = currentThisLocal;
00922 
00923     // if there is no constructor declaration, indicate to generate a default one.
00924     if (ClassBodyDeclList.size() > 0) {
00925         classBodyDecl = (PClassBodyDeclaration) ClassBodyDeclList.getFirst();
00926         for (Iterator i = ClassBodyDeclList.iterator(); i.hasNext();) {
00927             classBodyDecl = (PClassBodyDeclaration) i.next();
00928             if (classBodyDecl instanceof AConstructorClassBodyDeclaration)
00929                 break;
00930         }
00931 
00932         // generate default instance constructor if necessary
00933         if (!(classBodyDecl instanceof AConstructorClassBodyDeclaration)) {
00934             generateConstructor = true;
00935         }
00936 
00937         // method or constructor declarations
00938         currentLocals = null;
00939         currentStmts = null;
00940         currentThisLocal = null;
00941         currentLocalNames = null;
00942         currentLocalNamesIterator = null;
00943         for (Iterator i = ClassBodyDeclList.iterator(); i.hasNext();) {
00944             classBodyDecl = (PClassBodyDeclaration) i.next();
00945             if (!(classBodyDecl instanceof AFieldClassBodyDeclaration) && !(classBodyDecl instanceof ABlockClassBodyDeclaration) && !(classBodyDecl instanceof AStaticInitializerClassBodyDeclaration))
00946                 classBodyDecl.apply(this);
00947         }
00948     } else
00949         generateConstructor = true;
00950 
00951     // generate instance constructor if necessary
00952     if (generateConstructor) {
00953         try {
00954             SootMethod sootMethod;
00955             JimpleBody body;
00956             if (init == null) {
00957                 sootMethod = getSootMethod(currentSootClass.getName(), "<init>", new Vector());
00958                 sootMethod.setReturnType(ca.mcgill.sable.soot.VoidType.v());
00959                 sootMethod.setModifiers(Modifier.PUBLIC);
00960                 body = (JimpleBody) jimple.newBody(sootMethod);
00961             } else {
00962                 sootMethod = init;
00963                 body = initBody;
00964             }
00965             
00966             SequentialAnnotation sann = new SequentialAnnotation(null);
00967             StmtList stmts = body.getStmtList();
00968             for (Enumeration e = instanceLocals.elements(); e.hasMoreElements();) {
00969                 body.addLocal((Local) e.nextElement());
00970             }
00971             for (int i = 0; i < instanceStmts.size(); i++) {
00972                 sann.addStmt((Stmt) instanceStmts.elementAt(i));
00973                 stmts.add(instanceStmts.elementAt(i));
00974                 if ((i == 0) && (!currentSootClass.getName().equals("java.lang.Object"))) {
00975                     try {
00976                         SootClass sc = currentSootClass.getSuperClass();
00977                         SootMethod sm = getSootMethod(sc.getName(), "<init>", new Vector());
00978                         Stmt stmt = jimple.newInvokeStmt(jimple.newSpecialInvokeExpr(thisLocal, sm, new LinkedList()));
00979                         stmts.add(stmt);
00980                         sann.addStmt(stmt);
00981                     } catch (NoSuperClassException nsce) {
00982                     }
00983                 }
00984             }
00985             Stmt stmt = jimple.newReturnVoidStmt();
00986             stmts.add(stmt);
00987             sann.addStmt(stmt);
00988             
00989             ConstructorDeclarationAnnotation bann = new ConstructorDeclarationAnnotation(null);
00990             bann.addAnnotation(sann);
00991             bann.setSootMethod(sootMethod);
00992             bann.setConstructor(currentClassOrInterfaceType.getConstructor(new Vector()));
00993             am.addAnnotation(currentSootClass, sootMethod, bann);
00994             
00995             TemporaryLocalsReduction.reduce(body, bann);
00996             DeadCodeElimination.eliminate(body);
00997             JumpElimination.eliminate(body);
00998             DeadCodeEliminator.eliminateDeadCode(body);
00999             Transformations.removeUnusedLocals(body);
01000 
01001             bann.validate(body);
01002             
01003             sootMethod.storeBody(jimple, body);
01004         } catch (CompilerException e) {
01005             exceptions.addElement(e);
01006         }
01007     }
01008 
01009     // generate static constructor
01010     if (staticStmts.size() > 0) {
01011         SootMethod sootMethod;
01012         JimpleBody body;
01013         if (clinit == null) {
01014             sootMethod = new SootMethod("<clinit>", new LinkedList(), ca.mcgill.sable.soot.VoidType.v(),
01015                     Modifier.PUBLIC);
01016             body = (JimpleBody) jimple.newBody(sootMethod);
01017         } else {
01018             sootMethod = clinit;
01019             body = clinitBody;
01020         }
01021         SequentialAnnotation sann = new SequentialAnnotation(null);
01022         StmtList stmts = body.getStmtList();
01023         for (Enumeration e = staticLocals.elements(); e.hasMoreElements();) {
01024             body.addLocal((Local) e.nextElement());
01025         }
01026         for (int i = 0; i < staticStmts.size(); i++) {
01027             stmts.add(staticStmts.elementAt(i));
01028             sann.addStmt((Stmt) staticStmts.elementAt(i));
01029         }
01030         Stmt stmt = jimple.newReturnVoidStmt();
01031         stmts.add(stmt);
01032         sann.add(stmt);
01033         ConstructorDeclarationAnnotation bann = new ConstructorDeclarationAnnotation(null);
01034         bann.addAnnotation(sann);
01035         bann.setSootMethod(sootMethod);
01036         am.addAnnotation(currentSootClass, sootMethod, bann);
01037 
01038         currentSootClass.addMethod(sootMethod);
01039         
01040         TemporaryLocalsReduction.reduce(body, bann);
01041         DeadCodeElimination.eliminate(body);
01042         JumpElimination.eliminate(body);
01043         DeadCodeEliminator.eliminateDeadCode(body);
01044         Transformations.removeUnusedLocals(body);
01045 
01046         bann.validate(body);
01047         sootMethod.storeBody(jimple, body);
01048     } 
01049 }
01050 /**
01051  * 
01052  * @param node edu.ksu.cis.bandera.jjjc.node.AClassClassBodyDeclaration
01053  */
01054 public void caseAClassClassBodyDeclaration(AClassClassBodyDeclaration node) {
01055     System.out.println("Unsupported feature of Java: " + node);
01056     exceptions.addElement(new CompilerException("Unsupported feature of Java: " + node));
01057     throw new Error("Unsupported feature of Java: " + node);
01058 }
01059 /**
01060  * 
01061  * @param node edu.ksu.cis.bandera.jjjc.node.AClassDeclaration
01062  */
01063 public void caseAClassDeclaration(AClassDeclaration node) {
01064     try {
01065       currentClassOrInterfaceType = symbolTable.getDeclaredType(new Name(node.getId().toString()));
01066         symbolTable.setCurrentClassOrInterfaceType(currentClassOrInterfaceType);
01067         
01068         currentSootClass = getSootClass(currentClassOrInterfaceType.getName().toString());
01069       ClassDeclarationAnnotation cda = new ClassDeclarationAnnotation(node);
01070         LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
01071         cda.setFirstLine(lc.getFirstLine());
01072         cda.setFirstColumn(lc.getFirstColumn());
01073         cda.setLastLine(lc.getLastLine());
01074         cda.setLastColumn(lc.getLastColumn());
01075       cda.setSootClass(currentSootClass);
01076       am.addAnnotation(cda);
01077         am.putFilenameLinePairAnnotation(new FilenameLinePair(currentClassOrInterfaceType.getPath(),
01078             LineExtractor.extractLine(node)), cda);
01079 
01080         symbolTable.resetScope();
01081         if (node.getClassBody() != null) {
01082           node.getClassBody().apply(this);
01083         }
01084         compiledClasses.addElement(currentSootClass.getName());
01085         CompilationManager.addDocTriple(new DocTriple(currentSootClass, null, DocProcessor.tags(node, docComments)));
01086     } catch (CompilerException e) {
01087       exceptions.addElement(e);
01088     }
01089 
01090     currentClassOrInterfaceType = null;
01091     symbolTable.setCurrentClassOrInterfaceType(null);
01092     currentSootClass = null;
01093 }
01094 /**
01095  * 
01096  * @param node edu.ksu.cis.bandera.jjjc.node.AClassDeclarationBlockedStmt
01097  */
01098 public void caseAClassDeclarationBlockedStmt(AClassDeclarationBlockedStmt node) {
01099     System.out.println("Unsupported feature of Java: " + node);
01100     exceptions.addElement(new CompilerException("Unsupported feature of Java: " + node));
01101     throw new Error("Unsupported feature of Java: " + node);
01102 }
01103 /**
01104  * 
01105  * @param node edu.ksu.cis.bandera.jjjc.node.AClassDeclarationInterfaceMemberDeclaration
01106  */
01107 public void caseAClassDeclarationInterfaceMemberDeclaration(AClassDeclarationInterfaceMemberDeclaration node) {
01108     System.out.println("Unsupported feature of Java: " + node);
01109     exceptions.addElement(new CompilerException("Unsupported feature of Java: " + node));
01110     throw new Error("Unsupported feature of Java: " + node);
01111 }
01112 /**
01113  * 
01114  * @param node edu.ksu.cis.bandera.jjjc.node.AClassOrInterfaceTypeExp
01115  */
01116 public void caseAClassOrInterfaceTypeExp(AClassOrInterfaceTypeExp node) {
01117     try {
01118         RefType refType = RefType.v(getSootClass((new Name(node.getClassOrInterfaceType().toString())).toString()).getName());
01119         currentType = null;
01120         LinkedList arrayExps = new LinkedList();
01121         int dimensions = 0;
01122         currentValue = null;
01123         for (Iterator i = node.getDimExp().iterator(); i.hasNext();) {
01124             ((PDimExp) i.next()).apply(this);
01125             arrayExps.addLast(currentValue);
01126             currentValue = null;
01127             dimensions++;
01128         }
01129         dimensions += node.getDim().size();
01130         if (dimensions == 1) {
01131             currentValue = jimple.newNewArrayExpr(refType, (Value) arrayExps.removeFirst());
01132         } else {
01133             currentType = ca.mcgill.sable.soot.ArrayType.v(refType, dimensions);
01134             currentValue = jimple.newNewMultiArrayExpr((ca.mcgill.sable.soot.ArrayType) currentType, arrayExps);
01135             currentType = null;
01136         }
01137         Value newValue = currentValue;
01138         currentValue = null;
01139         Local lcl = declareLocal(nameGen.newName(), newValue.getType(), 0);
01140         currentStmts.addElement(jimple.newAssignStmt(lcl, newValue));
01141         currentValue = lcl;
01142         currentType = lcl.getType();
01143     } catch (CompilerException e) {
01144         exceptions.addElement(e);
01145     }
01146 }
01147 /**
01148  * 
01149  * @param node edu.ksu.cis.bandera.jjjc.node.ACompilationUnit
01150  */
01151 public void caseACompilationUnit(ACompilationUnit node) {
01152     try {
01153         if (node.getPackageDeclaration() != null) {
01154             symbolTable.setCurrentPackage(Package.getPackage(new Name(node.getPackageDeclaration().toString())));
01155         } else {
01156             symbolTable.setCurrentPackage(Package.getPackage(new Name("")));
01157         }
01158         Object temp[] = node.getTypeDeclaration().toArray();
01159         for (int i = 0; i < temp.length; i++) {
01160             ((PTypeDeclaration) temp[i]).apply(this);
01161         }
01162     } catch (CompilerException e) {
01163         exceptions.addElement(e);
01164     }
01165 }
01166 /**
01167  * 
01168  * @param node edu.ksu.cis.bandera.jjjc.node.AConstructorBody
01169  */
01170 public void caseAConstructorBody(AConstructorBody node) {
01171     try {
01172         symbolTable.enterScope();
01173         boolean needHelper = false;
01174         PConstructorInvocation constructorInvocation = (PConstructorInvocation) node.getConstructorInvocation();
01175         if (!(constructorInvocation instanceof AThisConstructorInvocation)) {
01176             needHelper = true;
01177         }
01178         if (constructorInvocation != null) {
01179             constructorInvocation.apply(this);
01180         } else {
01181             SootMethod sm = getSootMethod(currentSootClass.getSuperClass().getName(), "<init>", new Vector());
01182             SequentialAnnotation sann = new SequentialAnnotation(null);
01183             Stmt stmt = jimple.newInvokeStmt(jimple.newSpecialInvokeExpr(currentThisLocal, sm, new LinkedList()));
01184             currentStmts.addElement(stmt);
01185             sann.addStmt(stmt);
01186             currentAnnotation.addAnnotation(sann);
01187             needHelper = true;
01188         }
01189 
01190         if ((instanceStmts.size() > 1) && needHelper) {
01191             SequentialAnnotation sann = new SequentialAnnotation(null);
01192             JimpleStmtCloner.reset();
01193             JimpleStmtCloner.setBody(currentBody);
01194 
01195             for (Enumeration e = instanceStmts.elements(); e.hasMoreElements();) {
01196                 Stmt s = (Stmt) e.nextElement();
01197                 Stmt stmt = JimpleStmtCloner.clone(s);
01198                 sann.addStmt(stmt);
01199                 currentStmts.addElement(stmt);
01200             }
01201             if (initBody != null)
01202                 JimpleStmtCloner.copyTrap(initBody);
01203             JimpleStmtCloner.reset();
01204             JimpleStmtCloner.setBody(null);
01205             currentAnnotation.addAnnotation(sann);
01206         }
01207         labelEnterBlock();
01208         for (Iterator i = node.getBlockedStmt().iterator(); i.hasNext();) {
01209             ((PBlockedStmt) i.next()).apply(this);
01210         }
01211         labelExitBlock();
01212         symbolTable.exitScope();
01213     } catch (CompilerException e) {
01214         exceptions.addElement(e);
01215     }
01216 }
01217 /**
01218  * 
01219  * @param node edu.ksu.cis.bandera.jjjc.node.AConstructorDeclaration
01220  */
01221 public void caseAConstructorDeclaration(AConstructorDeclaration node) {
01222     if (CompilationManager.getModifiedMethodTable().get(node) != null) {
01223         ((Node) CompilationManager.getModifiedMethodTable().get(node)).apply(this);
01224         CompilationManager.addDocTriple(new DocTriple(currentSootClass, currentSootMethod, DocProcessor.tags(node, docComments)));
01225         return;
01226     }
01227     currentSootMethod = null;
01228     nameGen = new NameGenerator();
01229     currentLocalNames = new Hashtable();
01230     currentLocalNamesIterator = new Hashtable();
01231     currentLocals = new Hashtable();
01232     currentStmts = new Vector();
01233     currentValue = null;
01234     currentType = null;
01235     currentName = null;
01236     currentThisLocal = null;
01237     labels = new LinkedList();
01238     currentAnnotation = new ConstructorDeclarationAnnotation(node);
01239     LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
01240     currentAnnotation.setFirstLine(lc.getFirstLine());
01241     currentAnnotation.setFirstColumn(lc.getFirstColumn());
01242     currentAnnotation.setLastLine(lc.getLastLine());
01243     currentAnnotation.setLastColumn(lc.getLastColumn());
01244     currentTraps = new Vector();
01245     
01246     symbolTable.enterScope();
01247     node.getConstructorDeclarator().apply(this);
01248     node.getConstructorBody().apply(this);
01249     symbolTable.exitScope();
01250 
01251     // create the actual body
01252     StmtList stmts = currentBody.getStmtList();
01253     for (Enumeration e = currentLocals.elements(); e.hasMoreElements();) {
01254         currentBody.addLocal((Local) e.nextElement());
01255     }
01256     for (int i = 0; i < currentStmts.size(); i++) {
01257         stmts.add((Stmt) currentStmts.elementAt(i));
01258     }
01259 
01260     Stmt tempStmt = null;
01261     if (currentStmts.size() > 0) {
01262         int size = currentStmts.size();
01263         Stmt lastStmt = (Stmt) currentStmts.elementAt(--size);
01264         if (!(lastStmt instanceof JReturnStmt) && !(lastStmt instanceof JReturnVoidStmt)
01265                 && !(lastStmt instanceof JThrowStmt)) {
01266             tempStmt = jimple.newReturnVoidStmt();
01267             stmts.add(tempStmt);
01268             SequentialAnnotation ann = new SequentialAnnotation(null);
01269             ann.addStmt(tempStmt);
01270             currentAnnotation.addAnnotation(ann);
01271         }
01272     } else {
01273         SequentialAnnotation ann = new SequentialAnnotation(null);
01274         Stmt stmt = jimple.newReturnVoidStmt();
01275         ann.addStmt(stmt);
01276         stmts.add(stmt);
01277         currentAnnotation.addAnnotation(ann);
01278     }
01279     
01280     for (Enumeration e = currentTraps.elements(); e.hasMoreElements();) {
01281         currentBody.addTrap((Trap) e.nextElement());
01282     }
01283     
01284     am.addAnnotation(currentSootClass, currentSootMethod, currentAnnotation);
01285     
01286     // store body
01287     convertLocalTypes(currentBody);
01288     TemporaryLocalsReduction.reduce(currentBody, currentAnnotation);
01289     DeadCodeElimination.eliminate(currentBody);
01290     JumpElimination.eliminate(currentBody);
01291     DeadCodeEliminator.eliminateDeadCode(currentBody);
01292     DeadCodeElimination.eliminate(currentBody);
01293     //Transformations.removeUnusedLocals(currentBody);
01294     Transformations.cleanupCode(currentBody);
01295 
01296     currentAnnotation.validate(currentBody);
01297     //checkAnnotation(currentAnnotation, currentBody);
01298     currentSootMethod.storeBody(jimple, currentBody);
01299     am.putFilenameLinePairAnnotation(new FilenameLinePair(currentClassOrInterfaceType.getPath(),
01300             LineExtractor.extractLine(node)), currentAnnotation);
01301     
01302     CompilationManager.addDocTriple(new DocTriple(currentSootClass, currentSootMethod, DocProcessor.tags(node, docComments)));
01303 
01304     // cleaning up
01305     nameGen = null;
01306     currentLocals = null;
01307     currentLocalNames = null;
01308     currentLocalNamesIterator = null;
01309     currentStmts = null;
01310     currentValue = null;
01311     currentType = null;
01312     currentName = null;
01313     currentThisLocal = null;
01314     labels = null;
01315     currentTraps = null;
01316     currentAnnotation = null;
01317 }
01318 /**
01319  * 
01320  * @param node edu.ksu.cis.bandera.jjjc.node.AConstructorDeclarator
01321  */
01322 public void caseAConstructorDeclarator(AConstructorDeclarator node) {
01323     // get constructor header information
01324     String constructorName = "<init>";
01325 
01326     try {   
01327         // process parameter list
01328         currentType = null;
01329         Vector formalParameters = new Vector();
01330         for (Iterator i = node.getFormalParameter().iterator(); i.hasNext();) {
01331             ((PFormalParameter) i.next()).apply(this);
01332             formalParameters.addElement(Util.convertType(currentType, symbolTable));
01333             currentType = null;
01334         }
01335 
01336         currentSootMethod = getSootMethod(currentSootClass.getName(), constructorName, formalParameters);
01337         ((ConstructorDeclarationAnnotation) currentAnnotation).setSootMethod(currentSootMethod);
01338         ((ConstructorDeclarationAnnotation) currentAnnotation).setConstructor(currentClassOrInterfaceType.getConstructor(formalParameters));
01339         currentBody = (JimpleBody) jimple.newBody(currentSootMethod);
01340 
01341         // make a local for holding this ref
01342         {
01343             String thisName = nameGen.newName();
01344             currentThisLocal = declareLocal(thisName, ca.mcgill.sable.soot.RefType.v(currentSootClass.getName()), 0);
01345             SequentialAnnotation ann = new SequentialAnnotation(null);
01346             Stmt s = jimple.newIdentityStmt(currentThisLocal, jimple.newThisRef(currentSootClass));
01347             currentStmts.addElement(s);
01348             ann.addStmt(s);
01349             currentAnnotation.addAnnotation(ann);
01350         }
01351 
01352         // declare parameters variable as locals
01353         SequentialAnnotation ann = new SequentialAnnotation(null);
01354         int paramNum = 0;
01355         Method m = currentClassOrInterfaceType.getConstructor(formalParameters);
01356         for (Enumeration e = m.getParameters().elements(); e.hasMoreElements(); paramNum++) {
01357             Variable v = (Variable) e.nextElement();
01358             Local tempLocal = declareLocal(v.getName().toString(), Util.convertType(v.getType()),
01359                     Util.convertModifiers(v.getModifiers()));
01360             currentLocals.put(tempLocal.getName(), tempLocal);
01361             Stmt s = jimple.newIdentityStmt(tempLocal, jimple.newParameterRef(currentSootMethod, paramNum));
01362             currentStmts.addElement(s);
01363             ann.addStmt(s);
01364         }
01365         currentAnnotation.addAnnotation(ann);
01366     } catch (CompilerException e) {
01367         exceptions.addElement(e);
01368     }
01369 }
01370 /**
01371  * 
01372  * @param node edu.ksu.cis.bandera.jjjc.node.AContinueStmt
01373  */
01374 public void caseAContinueStmt(AContinueStmt node) {
01375     int start = currentStmts.size();
01376     
01377     if (node.getId() != null) {
01378         Unit target = getLabelUnit(node.getId().toString().trim());
01379       if (target == null) {
01380             exceptions.addElement(new CompilerException("Invalid continue statement..."));
01381             return;
01382       }
01383       Object lastFinallySynchBeforeControl = ((Vector) getLabelObject(target)).firstElement();
01384         for (Enumeration e = synchAnnotations.elements(); e.hasMoreElements();) {
01385             Object o = e.nextElement();
01386             if (o == lastFinallySynchBeforeControl) break;
01387             if (o instanceof Node) {
01388                 ((Node) o).apply(this);
01389             } else {
01390                 SynchronizedStmtAnnotation sann = (SynchronizedStmtAnnotation) o;
01391                 Stmt exitMon = jimple.newExitMonitorStmt(sann.getLockValue());
01392                 sann.addExitMonitor(exitMon);
01393               currentStmts.addElement(exitMon);
01394             }
01395         }
01396         currentStmts.addElement(jimple.newGotoStmt(target));
01397     } else {
01398         if (currentContinueTarget == null) {
01399             exceptions.addElement(new CompilerException("Invalid continue statement..."));
01400             return;
01401         } 
01402         for (Enumeration e = synchAnnotations.elements(); e.hasMoreElements();) {
01403             Object o = e.nextElement();
01404             if (o == lastFinallySynchBeforeControl) break;
01405             if (o instanceof Node) {
01406                 ((Node) o).apply(this);
01407             } else {
01408                 SynchronizedStmtAnnotation sann = (SynchronizedStmtAnnotation) o;
01409                 Stmt exitMon = jimple.newExitMonitorStmt(sann.getLockValue());
01410                 sann.addExitMonitor(exitMon);
01411               currentStmts.addElement(exitMon);
01412             }
01413         }
01414         currentStmts.addElement(jimple.newGotoStmt(currentContinueTarget));
01415     }
01416     
01417     int end = currentStmts.size();
01418     ContinueStmtAnnotation ann = new ContinueStmtAnnotation(node);
01419     LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
01420     ann.setFirstLine(lc.getFirstLine());
01421     ann.setFirstColumn(lc.getFirstColumn());
01422     ann.setLastLine(lc.getLastLine());
01423     ann.setLastColumn(lc.getLastColumn());
01424     am.putFilenameLinePairAnnotation(
01425             new FilenameLinePair(currentClassOrInterfaceType.getPath(),
01426                     LineExtractor.extractLine(node)),
01427             ann);
01428     
01429     for (int i = start; i < end; i++) {
01430         ann.addStmt((Stmt) currentStmts.elementAt(i));
01431     }
01432     currentAnnotation.addAnnotation(ann); 
01433 }
01434 /**
01435  * 
01436  * @param node edu.ksu.cis.bandera.jjjc.node.ADecimalIntegerLiteral
01437  */
01438 public void caseADecimalIntegerLiteral(ADecimalIntegerLiteral node) {
01439     String literal = node.toString().trim();
01440     if (literal.endsWith("L") || literal.endsWith("l")) {
01441         currentValue = LongConstant.v(Long.valueOf(literal.substring(0, literal.length() - 1)).longValue());
01442         integralConstantType = edu.ksu.cis.bandera.jjjc.symboltable.LongType.TYPE;
01443     } else {
01444         currentValue = IntConstant.v(Integer.valueOf(literal).intValue());
01445         integralConstantType = edu.ksu.cis.bandera.jjjc.symboltable.IntType.TYPE;
01446     }
01447 }
01448 /**
01449  * 
01450  * @param node edu.ksu.cis.bandera.jjjc.node.ADefaultSwitchLabel
01451  */
01452 public void caseADefaultSwitchLabel(ADefaultSwitchLabel node) {
01453     defaultSwitch = !defaultSwitch;
01454 }
01455 /**
01456  * 
01457  * @param node edu.ksu.cis.bandera.jjjc.node.ADoStmt
01458  */
01459 public void caseADoStmt(ADoStmt node) {
01460     Stmt doStmt = jimple.newNopStmt();
01461     Stmt testStmt = jimple.newNopStmt();
01462     Stmt endStmt = jimple.newNopStmt();
01463 
01464     DoWhileStmtAnnotation ann = new DoWhileStmtAnnotation(node);
01465     LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
01466     ann.setFirstLine(lc.getFirstLine());
01467     ann.setFirstColumn(lc.getFirstColumn());
01468     ann.setLastLine(lc.getLastLine());
01469     ann.setLastColumn(lc.getLastColumn());
01470     am.putFilenameLinePairAnnotation(
01471             new FilenameLinePair(currentClassOrInterfaceType.getPath(),
01472                     LineExtractor.extractLine(node)),
01473             ann);
01474 
01475     Object prevLastSynch = lastFinallySynchBeforeControl;
01476     if (synchAnnotations.size() > 0)
01477         lastFinallySynchBeforeControl = (Annotation) synchAnnotations.lastElement();
01478 
01479     Stmt prevTrueBranch = trueBranch;
01480     Stmt prevFalseBranch = falseBranch;
01481     trueBranch = doStmt;
01482     falseBranch = endStmt;
01483     Stmt prevBreakTarget = currentBreakTarget;
01484     Stmt prevContinueTarget = currentContinueTarget;
01485     currentBreakTarget = endStmt;
01486     currentContinueTarget = testStmt;
01487 
01488     BlockStmtAnnotation prevAnnotation = currentAnnotation;
01489     currentAnnotation = new BlockStmtAnnotation(node.getBlock());
01490 
01491     currentStmts.addElement(doStmt);
01492 
01493     node.getBlock().apply(this);
01494 
01495     ann.setBlockAnnotation(getFirstEnclosedAnnotation(currentAnnotation));
01496 
01497     currentStmts.addElement(testStmt);
01498 
01499     int start = currentStmts.size();
01500 
01501     Node n = (Node) node.getExp().clone();
01502     PushComplement.push(n);
01503     if (node.getExp() instanceof AUnaryExp)
01504         if ("!".equals(((AUnaryExp) node.getExp()).getUnaryOperator().toString().trim()))
01505             n = ((AUnaryExp) n).getExp();
01506     n.apply(new BooleanExpression(this, trueBranch, falseBranch));
01507     
01508     ann.setIndefinite(currentStmts.elementAt(currentStmts.size() - 1) instanceof JGotoStmt);
01509     
01510     int end = currentStmts.size();
01511     
01512     for (int i = start; i < end; i++) {
01513         ann.addStmt((Stmt) currentStmts.elementAt(i));
01514     }
01515     
01516     currentStmts.addElement(endStmt);
01517     currentValue = null;
01518 
01519 
01520     trueBranch = prevTrueBranch;
01521     falseBranch = prevFalseBranch;
01522     currentBreakTarget = prevBreakTarget;
01523     currentContinueTarget = prevContinueTarget;
01524     lastFinallySynchBeforeControl = prevLastSynch;
01525 
01526     currentAnnotation = prevAnnotation;
01527     currentAnnotation.addAnnotation(ann);
01528 }
01529 /**
01530  * 
01531  * @param node edu.ksu.cis.bandera.jjjc.node.ADoublePrimitiveType
01532  */
01533 public void caseADoublePrimitiveType(ADoublePrimitiveType node) {
01534     currentType = ca.mcgill.sable.soot.DoubleType.v();
01535 }
01536 /**
01537  * 
01538  * @param node edu.ksu.cis.bandera.jjjc.node.AEmptyStmt
01539  */
01540 public void caseAEmptyStmt(AEmptyStmt node) {
01541     Annotation ea = new EmptyStmtAnnotation(node);
01542     LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
01543     ea.setFirstLine(lc.getFirstLine());
01544     ea.setFirstColumn(lc.getFirstColumn());
01545     ea.setLastLine(lc.getLastLine());
01546     ea.setLastColumn(lc.getLastColumn());
01547     currentAnnotation.addAnnotation(ea);
01548     am.putFilenameLinePairAnnotation(
01549             new FilenameLinePair(currentClassOrInterfaceType.getPath(),
01550                     LineExtractor.extractLine(node)),
01551             ea);
01552 }
01553 /**
01554  * 
01555  * @param node edu.ksu.cis.bandera.jjjc.node.AExpCastExp
01556  */
01557 public void caseAExpCastExp(AExpCastExp node) {
01558     try {
01559         String t = ((ANameExp) node.getFirst()).getName().toString();
01560         ca.mcgill.sable.soot.Type type =
01561                 Util.convertType(symbolTable.resolveType(new Name(t)));
01562         int dimensions = Util.countArrayDimensions(t);
01563         if (dimensions > 0)
01564             type = ca.mcgill.sable.soot.ArrayType.v((BaseType) type, dimensions);
01565         node.getSecond().apply(this);
01566         Value castedValue = currentValue;
01567         currentValue = null;
01568         Local lcl = declareLocal(nameGen.newName(), type, 0);
01569         currentStmts.addElement(jimple.newAssignStmt(lcl, jimple.newCastExpr(castedValue, type)));
01570         currentValue = lcl;
01571     } catch (CompilerException e) {
01572         exceptions.addElement(e);
01573     }
01574 }
01575 /**
01576  * 
01577  * @param node edu.ksu.cis.bandera.jjjc.node.AExpStmt
01578  */
01579 public void caseAExpStmt(AExpStmt node) {
01580     int start = currentStmts.size();
01581     if(node.getExp() != null) {
01582         node.getExp().apply(this);
01583     }
01584     int end = currentStmts.size();
01585     ExpStmtAnnotation ann = new ExpStmtAnnotation(node);
01586     LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
01587     ann.setFirstLine(lc.getFirstLine());
01588     ann.setFirstColumn(lc.getFirstColumn());
01589     ann.setLastLine(lc.getLastLine());
01590     ann.setLastColumn(lc.getLastColumn());
01591     am.putFilenameLinePairAnnotation(
01592             new FilenameLinePair(currentClassOrInterfaceType.getPath(),
01593                     LineExtractor.extractLine(node)),
01594             ann);
01595     
01596     for (int i = start; i < end; i++) {
01597         ann.addStmt((Stmt) currentStmts.elementAt(i));
01598     }
01599     currentAnnotation.addAnnotation(ann); 
01600 }
01601 /**
01602  * 
01603  * @param node edu.ksu.cis.bandera.jjjc.node.AFalseBooleanLiteral
01604  */
01605 public void caseAFalseBooleanLiteral(AFalseBooleanLiteral node) {
01606     currentValue = IntConstant.v(0);
01607     integralConstantType = edu.ksu.cis.bandera.jjjc.symboltable.BooleanType.TYPE;
01608 }
01609 /**
01610  * 
01611  * @param node edu.ksu.cis.bandera.jjjc.node.AFieldDeclaration
01612  */
01613 public void caseAFieldDeclaration(AFieldDeclaration node) {
01614     try {
01615         fieldNode = node;
01616         
01617         int fieldModifiers = Util.convertModifiers(Util.convertModifiers(node.getModifier().toString()));
01618         if (node.parent() instanceof AConstantDeclarationInterfaceMemberDeclaration) {
01619             fieldModifiers = Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL;
01620         }
01621 
01622         // redirect field initializer to static or instance contstructor body
01623         if (Modifier.isStatic(fieldModifiers)) {
01624             currentLocals = staticLocals;
01625             currentStmts = staticStmts;
01626         } else {
01627             currentLocals = instanceLocals;
01628             currentStmts = instanceStmts;
01629         }
01630         
01631         PVariableDeclarator variableDeclarator;
01632         for (Iterator i = node.getVariableDeclarator().iterator(); i.hasNext();) {
01633             variableDeclarator = (PVariableDeclarator) i.next();
01634             currentType = ca.mcgill.sable.soot.IntType.v();
01635             variableDeclarator.apply(this);
01636         }
01637     } catch (CompilerException e) {
01638         exceptions.addElement(e);
01639     }
01640     currentType = null;
01641 }
01642 /**
01643  * 
01644  * @param node edu.ksu.cis.bandera.jjjc.node.AFloatingPointLiteralLiteral
01645  */
01646 public void caseAFloatingPointLiteralLiteral(AFloatingPointLiteralLiteral node) {
01647     String literal = node.toString().trim();
01648     if (literal.equals("Infinity"))
01649         currentValue = DoubleConstant.v(Double.POSITIVE_INFINITY);
01650     else if (literal.equals("NaN"))
01651         currentValue = DoubleConstant.v(Double.NaN);
01652     else if (literal.endsWith("F") || literal.endsWith("f"))
01653         currentValue = FloatConstant.v(Float.valueOf(literal).floatValue());
01654     else
01655         currentValue = DoubleConstant.v(Double.valueOf(literal).doubleValue());
01656 }
01657 /**
01658  * 
01659  * @param node edu.ksu.cis.bandera.jjjc.node.AFloatPrimitiveType
01660  */
01661 public void caseAFloatPrimitiveType(AFloatPrimitiveType node) {
01662     currentType = ca.mcgill.sable.soot.FloatType.v();
01663 }
01664 /**
01665  * 
01666  * @param node edu.ksu.cis.bandera.jjjc.node.AForStmt
01667  */
01668 public void caseAForStmt(AForStmt node) {
01669     PExp exp = null;
01670     
01671     if (node.getExp() != null) {
01672         exp = new AUnaryExp(new AComplementUnaryOperator(new TComplement()), (PExp) node.getExp().clone());
01673         PushComplement.push(exp);
01674         exp = ((AUnaryExp) exp).getExp();
01675     }
01676     
01677     ForStmtAnnotation ann = new ForStmtAnnotation(node);
01678     LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
01679     ann.setFirstLine(lc.getFirstLine());
01680     ann.setFirstColumn(lc.getFirstColumn());
01681     ann.setLastLine(lc.getLastLine());
01682     ann.setLastColumn(lc.getLastColumn());
01683     
01684     am.putFilenameLinePairAnnotation(
01685             new FilenameLinePair(currentClassOrInterfaceType.getPath(),
01686                     LineExtractor.extractLine(node)),
01687             ann);
01688     BlockStmtAnnotation prevAnnotation = currentAnnotation;
01689 
01690     Object prevLastSynch = lastFinallySynchBeforeControl;
01691     if (synchAnnotations.size() > 0)
01692         lastFinallySynchBeforeControl = (Annotation) synchAnnotations.lastElement();
01693     
01694     Stmt initStmt = jimple.newNopStmt();
01695     Stmt testStmt = jimple.newNopStmt();
01696     Stmt blockStmt = jimple.newNopStmt();
01697     Stmt updateStmt = jimple.newNopStmt();
01698     Stmt endStmt = jimple.newNopStmt();
01699 
01700     symbolTable.enterScope();
01701     labelEnterBlock();
01702     if (node.getForInit() != null) {
01703         forLocals = new Hashtable();
01704         forInitType = null;
01705         forInitModifiers = 0;
01706         currentStmts.addElement(initStmt);
01707 
01708         int start = currentStmts.size();
01709 
01710         currentAnnotation = null;
01711     
01712         node.getForInit().apply(this);
01713 
01714         currentAnnotation = prevAnnotation;
01715         
01716         int end = currentStmts.size();
01717 
01718         SequentialAnnotation sann = new SequentialAnnotation(null);
01719         
01720         for (int i = start; i < end; i++) {
01721             sann.addStmt((Stmt) currentStmts.elementAt(i));
01722         }
01723 
01724         ann.setInitAnnotation(sann);
01725 
01726         for (Enumeration e = forLocals.keys(); e.hasMoreElements();) {
01727             String key = (String) e.nextElement();
01728             ann.addDeclaredLocal(key, (Local) forLocals.get(key));
01729         }
01730         
01731         ann.setType(forInitType);
01732         ann.setModifiers(forInitModifiers);
01733     } else {
01734         initStmt = null;
01735     }
01736 
01737     boolean isIndefiniteLoop = false;
01738     
01739     if (exp != null) {
01740         currentStmts.addElement(testStmt);
01741         Stmt prevTrueBranch = trueBranch;
01742         Stmt prevFalseBranch = falseBranch;
01743         trueBranch = endStmt;
01744         falseBranch = blockStmt;
01745 
01746         int start = currentStmts.size();
01747         
01748         exp.apply(new BooleanExpression(this, trueBranch, falseBranch));
01749         
01750         if (currentStmts.elementAt(currentStmts.size() - 1) instanceof JGotoStmt) isIndefiniteLoop = true;
01751         
01752         int end = currentStmts.size();
01753         
01754         for (int i = start; i < end; i++) {
01755             ann.addStmt((Stmt) currentStmts.elementAt(i));
01756         }
01757         
01758         trueBranch = prevTrueBranch;
01759         falseBranch = prevFalseBranch;
01760     } else {
01761         testStmt = null;
01762         isIndefiniteLoop = true;
01763     }
01764     
01765     currentStmts.addElement(blockStmt);
01766 
01767     currentAnnotation = new BlockStmtAnnotation(node.getBlock());
01768 
01769     Stmt prevBreakTarget = currentBreakTarget;
01770     Stmt prevContinueTarget = currentContinueTarget;
01771     
01772     currentBreakTarget = endStmt;
01773     currentContinueTarget = updateStmt;
01774 
01775     node.getBlock().apply(this);
01776 
01777     ann.setBlockAnnotation(getFirstEnclosedAnnotation(currentAnnotation));
01778     
01779     currentBreakTarget = prevBreakTarget;
01780     currentContinueTarget = prevContinueTarget;
01781     
01782     currentStmts.addElement(updateStmt);
01783     
01784     int start = currentStmts.size();
01785     
01786     for (Iterator i = node.getForUpdate().iterator(); i.hasNext();) {
01787         ((PExp) i.next()).apply(this);
01788     }
01789     
01790     if (testStmt == null)
01791         currentStmts.addElement(jimple.newGotoStmt(blockStmt));
01792     else
01793         currentStmts.addElement(jimple.newGotoStmt(testStmt));
01794         
01795     int end = currentStmts.size();
01796 
01797     SequentialAnnotation sann = new SequentialAnnotation(null);
01798     
01799     for (int i = start; i < end; i++) {
01800         sann.addStmt((Stmt) currentStmts.elementAt(i));
01801     }
01802 
01803     ann.setUpdateAnnotation(sann);
01804     
01805     Stmt backPointStmt = (Stmt) currentStmts.elementAt(currentStmts.size() - 1);
01806     currentStmts.addElement(endStmt);
01807     
01808     symbolTable.exitScope();
01809     labelExitBlock();
01810 
01811     ann.setIndefinite(isIndefiniteLoop);
01812     
01813     currentAnnotation = prevAnnotation;
01814     currentAnnotation.addAnnotation(ann);
01815 
01816     lastFinallySynchBeforeControl = prevLastSynch;
01817 }
01818 /**
01819  * 
01820  * @param node edu.ksu.cis.bandera.jjjc.node.AHexIntegerLiteral
01821  */
01822 public void caseAHexIntegerLiteral(AHexIntegerLiteral node) {
01823     String literal = node.toString().substring(2).trim();
01824     if (literal.endsWith("L") || literal.endsWith("l")) {
01825         currentValue = LongConstant.v(new BigInteger(literal.substring(0, literal.length() - 1), 16).longValue());
01826         integralConstantType = edu.ksu.cis.bandera.jjjc.symboltable.LongType.TYPE;
01827     } else {
01828         currentValue = IntConstant.v(Long.valueOf(literal, 16).intValue());
01829         integralConstantType = edu.ksu.cis.bandera.jjjc.symboltable.IntType.TYPE;
01830     }
01831 }
01832 /**
01833  * 
01834  * @param node edu.ksu.cis.bandera.jjjc.node.AIdVariableDeclarator
01835  */
01836 public void caseAIdVariableDeclarator(AIdVariableDeclarator node) {
01837     try {
01838         node.getVariableDeclaratorId().apply(this);
01839         if (symbolTable.getNumScopeLevels() > 0) {
01840             Local lcl = declareLocal(currentName, currentType, 0);
01841             localAnnotation.addDeclaredLocal(currentName, lcl);
01842         } else {
01843             FieldDeclarationAnnotation ann = new FieldDeclarationAnnotation(fieldNode);
01844             SootField sf = getSootField(currentSootClass.getName(), currentName);
01845             ann.setSootField(sf);
01846             ann.setField(currentClassOrInterfaceType.getField(new Name(currentName)));
01847             am.addAnnotation(currentSootClass, sf, ann);
01848             am.putFilenameLinePairAnnotation(
01849                     new FilenameLinePair(currentClassOrInterfaceType.getPath(),
01850                         LineExtractor.extractLine(node.getVariableDeclaratorId())),
01851                     ann);
01852         }
01853     } catch (CompilerException e) {
01854         exceptions.addElement(e);
01855     }
01856 }
01857 /**
01858  * 
01859  * @param node edu.ksu.cis.bandera.jjjc.node.AIfStmt
01860  */
01861 public void caseAIfStmt(AIfStmt node) {
01862     PExp exp = new AUnaryExp(new AComplementUnaryOperator(new TComplement()), (PExp) node.getExp().clone());
01863     PushComplement.push(exp);
01864     exp = ((AUnaryExp) exp).getExp();
01865     
01866     Stmt thenStmt = jimple.newNopStmt();
01867     Stmt elseStmt = jimple.newNopStmt();
01868     Stmt endStmt = jimple.newNopStmt();
01869 
01870     BlockStmtAnnotation prevAnnotation = currentAnnotation;
01871     IfStmtAnnotation ann = new IfStmtAnnotation(node);
01872     LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
01873     ann.setFirstLine(lc.getFirstLine());
01874     ann.setFirstColumn(lc.getFirstColumn());
01875     ann.setLastLine(lc.getLastLine());
01876     ann.setLastColumn(lc.getLastColumn());
01877     am.putFilenameLinePairAnnotation(
01878             new FilenameLinePair(currentClassOrInterfaceType.getPath(),
01879                     LineExtractor.extractLine(node)),
01880             ann);
01881     
01882     Stmt prevTrueBranch = trueBranch;
01883     Stmt prevFalseBranch = falseBranch;
01884     trueBranch = elseStmt;
01885     falseBranch = thenStmt;
01886 
01887     int start = currentStmts.size();
01888     
01889     exp.apply(new BooleanExpression(this, trueBranch, falseBranch));
01890     
01891     int end = currentStmts.size();
01892     
01893     for (int i = start; i < end; i++) {
01894         ann.addStmt((Stmt) currentStmts.elementAt(i));
01895     }
01896 
01897     currentStmts.addElement(thenStmt);
01898 
01899     currentAnnotation = new BlockStmtAnnotation(node.getBlock());
01900     
01901     node.getThenPart().apply(this);
01902 
01903     SequentialAnnotation sann = new SequentialAnnotation(null);
01904     Stmt gotoStmt = jimple.newGotoStmt(endStmt);
01905     sann.addStmt(gotoStmt);
01906     ann.setAnnotation(sann);
01907     ann.setThenAnnotation(getFirstEnclosedAnnotation(currentAnnotation));
01908     
01909     currentStmts.addElement(gotoStmt);
01910     currentStmts.addElement(elseStmt);
01911 
01912     currentAnnotation = new BlockStmtAnnotation(node.getBlock());
01913 
01914     node.getBlock().apply(this);
01915     
01916     ann.setElseAnnotation(getFirstEnclosedAnnotation(currentAnnotation));
01917     
01918     currentStmts.addElement(endStmt);
01919     
01920     trueBranch = prevTrueBranch;
01921     falseBranch = prevFalseBranch;
01922 
01923     currentAnnotation = prevAnnotation;
01924     currentAnnotation.addAnnotation(ann);
01925 }
01926 /**
01927  * 
01928  * @param node edu.ksu.cis.bandera.jjjc.node.AInitClassInterfaceExp
01929  */
01930 public void caseAInitClassInterfaceExp(AInitClassInterfaceExp node) {
01931     try {
01932         String className = (new Name(node.getClassOrInterfaceType().toString())).toString();
01933         SootClass sc = getSootClass(className);
01934         className = sc.getName();
01935         ca.mcgill.sable.soot.Type type = ca.mcgill.sable.soot.RefType.v(className);
01936         int dimensions = node.getDim().size();
01937         Local lcl = declareLocal(nameGen.newName(), ca.mcgill.sable.soot.ArrayType.v((BaseType) type, dimensions), 0);
01938         currentValue = lcl;
01939         node.getArrayInitializer().apply(this);
01940         currentValue = lcl;
01941     } catch (Exception e) {
01942         exceptions.add(e);
01943     }
01944 }
01945 /**
01946  * 
01947  * @param node edu.ksu.cis.bandera.jjjc.node.AInitPrimitiveExp
01948  */
01949 public void caseAInitPrimitiveExp(AInitPrimitiveExp node) {
01950     node.getPrimitiveType().apply(this);
01951     ca.mcgill.sable.soot.Type primitiveType = currentType;
01952     currentType = null;
01953     int dimensions = node.getDim().size();
01954     Local lcl = declareLocal(nameGen.newName(),
01955             ca.mcgill.sable.soot.ArrayType.v((BaseType) primitiveType, dimensions), 0);
01956     currentValue = lcl;
01957     node.getArrayInitializer().apply(this);
01958     currentValue = lcl;
01959 }
01960 /**
01961  * 
01962  * @param node edu.ksu.cis.bandera.jjjc.node.AInstanceofExp
01963  */
01964 public void caseAInstanceofExp(AInstanceofExp node) {
01965     node.getExp().apply(this);
01966     node.getReferenceType().apply(this);
01967         
01968     Local lcl = declareLocal(nameGen.newName(), ca.mcgill.sable.soot.BooleanType.v(), 0);
01969     currentStmts.addElement(jimple.newAssignStmt(lcl, jimple.newInstanceOfExpr(currentValue, currentType)));
01970 
01971     currentValue = lcl; 
01972 }
01973 /**
01974  * 
01975  * @param node edu.ksu.cis.bandera.jjjc.node.AInterfaceBody
01976  */
01977 public void caseAInterfaceBody(AInterfaceBody node) {
01978     // prepare variables for field processing
01979     currentThisLocal = null;
01980     instanceLocals = null;
01981     currentValue = null;
01982     currentType = null;
01983     currentName = null;
01984     instanceStmts = null;
01985     nameGen = new NameGenerator();
01986     currentLocalNames = new Hashtable();
01987     currentLocalNamesIterator = new Hashtable();
01988     currentLocals = new Hashtable();
01989     currentStmts = new Vector();
01990     staticLocals = currentLocals;
01991     staticStmts = currentStmts;
01992     
01993     LinkedList interfaceMemberDeclList = node.getInterfaceMemberDeclaration();
01994     PInterfaceMemberDeclaration interfaceMemberDecl;
01995     if (interfaceMemberDeclList.size() > 0) {
01996         // process field decls
01997         for (Iterator i = interfaceMemberDeclList.iterator(); i.hasNext();) {
01998             interfaceMemberDecl = (PInterfaceMemberDeclaration) i.next();
01999             if (interfaceMemberDecl instanceof AConstantDeclarationInterfaceMemberDeclaration)
02000                 interfaceMemberDecl.apply(this);
02001         }
02002 
02003         // generate static constructor
02004         if (staticStmts.size() > 0) {
02005             SootMethod sootMethod = new SootMethod("<clinit>", new LinkedList(), ca.mcgill.sable.soot.VoidType.v(), Modifier.PUBLIC | Modifier.STATIC);
02006             currentSootClass.addMethod(sootMethod);
02007             JimpleBody body = (JimpleBody) jimple.newBody(sootMethod);
02008             StmtList stmts = body.getStmtList();
02009             for (Enumeration e = staticLocals.elements(); e.hasMoreElements();) {
02010                 body.addLocal((Local) e.nextElement());
02011             }
02012             for (int i = 0; i < staticStmts.size(); i++) {
02013                 stmts.add(staticStmts.elementAt(i));
02014             }
02015             stmts.add(jimple.newReturnVoidStmt());
02016             sootMethod.storeBody(jimple, body);
02017         }
02018         currentLocals = null;
02019         currentStmts = null;
02020         nameGen = null;
02021         staticLocals = currentLocals;
02022         staticStmts = currentStmts;
02023         instanceLocals = currentLocals;
02024         instanceStmts = currentStmts;
02025 
02026         // process the the rest decls
02027         for (Iterator i = interfaceMemberDeclList.iterator(); i.hasNext();) {
02028             interfaceMemberDecl = (PInterfaceMemberDeclaration) i.next();
02029             if (!(interfaceMemberDecl instanceof AConstantDeclarationInterfaceMemberDeclaration))
02030                 interfaceMemberDecl.apply(this);
02031         }
02032     }
02033     compiledClasses.addElement(currentSootClass.getName());
02034 }
02035 /**
02036  * 
02037  * @param node edu.ksu.cis.bandera.jjjc.node.AInterfaceDeclaration
02038  */
02039 public void caseAInterfaceDeclaration(AInterfaceDeclaration node) {
02040     try {
02041       currentClassOrInterfaceType = symbolTable.getDeclaredType(new Name(node.getId().toString()));
02042         symbolTable.setCurrentClassOrInterfaceType(currentClassOrInterfaceType);
02043         
02044         currentSootClass = getSootClass(currentClassOrInterfaceType.getName().toString());
02045         
02046       ClassDeclarationAnnotation cda = new ClassDeclarationAnnotation(node);
02047         LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
02048         cda.setFirstLine(lc.getFirstLine());
02049         cda.setFirstColumn(lc.getFirstColumn());
02050         cda.setLastLine(lc.getLastLine());
02051         cda.setLastColumn(lc.getLastColumn());
02052       cda.setSootClass(currentSootClass);
02053       am.addAnnotation(cda);
02054         am.putFilenameLinePairAnnotation(new FilenameLinePair(currentClassOrInterfaceType.getPath(),
02055             LineExtractor.extractLine(node)), cda);
02056 
02057         if (node.getInterfaceBody() != null) {
02058           node.getInterfaceBody().apply(this);
02059         }
02060         compiledClasses.addElement(currentSootClass.getName());
02061     } catch (CompilerException e) {
02062       exceptions.addElement(e);
02063     }
02064 
02065     currentClassOrInterfaceType = null;
02066     symbolTable.setCurrentClassOrInterfaceType(null);
02067     currentSootClass = null;
02068 }
02069 /**
02070  * 
02071  * @param node edu.ksu.cis.bandera.jjjc.node.AInterfaceDeclarationClassMemberDeclaration
02072  */
02073 public void caseAInterfaceDeclarationClassMemberDeclaration(AInterfaceDeclarationClassMemberDeclaration node) {
02074     System.out.println("Unsupported feature of Java: " + node);
02075     exceptions.addElement(new CompilerException("Unsupported feature of Java: " + node));
02076     throw new Error("Unsupported feature of Java: " + node);
02077 }
02078 /**
02079  * 
02080  * @param node edu.ksu.cis.bandera.jjjc.node.AInterfaceDeclarationInterfaceMemberDeclaration
02081  */
02082 public void caseAInterfaceDeclarationInterfaceMemberDeclaration(AInterfaceDeclarationInterfaceMemberDeclaration node) {
02083     System.out.println("Unsupported feature of Java: " + node);
02084     exceptions.addElement(new CompilerException("Unsupported feature of Java: " + node));
02085     throw new Error("Unsupported feature of Java: " + node);
02086 }
02087 /**
02088  * 
02089  * @param node edu.ksu.cis.bandera.jjjc.node.AIntPrimitiveType
02090  */
02091 public void caseAIntPrimitiveType(AIntPrimitiveType node) {
02092     currentType = ca.mcgill.sable.soot.IntType.v();
02093 }
02094 /**
02095  * 
02096  * @param node edu.ksu.cis.bandera.jjjc.node.ALabelStmt
02097  */
02098 public void caseALabelStmt(ALabelStmt node) {
02099     LabeledStmtAnnotation ann = new LabeledStmtAnnotation(node);
02100     LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
02101     ann.setFirstLine(lc.getFirstLine());
02102     ann.setFirstColumn(lc.getFirstColumn());
02103     ann.setLastLine(lc.getLastLine());
02104     ann.setLastColumn(lc.getLastColumn());
02105     ann.setId(node.getId().toString().trim());
02106     try {
02107         declareLabel(node.getId().toString().trim());
02108     } catch (CompilerException e) {
02109         exceptions.addElement(e);
02110         return;
02111     }
02112     BlockStmtAnnotation prevAnnotation = currentAnnotation;
02113     currentAnnotation = new BlockStmtAnnotation(node.getBlock());
02114     node.getBlock().apply(this);
02115     ann.setAnnotation(getFirstEnclosedAnnotation(currentAnnotation));
02116     currentAnnotation = prevAnnotation;
02117     currentAnnotation.addAnnotation(ann);
02118 }
02119 /**
02120  * 
02121  * @param node edu.ksu.cis.bandera.jjjc.node.ALocalVariableDeclaration
02122  */
02123 public void caseALocalVariableDeclaration(ALocalVariableDeclaration node) {
02124     // get local var modifiers
02125     try {
02126         localAnnotation = new LocalDeclarationStmtAnnotation(node);
02127         LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
02128         localAnnotation.setFirstLine(lc.getFirstLine());
02129         localAnnotation.setFirstColumn(lc.getFirstColumn());
02130         localAnnotation.setLastLine(lc.getLastLine());
02131         localAnnotation.setLastColumn(lc.getLastColumn());
02132         am.putFilenameLinePairAnnotation(
02133                 new FilenameLinePair(currentClassOrInterfaceType.getPath(),
02134                         LineExtractor.extractLine(node)),
02135                 localAnnotation);
02136         
02137         int start = currentStmts.size();
02138         
02139         int modifiers = Util.convertModifiers(Util.convertModifiers(node.getModifier().toString()));
02140         currentType = null;
02141         node.getType().apply(this);
02142         ca.mcgill.sable.soot.Type localType = currentType;
02143         localAnnotation.setType(localType);
02144         localAnnotation.setModifiers(modifiers);
02145         PVariableDeclarator variableDeclarator;
02146         for (Iterator i = node.getVariableDeclarator().iterator(); i.hasNext();) {
02147             variableDeclarator = (PVariableDeclarator) i.next();
02148             currentType = localType;
02149             variableDeclarator.apply(this);
02150         }
02151         currentType = null;
02152 
02153         if (currentAnnotation != null) {
02154             int end = currentStmts.size();
02155         
02156             for (int i = start; i < end; i++) {
02157                 localAnnotation.addStmt((Stmt) currentStmts.elementAt(i));
02158             }
02159             currentAnnotation.addAnnotation(localAnnotation);
02160         } else {
02161             forInitType = localType;
02162             forInitModifiers = modifiers;
02163         }
02164         localAnnotation = null;
02165     } catch (CompilerException e) {
02166         exceptions.addElement(e);
02167     }
02168 }
02169 /**
02170  * 
02171  * @param node edu.ksu.cis.bandera.jjjc.node.ALongPrimitiveType
02172  */
02173 public void caseALongPrimitiveType(ALongPrimitiveType node) {
02174     currentType = ca.mcgill.sable.soot.LongType.v();
02175 }
02176 /**
02177  * 
02178  * @param node edu.ksu.cis.bandera.jjjc.node.AMethodDeclaration
02179  */
02180 public void caseAMethodDeclaration(AMethodDeclaration node) {
02181     if (CompilationManager.getModifiedMethodTable().get(node) != null) {
02182         ((Node) CompilationManager.getModifiedMethodTable().get(node)).apply(this);
02183         CompilationManager.addDocTriple(new DocTriple(currentSootClass, currentSootMethod, DocProcessor.tags(node, docComments)));
02184         return;
02185     }
02186     methodLine = LineExtractor.extractLine(node);
02187     // prepare variables for method processing
02188     currentSootMethod = null;
02189     nameGen = new NameGenerator();
02190     currentLocalNames = new Hashtable();
02191     currentLocalNamesIterator = new Hashtable();
02192     currentLocals = new Hashtable();
02193     currentStmts = new Vector();
02194     currentValue = null;
02195     currentType = null;
02196     currentName = null;
02197     currentThisLocal = null;
02198     labels = new LinkedList();
02199     currentAnnotation = new MethodDeclarationAnnotation(node);
02200     LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
02201     currentAnnotation.setFirstLine(lc.getFirstLine());
02202     currentAnnotation.setFirstColumn(lc.getFirstColumn());
02203     currentAnnotation.setLastLine(lc.getLastLine());
02204     currentAnnotation.setLastColumn(lc.getLastColumn());
02205 
02206     currentTraps = new Vector();
02207 
02208     // apply method header & body
02209     symbolTable.enterScope();
02210     node.getMethodHeader().apply(this);
02211     node.getMethodBody().apply(this);
02212     symbolTable.exitScope();
02213 
02214     // create the actual body
02215     StmtList stmts = currentBody.getStmtList();
02216     for (Enumeration e = currentLocals.elements(); e.hasMoreElements();) {
02217         currentBody.addLocal((Local) e.nextElement());
02218     }
02219 
02220     for (int i = 0; i < currentStmts.size(); i++) {
02221         stmts.add((Stmt) currentStmts.elementAt(i));
02222     }
02223 
02224     Stmt tempStmt = null;
02225     if (currentStmts.size() > 0) {
02226         int size = currentStmts.size();
02227         Stmt lastStmt = (Stmt) currentStmts.elementAt(--size);
02228         if (!(lastStmt instanceof JReturnStmt) && !(lastStmt instanceof JReturnVoidStmt)
02229                 && !(lastStmt instanceof JThrowStmt)) {
02230             tempStmt = jimple.newReturnVoidStmt();
02231             stmts.add(tempStmt);
02232             SequentialAnnotation ann = new SequentialAnnotation(null);
02233             ann.addStmt(tempStmt);
02234             currentAnnotation.addAnnotation(ann);
02235         }
02236     } else {
02237         SequentialAnnotation ann = new SequentialAnnotation(null);
02238         Stmt stmt = jimple.newReturnVoidStmt();
02239         ann.addStmt(stmt);
02240         stmts.add(stmt);
02241         currentAnnotation.addAnnotation(ann);
02242     }
02243 
02244     for (Enumeration e = currentTraps.elements(); e.hasMoreElements();) {
02245         currentBody.addTrap((Trap) e.nextElement());
02246     }
02247     
02248     am.addAnnotation(currentSootClass, currentSootMethod, currentAnnotation);
02249     
02250     // store body
02251     if (!(currentSootMethod.getReturnType() instanceof ca.mcgill.sable.soot.VoidType)) {
02252         addRetIfNecessary(currentBody, currentSootMethod.getReturnType());
02253     }
02254     convertLocalTypes(currentBody);
02255     TemporaryLocalsReduction.reduce(currentBody, currentAnnotation);
02256     DeadCodeElimination.eliminate(currentBody);
02257     JumpElimination.eliminate(currentBody);
02258     DeadCodeEliminator.eliminateDeadCode(currentBody);
02259     DeadCodeElimination.eliminate(currentBody);
02260     Transformations.removeUnusedLocals(currentBody);
02261     patchBody(currentBody);
02262     //Transformations.cleanupCode(currentBody);
02263 
02264     currentAnnotation.validate(currentBody);
02265     //checkAnnotation(currentAnnotation, currentBody);
02266     currentSootMethod.storeBody(jimple, currentBody);
02267     am.putFilenameLinePairAnnotation(new FilenameLinePair(currentClassOrInterfaceType.getPath(),
02268             LineExtractor.extractLine(node)), currentAnnotation);
02269 
02270     if (!Modifier.isAbstract(currentSootMethod.getModifiers()))
02271         CompilationManager.addDocTriple(new DocTriple(currentSootClass, currentSootMethod, DocProcessor.tags(node, docComments)));
02272     
02273     // cleaning up
02274     nameGen = null;
02275     currentLocals = null;
02276     currentLocalNames = null;
02277     currentLocalNamesIterator = null;
02278     currentStmts = null;
02279     currentValue = null;
02280     currentType = null;
02281     currentName = null;
02282     currentThisLocal = null;
02283     currentBody = null;
02284     labels = null;
02285     currentTraps = null;
02286     currentAnnotation = null;
02287 }
02288 /**
02289  * 
02290  * @param node edu.ksu.cis.bandera.jjjc.node.AMethodDeclarator
02291  */
02292 public void caseAMethodDeclarator(AMethodDeclarator node) {
02293     // get method header information
02294     String methodName = node.getId().toString().trim();
02295 
02296     try {
02297         // process parameter list
02298         Vector formalParameters = new Vector();
02299         for (Iterator i = node.getFormalParameter().iterator(); i.hasNext();) {
02300             ((PFormalParameter) i.next()).apply(this);
02301             formalParameters.addElement(Util.convertType(currentType, symbolTable));
02302             currentType = null;
02303         }
02304     
02305         currentSootMethod = getSootMethod(currentSootClass.getName(), methodName, formalParameters);
02306         ((MethodDeclarationAnnotation) currentAnnotation).setSootMethod(currentSootMethod);
02307         ((MethodDeclarationAnnotation) currentAnnotation).setMethod(currentClassOrInterfaceType.getMethod(new Name(methodName), formalParameters));
02308 
02309         if (!isInterface) {
02310             currentBody = (JimpleBody) jimple.newBody(currentSootMethod);
02311 
02312             int methodModifiers = currentSootMethod.getModifiers();
02313             // make a local for holding this ref if the method is not static, abstract, or native
02314             if (!Modifier.isStatic(methodModifiers) && !Modifier.isAbstract(methodModifiers) && !Modifier.isNative(methodModifiers)) {
02315                 String thisName = nameGen.newName();
02316                 currentThisLocal = declareLocal(thisName, ca.mcgill.sable.soot.RefType.v(currentSootClass.getName()), 0);
02317                 currentLocals.put(currentThisLocal.getName(), currentThisLocal);
02318     
02319                 SequentialAnnotation sann = new SequentialAnnotation(null);
02320                 Stmt stmt = jimple.newIdentityStmt(currentThisLocal, jimple.newThisRef(currentSootClass));
02321                 currentStmts.addElement(stmt);
02322                 sann.addStmt(stmt);
02323                 currentAnnotation.addAnnotation(sann);
02324             }
02325             
02326             // declare parameters variable as locals
02327             if (!Modifier.isAbstract(methodModifiers) && !Modifier.isNative(methodModifiers)) {
02328                 Method m = currentClassOrInterfaceType.getMethod(new Name(methodName), formalParameters);
02329     
02330                 SequentialAnnotation sann = new SequentialAnnotation(null);
02331     
02332                 int paramNum = 0;
02333                 for (Enumeration e = m.getParameters().elements(); e.hasMoreElements(); paramNum++) {
02334                     Variable v = (Variable) e.nextElement();
02335                     Local tempLocal = declareLocal(v.getName().toString(), Util.convertType(v.getType()),
02336                             Util.convertModifiers(v.getModifiers()));
02337                     Stmt stmt = jimple.newIdentityStmt(tempLocal, jimple.newParameterRef(currentSootMethod, paramNum));
02338                     currentStmts.addElement(stmt);
02339                     sann.addStmt(stmt);
02340                 }
02341     
02342                 currentAnnotation.addAnnotation(sann);
02343             }
02344         }
02345     } catch (CompilerException e) {
02346         exceptions.addElement(e);
02347     }   
02348 }
02349 /**
02350  * 
02351  * @param node edu.ksu.cis.bandera.jjjc.node.ANameArrayAccess
02352  */
02353 public void caseANameArrayAccess(ANameArrayAccess node) {
02354     String arrayName = (new Name(node.getName().toString())).toString();
02355     node.getExp().apply(this);
02356     Value index = currentValue;
02357     currentValue = null;
02358     if ((node.parent() instanceof AArrayAccessLeftHandSide) || assignExp) {
02359         nameExp(false, arrayName);
02360         currentValue = jimple.newArrayRef(currentValue, index);
02361     } else {
02362         nameExp(false, arrayName);
02363         currentValue = jimple.newArrayRef(currentValue, index);
02364         Local lcl = declareLocal(nameGen.newName(), currentValue.getType(), 0);
02365         currentStmts.addElement(jimple.newAssignStmt(lcl, currentValue));
02366         currentValue = lcl;
02367     }
02368     assignExp = false;
02369 }
02370 /**
02371  * 
02372  * @param node edu.ksu.cis.bandera.jjjc.node.ANameArrayType
02373  */
02374 public void caseANameArrayType(ANameArrayType node) {
02375     try {
02376         ca.mcgill.sable.soot.BaseType temp =
02377                 ca.mcgill.sable.soot.RefType.v(getSootClass(node.getName().toString().trim()).getName());
02378         currentType = ca.mcgill.sable.soot.ArrayType.v(temp, node.getDim().size());
02379     } catch (CompilerException e) {
02380         exceptions.addElement(e);
02381     }
02382 }
02383 /**
02384  * 
02385  * @param node edu.ksu.cis.bandera.jjjc.node.ANameCastExp
02386  */
02387 public void caseANameCastExp(ANameCastExp node) {
02388     try {
02389         String className = (new Name(node.getName().toString())).toString();
02390         SootClass sc = getSootClass(className);
02391         className = sc.getName();
02392         ca.mcgill.sable.soot.Type type = ca.mcgill.sable.soot.RefType.v(className);
02393         int dimensions = node.getDim().size();
02394         if (dimensions != 0) {
02395             type = ca.mcgill.sable.soot.ArrayType.v((ca.mcgill.sable.soot.BaseType) type, dimensions);
02396         }
02397         node.getExp().apply(this);
02398         Value castedValue = currentValue;
02399         currentValue = null;
02400         Local lcl = declareLocal(nameGen.newName(), type, 0);
02401         currentStmts.addElement(jimple.newAssignStmt(lcl, jimple.newCastExpr(castedValue, type)));
02402         currentValue = lcl;
02403     } catch (CompilerException e) {
02404         exceptions.addElement(e);
02405     }
02406 }
02407 /**
02408  * 
02409  * @param node edu.ksu.cis.bandera.jjjc.node.ANamedTypeExp
02410  */
02411 public void caseANamedTypeExp(ANamedTypeExp node) {
02412     System.out.println("Unsupported feature of Java: " + node);
02413     exceptions.addElement(new CompilerException("Unsupported feature of Java: " + node));
02414     throw new Error("Unsupported feature of Java: " + node);
02415 }
02416 /**
02417  * 
02418  * @param node edu.ksu.cis.bandera.jjjc.node.ANameExp
02419  */
02420 public void caseANameExp(ANameExp node) {
02421     nameExp(node.parent() instanceof ANameLeftHandSide, (new Name(node.getName().toString())).toString());
02422 }
02423 /**
02424  * 
02425  * @param node edu.ksu.cis.bandera.jjjc.node.ANameLeftHandSide
02426  */
02427 public void caseANameLeftHandSide(ANameLeftHandSide node) {
02428     nameExp(true, (new Name(node.getName().toString())).toString());
02429 }
02430 /**
02431  * 
02432  * @param node edu.ksu.cis.bandera.jjjc.node.ANameMethodInvocationExp
02433  */
02434 public void caseANameMethodInvocationExp(ANameMethodInvocationExp node) {
02435     try {
02436         String methodName = (new Name(node.getName().toString())).toString();
02437         LinkedList args = new LinkedList();
02438         currentValue = null;
02439         Vector types = new Vector();
02440         {
02441             Object temp[] = node.getArgumentList().toArray();
02442             for (int i = 0; i < temp.length; i++) {
02443                 ((PExp) temp[i]).apply(this);
02444                 args.addLast(currentValue);
02445                 if (currentValue instanceof IntConstant) {
02446                     types.addElement(integralConstantType);
02447                 } else {
02448                     types.addElement(Util.convertType(currentValue instanceof ConditionExpr ? ca.mcgill.sable.soot.BooleanType.v() : currentValue.getType(), symbolTable));
02449                 }
02450                 currentValue = null;
02451             }
02452         }
02453         methodInvocation(methodName, args, types, false);
02454     } catch (CompilerException e) {
02455         exceptions.addElement(e);
02456     }
02457 }
02458 /**
02459  * 
02460  * @param node edu.ksu.cis.bandera.jjjc.node.ANameReferenceType
02461  */
02462 public void caseANameReferenceType(ANameReferenceType node) {
02463     try {
02464         currentType = ca.mcgill.sable.soot.RefType.v(getSootClass(node.getName().toString().trim()).getName());
02465     } catch (CompilerException e) {
02466         exceptions.addElement(e);
02467     }
02468 }
02469 /**
02470  * 
02471  * @param node edu.ksu.cis.bandera.jjjc.node.ANullLiteral
02472  */
02473 public void caseANullLiteral(ANullLiteral node) {
02474     currentValue = NullConstant.v();
02475 }
02476 /**
02477  * 
02478  * @param node edu.ksu.cis.bandera.jjjc.node.AOctalIntegerLiteral
02479  */
02480 public void caseAOctalIntegerLiteral(AOctalIntegerLiteral node) {
02481     String literal = node.toString().substring(1).trim();
02482     if (literal.endsWith("L") || literal.endsWith("l")) {
02483         currentValue = LongConstant.v(new BigInteger(literal.substring(0, literal.length() - 1), 8).longValue());
02484         integralConstantType = edu.ksu.cis.bandera.jjjc.symboltable.LongType.TYPE;
02485     } else {
02486         currentValue = IntConstant.v(Long.valueOf(literal, 8).intValue());
02487         integralConstantType = edu.ksu.cis.bandera.jjjc.symboltable.IntType.TYPE;
02488     }
02489 }
02490 /**
02491  * 
02492  * @param node edu.ksu.cis.bandera.jjjc.node.APostDecrementExp
02493  */
02494 public void caseAPostDecrementExp(APostDecrementExp node) {
02495     postIncDecExp(node, false);
02496 }
02497 /**
02498  * 
02499  * @param node edu.ksu.cis.bandera.jjjc.node.APostIncrementExp
02500  */
02501 public void caseAPostIncrementExp(APostIncrementExp node) {
02502     postIncDecExp(node, true);
02503 }
02504 /**
02505  * 
02506  * @param node edu.ksu.cis.bandera.jjjc.node.APrimaryFieldAccess
02507  */
02508 public void caseAPrimaryFieldAccess(APrimaryFieldAccess node) {
02509     node.getExp().apply(this);
02510     if (currentValue.getType() instanceof RefType) {
02511         try {
02512             boolean isAssign = assignExp;
02513             assignExp = false;
02514             fieldAccess((node.parent() instanceof AFieldAccessLeftHandSide) || isAssign, currentValue,
02515                     (currentValue == currentThisLocal) ? currentSootClass.getName() : ((RefType) currentValue.getType()).className,
02516                     node.getId().toString().trim());
02517         } catch (CompilerException e) {
02518             exceptions.addElement(e);
02519         }
02520     } else {
02521         if ("length".equals(node.getId().toString().trim())) {
02522             currentValue = jimple.newLengthExpr(currentValue);
02523             Local lcl = declareLocal(nameGen.newName(), currentValue.getType(), 0);
02524             currentStmts.addElement(jimple.newAssignStmt(lcl, currentValue));
02525             currentValue = lcl;
02526         } else {
02527             exceptions.addElement(new CompilerException("Arrays does not have field " + node.getId() + " in expression " + node));
02528             currentValue = IntConstant.v(0);
02529         }
02530     }
02531 }
02532 /**
02533  * 
02534  * @param node edu.ksu.cis.bandera.jjjc.node.APrimaryMethodInvocationExp
02535  */
02536 public void caseAPrimaryMethodInvocationExp(APrimaryMethodInvocationExp node) {
02537     try {
02538         node.getExp().apply(this);
02539         Value caller = currentValue;
02540         currentValue = null;
02541         LinkedList args = new LinkedList();
02542         Vector types = new Vector();
02543         {
02544             Object temp[] = node.getArgumentList().toArray();
02545             for (int i = 0; i < temp.length; i++) {
02546                 ((PExp) temp[i]).apply(this);
02547                 args.addLast(currentValue);
02548                 if (currentValue instanceof IntConstant) {
02549                     types.addElement(integralConstantType);
02550                 } else {
02551                     types.addElement(Util.convertType(currentValue instanceof ConditionExpr ? ca.mcgill.sable.soot.BooleanType.v() : currentValue.getType(), symbolTable));
02552                 }
02553                 currentValue = null;
02554             }
02555         }
02556         String methodName = node.getId().toString().trim();
02557         methodInvoke(caller, ((RefType) caller.getType()).className, methodName, args, types, false);
02558     } catch (CompilerException e) {
02559         exceptions.addElement(e);
02560     }
02561 }
02562 /**
02563  * 
02564  * @param node edu.ksu.cis.bandera.jjjc.node.APrimaryNoNewArrayArrayAccess
02565  */
02566 public void caseAPrimaryNoNewArrayArrayAccess(APrimaryNoNewArrayArrayAccess node) {
02567     node.getFirst().apply(this);
02568     Value first = currentValue;
02569     currentValue = null;
02570     node.getSecond().apply(this);
02571     if (node.parent() instanceof AArrayAccessLeftHandSide){
02572         currentValue = jimple.newArrayRef(first, currentValue);
02573     } else {
02574         currentValue = jimple.newArrayRef(first, currentValue);
02575         Local lcl = declareLocal(nameGen.newName(), currentValue.getType(), 0);
02576         currentStmts.addElement(jimple.newAssignStmt(lcl, currentValue));
02577         currentValue = lcl;
02578     }
02579 }
02580 /**
02581  * 
02582  * @param node edu.ksu.cis.bandera.jjjc.node.APrimitiveArrayType
02583  */
02584 public void caseAPrimitiveArrayType(APrimitiveArrayType node) {
02585     node.getPrimitiveType().apply(this);
02586     
02587     ca.mcgill.sable.soot.BaseType temp = (ca.mcgill.sable.soot.BaseType) currentType;
02588     currentType = ca.mcgill.sable.soot.ArrayType.v(temp, node.getDim().size());
02589 }
02590 /**
02591  * 
02592  * @param node edu.ksu.cis.bandera.jjjc.node.APrimitiveTypeArrayExp
02593  */
02594 public void caseAPrimitiveTypeArrayExp(APrimitiveTypeArrayExp node) {
02595     node.getPrimitiveType().apply(this);
02596     ca.mcgill.sable.soot.Type primitiveType = currentType;
02597     currentType = null;
02598     LinkedList arrayExps = new LinkedList();
02599     int dimensions = 0;
02600     for (Iterator i = node.getDimExp().iterator(); i.hasNext();) {
02601         ((PDimExp) i.next()).apply(this);
02602         arrayExps.addLast(currentValue);
02603         currentValue = null;
02604         dimensions++;
02605     }
02606     dimensions += node.getDim().size();
02607     if (dimensions == 1) {
02608         currentValue = jimple.newNewArrayExpr(primitiveType, (Value) arrayExps.removeFirst());
02609     } else {
02610         currentType = ca.mcgill.sable.soot.ArrayType.v((ca.mcgill.sable.soot.BaseType) primitiveType, dimensions);
02611         currentValue = jimple.newNewMultiArrayExpr((ca.mcgill.sable.soot.ArrayType) currentType, arrayExps);
02612         currentType = null;
02613     }
02614     Value newValue = currentValue;
02615     currentValue = null;
02616     Local lcl = declareLocal(nameGen.newName(), newValue.getType(), 0);
02617     currentStmts.addElement(jimple.newAssignStmt(lcl, newValue));
02618     currentValue = lcl;
02619     currentType = lcl.getType();
02620 }
02621 /**
02622  * 
02623  * @param node edu.ksu.cis.bandera.jjjc.node.APrimitiveTypeCastExp
02624  */
02625 public void caseAPrimitiveTypeCastExp(APrimitiveTypeCastExp node) {
02626     node.getPrimitiveType().apply(this);
02627     int dimensions = node.getDim().size();
02628     if (dimensions != 0) {
02629         currentType = ca.mcgill.sable.soot.ArrayType.v((ca.mcgill.sable.soot.BaseType) currentType, dimensions);
02630     }
02631     node.getExp().apply(this);
02632     Local lcl = declareLocal(nameGen.newName(), currentType, 0);
02633     currentStmts.addElement(jimple.newAssignStmt(lcl, jimple.newCastExpr(currentValue, currentType)));
02634     currentValue = lcl;
02635 }
02636 /**
02637  * 
02638  * @param node edu.ksu.cis.bandera.jjjc.node.APrimitiveTypePrimaryExp
02639  */
02640 public void caseAPrimitiveTypePrimaryExp(APrimitiveTypePrimaryExp node) {
02641     System.out.println("Unsupported feature of Java: " + node);
02642     exceptions.addElement(new CompilerException("Unsupported feature of Java: " + node));
02643     throw new Error("Unsupported feature of Java: " + node);
02644 }
02645 /**
02646  * 
02647  * @param node edu.ksu.cis.bandera.jjjc.node.AQualifiedClassInstanceCreationExp
02648  */
02649 public void caseAQualifiedClassInstanceCreationExp(AQualifiedClassInstanceCreationExp node) {
02650     System.out.println("Unsupported feature of Java: " + node);
02651     exceptions.addElement(new CompilerException("Unsupported feature of Java: " + node));
02652     throw new Error("Unsupported feature of Java: " + node);
02653 }
02654 /**
02655  * 
02656  * @param node edu.ksu.cis.bandera.jjjc.node.AQualifiedConstructorInvocation
02657  */
02658 public void caseAQualifiedConstructorInvocation(AQualifiedConstructorInvocation node) {
02659     System.out.println("Unsupported feature of Java: " + node);
02660     exceptions.addElement(new CompilerException("Unsupported feature of Java: " + node));
02661     throw new Error("Unsupported feature of Java: " + node);
02662 }
02663 /**
02664  * 
02665  * @param node edu.ksu.cis.bandera.jjjc.node.AQualifiedThisExp
02666  */
02667 public void caseAQualifiedThisExp(AQualifiedThisExp node) {
02668     System.out.println("Unsupported feature of Java: " + node);
02669     exceptions.addElement(new CompilerException("Unsupported feature of Java: " + node));
02670     throw new Error("Unsupported feature of Java: " + node);
02671 }
02672 /**
02673  * 
02674  * @param node edu.ksu.cis.bandera.jjjc.node.AQuestionExp
02675  */
02676 public void caseAQuestionExp(AQuestionExp node) {
02677     Stmt thenStmt = jimple.newNopStmt();
02678     Stmt elseStmt = jimple.newNopStmt();
02679     Stmt endStmt = jimple.newNopStmt();
02680     Stmt prevTrueBranch = trueBranch;
02681     Stmt prevFalseBranch = falseBranch;
02682     trueBranch = elseStmt;
02683     falseBranch = thenStmt;
02684     Node n = new AUnaryExp(new AComplementUnaryOperator(new TComplement()), (PExp) node.getFirst().clone());
02685     PushComplement.push(n);
02686     n = ((AUnaryExp) n).getExp();
02687     n.apply(new BooleanExpression(this, trueBranch, falseBranch));
02688     currentStmts.addElement(thenStmt);
02689     trueBranch = falseBranch = null;
02690     node.getSecond().apply(this);
02691     boolean nullConstant = currentValue.getType() instanceof ca.mcgill.sable.soot.NullType;
02692     Local lcl = declareLocal(nameGen.newName(), currentValue.getType(), 0);
02693     currentStmts.addElement(jimple.newAssignStmt(lcl, currentValue));
02694     currentStmts.addElement(jimple.newGotoStmt(endStmt));
02695     currentStmts.addElement(elseStmt);
02696     node.getThird().apply(this);
02697     if (!(currentValue.getType() instanceof ca.mcgill.sable.soot.NullType) && nullConstant) {
02698         lcl.setType(currentValue.getType());
02699     }
02700     currentStmts.addElement(jimple.newAssignStmt(lcl, currentValue));
02701     currentStmts.addElement(endStmt);
02702     currentValue = lcl;
02703     
02704     trueBranch = prevTrueBranch;
02705     falseBranch = prevFalseBranch;
02706 }
02707 /**
02708  * 
02709  * @param node edu.ksu.cis.bandera.jjjc.node.AReturnStmt
02710  */
02711 public void caseAReturnStmt(AReturnStmt node) {
02712     int start = currentStmts.size();
02713 
02714     if (node.getExp() == null) {
02715         if (!(currentSootMethod.getReturnType() instanceof ca.mcgill.sable.soot.VoidType))
02716             exceptions.addElement(new CompilerException("Method " + currentSootMethod.getName() + " should return a value"));
02717         for (Enumeration e = synchAnnotations.elements(); e.hasMoreElements();) {
02718             SynchronizedStmtAnnotation sann = (SynchronizedStmtAnnotation) e.nextElement();
02719             Stmt exitMon = jimple.newExitMonitorStmt(sann.getLockValue());
02720             sann.addExitMonitor(exitMon);
02721           currentStmts.addElement(exitMon);
02722         }
02723         currentStmts.addElement(jimple.newReturnVoidStmt());
02724     } else {
02725         node.getExp().apply(this);
02726         boolean f = true;
02727         if (currentValue instanceof Local) {
02728             f = !"$ret".equals(((Local) currentValue).getName().trim());
02729         }
02730         if (f) {
02731             Value exp = currentValue;
02732             currentValue = null;
02733             Local lcl = declareLocal("$ret", exp.getType(), 0);
02734             currentStmts.addElement(jimple.newAssignStmt(lcl, exp));
02735             currentValue = lcl;
02736         }
02737         for (Enumeration e = synchAnnotations.elements(); e.hasMoreElements();) {
02738             SynchronizedStmtAnnotation sann = (SynchronizedStmtAnnotation) e.nextElement();
02739             Stmt exitMon = jimple.newExitMonitorStmt(sann.getLockValue());
02740             sann.addExitMonitor(exitMon);
02741           currentStmts.addElement(exitMon);
02742         }
02743         currentStmts.addElement(jimple.newReturnStmt(currentValue));
02744     }
02745     
02746     int end = currentStmts.size();
02747     ReturnStmtAnnotation ann = new ReturnStmtAnnotation(node);
02748     LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
02749     ann.setFirstLine(lc.getFirstLine());
02750     ann.setFirstColumn(lc.getFirstColumn());
02751     ann.setLastLine(lc.getLastLine());
02752     ann.setLastColumn(lc.getLastColumn());
02753     am.putFilenameLinePairAnnotation(
02754             new FilenameLinePair(currentClassOrInterfaceType.getPath(),
02755                     LineExtractor.extractLine(node)),
02756             ann);
02757     
02758     for (int i = start; i < end; i++) {
02759         ann.addStmt((Stmt) currentStmts.elementAt(i));
02760     }
02761     currentAnnotation.addAnnotation(ann); 
02762 }
02763 /**
02764  * 
02765  * @param node edu.ksu.cis.bandera.jjjc.node.AShortPrimitiveType
02766  */
02767 public void caseAShortPrimitiveType(AShortPrimitiveType node) {
02768     currentType = ca.mcgill.sable.soot.ShortType.v();
02769 }
02770 /**
02771  * 
02772  * @param node edu.ksu.cis.bandera.jjjc.node.ASimpleClassInstanceCreationExp
02773  */
02774 public void caseASimpleClassInstanceCreationExp(ASimpleClassInstanceCreationExp node) {
02775     try {
02776         SootClass sc = getSootClass((new Name(node.getName().toString())).toString());
02777         String className = sc.getName();
02778         Local lcl = declareLocal(nameGen.newName(), ca.mcgill.sable.soot.RefType.v(className), 0);
02779         currentStmts.addElement(jimple.newAssignStmt(lcl, jimple.newNewExpr(ca.mcgill.sable.soot.RefType.v(className))));
02780         currentValue = null;
02781         LinkedList args = new LinkedList();
02782         Vector argTypes = new Vector();
02783         {
02784             Object temp[] = node.getArgumentList().toArray();
02785             for (int i = 0; i < temp.length; i++) {
02786                 ((PExp) temp[i]).apply(this);
02787                 args.addLast(currentValue);
02788                 if (currentValue instanceof IntConstant) {
02789                     argTypes.addElement(integralConstantType);
02790                 } else {
02791                     argTypes.addElement(Util.convertType(currentValue.getType(), symbolTable));
02792                 }
02793                 currentValue = null;
02794             }
02795         }
02796         SootMethod sm = getSootMethod(className, "<init>", argTypes);
02797         currentStmts.addElement(jimple.newInvokeStmt(jimple.newSpecialInvokeExpr(lcl, sm, args)));
02798 
02799         for (java.util.Iterator i = CompilationManager.getQuantifiers().iterator(); i.hasNext();) {
02800             // inline available
02801             QuantifiedVariable q = (QuantifiedVariable) i.next();
02802             if (q.isExact()) {
02803                 if (q.getType().toString().equals(sc.getName())) {
02804                     inlineAvailable(q, lcl);
02805                 }
02806             } else {
02807                 if (isSubtypeOf(className, q.getType().toString())) {
02808                     inlineAvailable(q, lcl);
02809                 }
02810             }
02811         }
02812         
02813         currentValue = lcl;
02814     } catch (CompilerException e) {
02815         exceptions.addElement(e);
02816     }
02817 }
02818 /**
02819  * 
02820  * @param node edu.ksu.cis.bandera.jjjc.node.AStaticInitializerClassBodyDeclaration
02821  */
02822 public void caseAStaticInitializerClassBodyDeclaration(AStaticInitializerClassBodyDeclaration node) {
02823     if (clinit == null) {
02824         clinit = new SootMethod("<clinit>", new LinkedList(), ca.mcgill.sable.soot.VoidType.v(),
02825                 Modifier.PUBLIC | Modifier.STATIC);
02826         clinitBody = (JimpleBody) jimple.newBody(clinit);
02827     }
02828     
02829     currentSootMethod = clinit;
02830     currentBody = clinitBody;
02831     currentLocalNames = new Hashtable();
02832     currentLocalNamesIterator = new Hashtable();
02833     currentLocals = staticLocals;
02834     currentStmts = staticStmts;
02835     currentValue = null;
02836     currentType = null;
02837     currentName = null;
02838     labels = new LinkedList();
02839     currentAnnotation = new StaticInitializerAnnotation(node);
02840     LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
02841     currentAnnotation.setFirstLine(lc.getFirstLine());
02842     currentAnnotation.setFirstColumn(lc.getFirstColumn());
02843     currentAnnotation.setLastLine(lc.getLastLine());
02844     currentAnnotation.setLastColumn(lc.getLastColumn());
02845     currentTraps = new Vector();
02846 
02847     node.getBlock().apply(this);
02848 
02849     for (Enumeration e = currentTraps.elements(); e.hasMoreElements();) {
02850         clinitBody.addTrap((JTrap) e.nextElement());
02851     }
02852     
02853     currentLocals = null;
02854     currentLocalNames = null;
02855     currentLocalNamesIterator = null;
02856     currentStmts = null;
02857     currentValue = null;
02858     currentType = null;
02859     currentName = null;
02860     currentBody = null;
02861     labels = null;
02862     currentTraps = null;
02863     currentSootMethod = null;
02864 
02865     am.addAnnotation(currentSootClass, "static initializer " + staticInitializers++, currentAnnotation);
02866     currentAnnotation = null;
02867 }
02868 /**
02869  * 
02870  * @param node edu.ksu.cis.bandera.jjjc.node.AStringLiteralLiteral
02871  */
02872 public void caseAStringLiteralLiteral(AStringLiteralLiteral node) {
02873     currentValue = StringConstant.v(Util.decodeString(node.toString().trim()));
02874 }
02875 /**
02876  * 
02877  * @param node edu.ksu.cis.bandera.jjjc.node.ASuperConstructorInvocation
02878  */
02879 public void caseASuperConstructorInvocation(ASuperConstructorInvocation node) {
02880     SuperConstructorInvocationStmtAnnotation ann = new SuperConstructorInvocationStmtAnnotation(node);
02881     LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
02882     ann.setFirstLine(lc.getFirstLine());
02883     ann.setFirstColumn(lc.getFirstColumn());
02884     ann.setLastLine(lc.getLastLine());
02885     ann.setLastColumn(lc.getLastColumn());
02886     try {
02887         LinkedList args = new LinkedList();
02888         Vector types = new Vector();
02889         currentValue = null;
02890         for (Iterator i = node.getArgumentList().iterator(); i.hasNext();) {
02891             ((PExp) i.next()).apply(this);
02892             args.addLast(currentValue);
02893             if (currentValue instanceof IntConstant)
02894                 types.addElement(integralConstantType);
02895             else
02896                 types.addElement(Util.convertType(currentValue instanceof ConditionExpr ? ca.mcgill.sable.soot.BooleanType.v() : currentValue.getType(), symbolTable));
02897             currentValue = null;
02898         }
02899         SootMethod sm = getSootMethod(currentSootClass.getSuperClass().getName(), "<init>", types);
02900         Stmt stmt = jimple.newInvokeStmt(jimple.newSpecialInvokeExpr(currentThisLocal, sm, args));
02901         currentStmts.addElement(stmt);
02902         ann.addStmt(stmt);
02903     } catch (CompilerException e) {
02904         exceptions.addElement(e);
02905     }
02906     currentAnnotation.addAnnotation(ann);
02907 }
02908 /**
02909  * 
02910  * @param node edu.ksu.cis.bandera.jjjc.node.ASuperFieldAccess
02911  */
02912 public void caseASuperFieldAccess(ASuperFieldAccess node) {
02913     try {
02914         fieldAccess(node.parent() instanceof AFieldAccessLeftHandSide, currentThisLocal,
02915             currentSootClass.getSuperClass().getName(), node.getId().toString().trim());
02916     } catch (CompilerException e) {
02917         exceptions.addElement(e);
02918     }
02919 }
02920 /**
02921  * 
02922  * @param node edu.ksu.cis.bandera.jjjc.node.ASuperMethodInvocationExp
02923  */
02924 public void caseASuperMethodInvocationExp(ASuperMethodInvocationExp node) {
02925     try {
02926         String methodName = node.getId().toString().trim();
02927         String className = currentSootClass.getSuperClass().getName();
02928         Value caller = currentThisLocal;
02929         currentValue = null;
02930         LinkedList args = new LinkedList();
02931         Object temp[] = node.getArgumentList().toArray();
02932         Vector types = new Vector();
02933         for (int i = 0; i < temp.length; i++) {
02934             ((PExp) temp[i]).apply(this);
02935             args.addLast(currentValue);
02936             if (currentValue instanceof IntConstant) {
02937                 types.addElement(integralConstantType);
02938             } else {
02939                 types.addElement(Util.convertType(currentValue instanceof ConditionExpr ? ca.mcgill.sable.soot.BooleanType.v() : currentValue.getType(), symbolTable));
02940             }
02941         }
02942         currentValue = null;
02943         methodInvoke(caller, className, methodName, args, types, true);
02944     } catch (CompilerException e) {
02945         exceptions.addElement(e);
02946     }
02947 }
02948 /**
02949  * 
02950  * @param node edu.ksu.cis.bandera.jjjc.node.ASwitchStmt
02951  */
02952 public void caseASwitchStmt(ASwitchStmt node) {
02953     LinkedList prevLookupValues = currentLookupValues;
02954     LinkedList prevTargets = currentTargets;
02955     Stmt prevDefaultStmt = currentDefaultStmt;
02956     boolean prevDefaultSwitch = defaultSwitch;
02957     
02958     SwitchStmtAnnotation ann = new SwitchStmtAnnotation(node);
02959     LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
02960     ann.setFirstLine(lc.getFirstLine());
02961     ann.setFirstColumn(lc.getFirstColumn());
02962     ann.setLastLine(lc.getLastLine());
02963     ann.setLastColumn(lc.getLastColumn());
02964     am.putFilenameLinePairAnnotation(
02965             new FilenameLinePair(currentClassOrInterfaceType.getPath(),
02966                     LineExtractor.extractLine(node)),
02967             ann);
02968     BlockStmtAnnotation prevAnnotation = currentAnnotation;
02969         
02970     Stmt startStmt = jimple.newNopStmt();
02971     Stmt endStmt = jimple.newNopStmt();
02972     currentTargets = new LinkedList();
02973     currentDefaultStmt = endStmt;
02974     Stmt prevBreakTarget = currentBreakTarget;
02975     Stmt prevContinueTarget = currentContinueTarget;
02976     currentBreakTarget = endStmt;
02977     currentContinueTarget = endStmt;
02978     currentStmts.addElement(startStmt);
02979 
02980 
02981     int start = currentStmts.size();
02982     
02983     node.getExp().apply(this);
02984 
02985     int end = currentStmts.size();
02986     
02987     for (int i = start; i < end; i++) {
02988         ann.addStmt((Stmt) currentStmts.elementAt(i));
02989     }
02990     
02991     Value switchValue = currentValue;
02992     currentValue = null;
02993     Vector tempStmts;
02994     LinkedList casesStmts = new LinkedList();
02995 
02996     currentLookupValues = new LinkedList();
02997     
02998     for (Iterator i = node.getSwitchBlockStmtGroup().iterator(); i.hasNext();) {
02999         defaultSwitch = false;
03000         ASwitchBlockStmtGroup switchBlockStmtGroup = (ASwitchBlockStmtGroup) i.next();
03001         tempStmts = currentStmts;
03002         currentStmts = new Vector();
03003 
03004         currentAnnotation = new BlockStmtAnnotation(switchBlockStmtGroup);
03005         
03006         for (Iterator j = switchBlockStmtGroup.getBlockedStmt().iterator(); j.hasNext();) {
03007             ((PBlockedStmt) j.next()).apply(this);
03008         }
03009         
03010         Stmt caseStmt = jimple.newNopStmt();
03011         casesStmts.addLast(caseStmt);
03012         for (int k = 0; k < currentStmts.size(); k++) {
03013             casesStmts.addLast(currentStmts.elementAt(k));
03014         }
03015         currentStmts = tempStmts;
03016 
03017         for (Iterator j = switchBlockStmtGroup.getSwitchLabel().iterator(); j.hasNext();) {
03018             boolean tempDefault = defaultSwitch;
03019             
03020             ((PSwitchLabel) j.next()).apply(this);
03021             
03022             if (tempDefault == defaultSwitch) {
03023                 currentTargets.addLast(caseStmt);
03024                 ann.addSwitchCase((Integer) currentLookupValues.getLast(), currentAnnotation);
03025             } else {
03026                 currentDefaultStmt = caseStmt;
03027                 ann.setDefaultAnnotation(currentAnnotation);
03028             }
03029         }
03030     }
03031     Stmt caseStmt = endStmt;
03032     for (Iterator i = node.getSwitchLabel().iterator(); i.hasNext();) {
03033         boolean tempDefault = defaultSwitch;
03034         ((PSwitchLabel) i.next()).apply(this);
03035         if (tempDefault == defaultSwitch)
03036             currentTargets.addLast(caseStmt);
03037         else {
03038             currentDefaultStmt = caseStmt;
03039         }
03040     }
03041 
03042     Stmt stmt = jimple.newLookupSwitchStmt(switchValue, currentLookupValues, currentTargets, currentDefaultStmt);
03043     currentStmts.addElement(stmt);
03044     ann.addStmt(stmt);
03045     
03046     currentLookupValues = null;
03047     currentTargets = null;
03048     currentDefaultStmt = null;
03049     defaultSwitch = false;
03050     for (Iterator i = casesStmts.iterator(); i.hasNext();) {
03051         currentStmts.addElement(i.next());
03052     }
03053     currentStmts.addElement(endStmt);
03054     currentValue = null;
03055     currentBreakTarget = prevBreakTarget;
03056     currentContinueTarget = prevContinueTarget;
03057 
03058     currentAnnotation = prevAnnotation;
03059     currentAnnotation.addAnnotation(ann);
03060     
03061     currentLookupValues = prevLookupValues;
03062     currentTargets = prevTargets;
03063     currentDefaultStmt = prevDefaultStmt;
03064     defaultSwitch = prevDefaultSwitch;
03065 }
03066 /**
03067  * 
03068  * @param node edu.ksu.cis.bandera.jjjc.node.ASynchronizedModifier
03069  */
03070 public void caseASynchronizedModifier(ASynchronizedModifier node) {
03071     node.getSynchronized();
03072 }
03073 /**
03074  * 
03075  * @param node edu.ksu.cis.bandera.jjjc.node.ASynchronizedStmt
03076  */
03077 public void caseASynchronizedStmt(ASynchronizedStmt node) {
03078     try {
03079         SynchronizedStmtAnnotation ann = new SynchronizedStmtAnnotation(node);
03080         LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
03081         ann.setFirstLine(lc.getFirstLine());
03082         ann.setFirstColumn(lc.getFirstColumn());
03083         ann.setLastLine(lc.getLastLine());
03084         ann.setLastColumn(lc.getLastColumn());
03085         int ln = LineExtractor.extractLine(node);
03086         if (ln <= 0) ln = methodLine;
03087         am.putFilenameLinePairAnnotation(
03088                 new FilenameLinePair(currentClassOrInterfaceType.getPath(),
03089                         ln),
03090                 ann);
03091         
03092         Stmt beginStmt = jimple.newNopStmt();
03093         Stmt stmt1 = jimple.newNopStmt();
03094         Stmt stmt2 = jimple.newNopStmt();
03095         Stmt endStmt = jimple.newNopStmt();
03096         Stmt gotoStmt = jimple.newGotoStmt(endStmt);
03097         currentStmts.addElement(beginStmt);
03098 
03099         int start = currentStmts.size();
03100         if (node.getExp() != null)
03101             node.getExp().apply(this);
03102             
03103         Value lockValue = currentValue;
03104 
03105         ann.setLockValue(lockValue);
03106 
03107         Stmt enterMonitor = jimple.newEnterMonitorStmt(lockValue);
03108         Stmt exitMonitor = jimple.newExitMonitorStmt(lockValue);
03109         
03110         ann.setEnterMonitor(enterMonitor);
03111         ann.addExitMonitor(exitMonitor);
03112         
03113         synchAnnotations.insertElementAt(ann, 0);
03114         finallyAndSynch.insertElementAt(ann, 0);
03115         
03116         currentValue = null;
03117         currentStmts.addElement(enterMonitor);
03118         int end = currentStmts.size();
03119     
03120         for (int i = start; i < end; i++) {
03121             ann.addStmt((Stmt) currentStmts.elementAt(i));
03122         }
03123         
03124         currentStmts.addElement(stmt1);
03125         
03126         if (node.getBlock() != null) {
03127             BlockStmtAnnotation prevAnnotation = currentAnnotation;
03128             currentAnnotation = new BlockStmtAnnotation(node.getBlock());
03129             
03130             node.getBlock().apply(this);
03131 
03132             ann.setBlockAnnotation(currentAnnotation);
03133             currentAnnotation = prevAnnotation;
03134         } else {
03135             ann.setBlockAnnotation(new BlockStmtAnnotation(null));
03136         }
03137 
03138         Stmt lastStmt = (Stmt) currentStmts.lastElement();
03139 
03140         boolean f = false;
03141         if ((lastStmt instanceof ReturnStmt) || (lastStmt instanceof ReturnVoidStmt)
03142                 || (lastStmt instanceof ThrowStmt) || (lastStmt instanceof GotoStmt)) {
03143             f = true;
03144             stmt2 = lastStmt;
03145         } else {
03146             currentStmts.addElement(stmt2);
03147             SequentialAnnotation seqann = new SequentialAnnotation(null);
03148             seqann.addStmt(exitMonitor);
03149             seqann.addStmt(gotoStmt);
03150             ((BlockStmtAnnotation) ann.getBlockAnnotation()).addAnnotation(seqann);
03151         
03152             currentStmts.addElement(exitMonitor);
03153             currentStmts.addElement(gotoStmt);
03154         }
03155 
03156 
03157         start = currentStmts.size();
03158         
03159         SootClass sc = getSootClass("java.lang.Throwable");
03160         Local lcl = declareLocal(nameGen.newName(), ca.mcgill.sable.soot.RefType.v("java.lang.Throwable"), 0);
03161         Stmt stmt3 = jimple.newIdentityStmt(lcl, jimple.newCaughtExceptionRef(currentBody));
03162         currentStmts.addElement(stmt3);
03163         
03164         for (Enumeration e = synchAnnotations.elements(); e.hasMoreElements();) {
03165             SynchronizedStmtAnnotation sann = (SynchronizedStmtAnnotation) e.nextElement();
03166             Stmt exitMon = jimple.newExitMonitorStmt(sann.getLockValue());
03167             if (sann != ann)    sann.addExitMonitor(exitMon);
03168           currentStmts.addElement(exitMon);
03169         }
03170         
03171         Stmt stmt4 = jimple.newThrowStmt(lcl);
03172         currentStmts.addElement(stmt4);
03173         
03174         end = currentStmts.size();
03175 
03176         SequentialAnnotation sann = new SequentialAnnotation(null);
03177     
03178         for (int i = start; i < end; i++) {
03179             sann.addStmt((Stmt) currentStmts.elementAt(i));
03180         }
03181 
03182         ann.setCatchAnnotation(sann);
03183 
03184         if (!f)
03185             currentStmts.addElement(endStmt);
03186         
03187         currentBody.addTrap(jimple.newTrap(sc, stmt1, stmt2, stmt3));
03188 
03189         synchAnnotations.removeElementAt(0);
03190         finallyAndSynch.removeElementAt(0);
03191         
03192         currentAnnotation.addAnnotation(ann);
03193     } catch (CompilerException e) {
03194         exceptions.addElement(e);
03195     }
03196 }
03197 /**
03198  * 
03199  * @param node edu.ksu.cis.bandera.jjjc.node.AThisConstructorInvocation
03200  */
03201 public void caseAThisConstructorInvocation(AThisConstructorInvocation node) {
03202     ThisConstructorInvocationStmtAnnotation ann = new ThisConstructorInvocationStmtAnnotation(node);
03203     LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
03204     ann.setFirstLine(lc.getFirstLine());
03205     ann.setFirstColumn(lc.getFirstColumn());
03206     ann.setLastLine(lc.getLastLine());
03207     ann.setLastColumn(lc.getLastColumn());
03208     try {
03209         LinkedList args = new LinkedList();
03210         Vector types = new Vector();
03211         currentValue = null;
03212         for (Iterator i = node.getArgumentList().iterator(); i.hasNext();) {
03213             ((PExp) i.next()).apply(this);
03214             args.addLast(currentValue);
03215             if (currentValue instanceof IntConstant)
03216                 types.addElement(integralConstantType);
03217             else
03218                 types.addElement(Util.convertType(currentValue instanceof ConditionExpr ? ca.mcgill.sable.soot.BooleanType.v() : currentValue.getType(), symbolTable));
03219             currentValue = null;
03220         }
03221         SootMethod sm = getSootMethod(currentSootClass.getName(), "<init>", types);
03222         Stmt stmt = jimple.newInvokeStmt(jimple.newSpecialInvokeExpr(currentThisLocal, sm, args));
03223         currentStmts.addElement(stmt);
03224         ann.addStmt(stmt);
03225     } catch (CompilerException e) {
03226         exceptions.addElement(e);
03227     }
03228     currentAnnotation.addAnnotation(ann);
03229 }
03230 /**
03231  * 
03232  * @param node edu.ksu.cis.bandera.jjjc.node.AThisExp
03233  */
03234 public void caseAThisExp(AThisExp node) {
03235     currentValue = currentThisLocal;
03236 }
03237 /**
03238  * 
03239  * @param node edu.ksu.cis.bandera.jjjc.node.AThrowStmt
03240  */
03241 public void caseAThrowStmt(AThrowStmt node) {
03242     int start = currentStmts.size();
03243 
03244     for (Enumeration e = synchAnnotations.elements(); e.hasMoreElements();) {
03245         SynchronizedStmtAnnotation sann = (SynchronizedStmtAnnotation) e.nextElement();
03246         Stmt exitMon = jimple.newExitMonitorStmt(sann.getLockValue());
03247         sann.addExitMonitor(exitMon);
03248       currentStmts.addElement(exitMon);
03249     }
03250     
03251     node.getExp().apply(this);
03252     currentStmts.addElement(jimple.newThrowStmt(currentValue));
03253     currentValue = null;
03254     
03255     int end = currentStmts.size();
03256     ThrowStmtAnnotation ann = new ThrowStmtAnnotation(node);
03257     LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
03258     ann.setFirstLine(lc.getFirstLine());
03259     ann.setFirstColumn(lc.getFirstColumn());
03260     ann.setLastLine(lc.getLastLine());
03261     ann.setLastColumn(lc.getLastColumn());
03262     am.putFilenameLinePairAnnotation(
03263             new FilenameLinePair(currentClassOrInterfaceType.getPath(),
03264                     LineExtractor.extractLine(node)),
03265             ann);
03266     
03267     for (int i = start; i < end; i++) {
03268         ann.addStmt((Stmt) currentStmts.elementAt(i));
03269     }
03270     currentAnnotation.addAnnotation(ann); 
03271 }
03272 /**
03273  * 
03274  * @param node edu.ksu.cis.bandera.jjjc.node.ATrueBooleanLiteral
03275  */
03276 public void caseATrueBooleanLiteral(ATrueBooleanLiteral node) {
03277     currentValue = IntConstant.v(1);
03278     integralConstantType = edu.ksu.cis.bandera.jjjc.symboltable.BooleanType.TYPE;
03279 }
03280 /**
03281  * 
03282  * @param node edu.ksu.cis.bandera.jjjc.node.ATryFinallyStmt
03283  */
03284 public void caseATryFinallyStmt(ATryFinallyStmt node) {
03285     System.out.println("Unsupported feature of Java: " + node);
03286     exceptions.addElement(new CompilerException("Unsupported feature of Java: " + node));
03287     throw new Error("Unsupported feature of Java: " + node);
03288     /*
03289     finallyAndSynch.insertElementAt(node.getFinally(), 0);
03290     
03291     Stmt prevBeginTrapStmt = beginTrapStmt;
03292     Stmt prevEndTrapStmt = endTrapStmt;
03293     Stmt prevEndTryStmt = endTryStmt;
03294     
03295     TryFinallyStmtAnnotation ann = new TryFinallyStmtAnnotation(node);
03296     am.putFilenameLinePairAnnotation(
03297             new FilenameLinePair(currentClassOrInterfaceType.getPath(),
03298                     LineExtractor.extractLine(node)),
03299             ann);
03300 
03301     TryStmtAnnotation prevAnn = currentTryAnnotation;
03302     currentTryAnnotation = ann;
03303     
03304     BlockStmtAnnotation prevAnnotation = currentAnnotation;
03305     
03306     endTryStmt = jimple.newNopStmt();
03307     beginTrapStmt = jimple.newNopStmt();
03308     
03309     currentStmts.addElement(beginTrapStmt);
03310 
03311     currentAnnotation = new BlockStmtAnnotation(node.getBlock());
03312     
03313     node.getBlock().apply(this);
03314 
03315     Stmt lastStmt = (Stmt) currentStmts.lastElement();
03316 
03317     
03318     SequentialAnnotation sann = new SequentialAnnotation(null);
03319     endTrapStmt = jimple.newGotoStmt(endTryStmt);
03320     sann.addStmt(endTrapStmt);
03321     currentAnnotation.addAnnotation(sann);
03322     ann.setBlockAnnotation(currentAnnotation);
03323     
03324     currentStmts.addElement(endTrapStmt);
03325     
03326     for (Iterator i = node.getCatchClause().iterator(); i.hasNext();) {
03327         PCatchClause catchClause = (PCatchClause) i.next();
03328         catchClause.apply(this);
03329     }
03330     currentStmts.addElement(endTryStmt);
03331 
03332     // finally
03333   currentAnnotation = new BlockStmtAnnotation(node.getFinally());
03334   node.getFinally().apply(this);
03335   ann.setFinallyAnnotation(currentAnnotation);
03336 
03337     // goto endStmt
03338     // temp := @caughtexception
03339     // finally...
03340     // throw temp
03341     Stmt endStmt = jimple.newNopStmt();
03342     currentAnnotation = new BlockStmtAnnotation(null);
03343     sann = new SequentialAnnotation(null);
03344     Stmt stmt = jimple.newGotoStmt(endStmt);
03345     currentStmts.addElement(stmt);
03346     sann.addStmt(stmt);
03347     Local lcl = declareLocal(nameGen.newName(), RefType.v("java.lang.Throwable"), 0);
03348     stmt = jimple.newIdentityStmt(lcl, jimple.newCaughtExceptionRef(currentBody));
03349     try {
03350         Trap trap = jimple.newTrap(getSootClass("java.lang.Throwable"), beginTrapStmt, endTryStmt, stmt);
03351         currentTraps.addElement(trap);
03352     } catch (CompilerException e) {
03353         exceptions.addElement(e);
03354     }
03355     currentStmts.addElement(stmt);
03356     sann.addStmt(stmt);
03357     currentAnnotation.addAnnotation(sann);
03358   node.getFinally().apply(this);
03359     sann = new SequentialAnnotation(null);
03360     for (Enumeration e = synchAnnotations.elements(); e.hasMoreElements();) {
03361         SynchronizedStmtAnnotation syann = (SynchronizedStmtAnnotation) e.nextElement();
03362         Stmt exitMon = jimple.newExitMonitorStmt(syann.getLockValue());
03363         syann.addExitMonitor(exitMon);
03364       currentStmts.addElement(exitMon);
03365       sann.addStmt(exitMon);
03366     }
03367     stmt = jimple.newThrowStmt(lcl);
03368     currentStmts.addElement(stmt);
03369     sann.addStmt(stmt);
03370     currentAnnotation.addAnnotation(sann);
03371     ann.setFinallyExceptionAnnotation(currentAnnotation);
03372 
03373     currentStmts.addElement(endStmt);
03374     
03375     currentAnnotation = prevAnnotation;
03376     currentAnnotation.addAnnotation(ann);
03377     currentTryAnnotation = prevAnn;
03378     
03379     beginTrapStmt = prevBeginTrapStmt;
03380     endTrapStmt = prevEndTrapStmt;
03381     endTryStmt = prevEndTryStmt;
03382     
03383     finallyAndSynch.removeElementAt(0);
03384     */
03385 }
03386 /**
03387  * 
03388  * @param node edu.ksu.cis.bandera.jjjc.node.ATryStmt
03389  */
03390 public void caseATryStmt(ATryStmt node) {
03391     Stmt prevBeginTrapStmt = beginTrapStmt;
03392     Stmt prevEndTrapStmt = endTrapStmt;
03393     Stmt prevEndTryStmt = endTryStmt;
03394     
03395     TryStmtAnnotation ann = new TryStmtAnnotation(node);
03396     LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
03397     ann.setFirstLine(lc.getFirstLine());
03398     ann.setFirstColumn(lc.getFirstColumn());
03399     ann.setLastLine(lc.getLastLine());
03400     ann.setLastColumn(lc.getLastColumn());
03401     am.putFilenameLinePairAnnotation(
03402             new FilenameLinePair(currentClassOrInterfaceType.getPath(),
03403                     LineExtractor.extractLine(node)),
03404             ann);
03405 
03406     TryStmtAnnotation prevAnn = currentTryAnnotation;
03407     currentTryAnnotation = ann;
03408     
03409     BlockStmtAnnotation prevAnnotation = currentAnnotation;
03410     
03411     endTryStmt = jimple.newNopStmt();
03412     beginTrapStmt = jimple.newNopStmt();
03413     
03414     currentStmts.addElement(beginTrapStmt);
03415 
03416     currentAnnotation = new BlockStmtAnnotation(node.getBlock());
03417     
03418     node.getBlock().apply(this);
03419 
03420     Stmt lastStmt = (Stmt) currentStmts.lastElement();
03421 
03422     boolean f = false;
03423 
03424     if ((lastStmt instanceof ReturnStmt) || (lastStmt instanceof ReturnVoidStmt)
03425             || (lastStmt instanceof ThrowStmt) || (lastStmt instanceof GotoStmt)) {
03426         f = true;
03427         endTrapStmt = lastStmt;
03428     } else {
03429         SequentialAnnotation sann = new SequentialAnnotation(null);
03430         endTrapStmt = jimple.newGotoStmt(endTryStmt);
03431         sann.addStmt(endTrapStmt);
03432         currentAnnotation.addAnnotation(sann);
03433         currentStmts.addElement(endTrapStmt);
03434     }
03435     
03436     ann.setBlockAnnotation(currentAnnotation);
03437 
03438     catchHasEnd = true;
03439     
03440     for (Iterator i = node.getCatchClause().iterator(); i.hasNext();) {
03441         PCatchClause catchClause = (PCatchClause) i.next();
03442         catchClause.apply(this);
03443     }
03444 
03445     if (!f || catchHasEnd)
03446         currentStmts.addElement(endTryStmt);
03447 
03448     currentAnnotation = prevAnnotation;
03449     currentAnnotation.addAnnotation(ann);
03450     currentTryAnnotation = prevAnn;
03451     
03452     beginTrapStmt = prevBeginTrapStmt;
03453     endTrapStmt = prevEndTrapStmt;
03454     endTryStmt = prevEndTryStmt;
03455 }
03456 /**
03457  * 
03458  * @param node edu.ksu.cis.bandera.jjjc.node.AUnaryExp
03459  */
03460 public void caseAUnaryExp(AUnaryExp node) {
03461     String operator = node.getUnaryOperator().toString().trim();
03462     if (operator.equals("++")) {
03463         preIncDecExp(node, true);
03464     } else if (operator.equals("--")) {
03465         preIncDecExp(node, false);
03466     } else if (operator.equals("+")) {
03467         node.getExp().apply(this);
03468     } else if (operator.equals("-")) {
03469         node.getExp().apply(this);
03470         if (currentValue instanceof IntConstant) {
03471             currentValue = IntConstant.v(-((IntConstant) currentValue).value);
03472         } else if (currentValue instanceof LongConstant) {
03473             currentValue = LongConstant.v(-((LongConstant) currentValue).value);
03474         } else if (currentValue instanceof FloatConstant) {
03475             currentValue = FloatConstant.v(-((FloatConstant) currentValue).value);
03476         } else if (currentValue instanceof DoubleConstant) {
03477             currentValue = DoubleConstant.v(-((DoubleConstant) currentValue).value);
03478         } else {
03479             currentValue = jimple.newNegExpr(currentValue);
03480             Local lcl = declareLocal(nameGen.newName(), currentValue.getType(), 0);
03481             currentStmts.addElement(jimple.newAssignStmt(lcl, currentValue));
03482             currentValue = lcl;
03483         }
03484     } else if (operator.equals("~")) {
03485         node.getExp().apply(this);
03486         Value operand;
03487         if (currentValue.getType() instanceof ca.mcgill.sable.soot.IntType)
03488             operand = IntConstant.v(-1);
03489         else
03490             operand = LongConstant.v(-1);
03491         currentStmts.addElement(jimple.newAssignStmt(currentValue, jimple.newXorExpr(currentValue, operand)));
03492     } else if (operator.equals("!")) {
03493         Local lcl = null;
03494         if (trueBranch == null) {
03495             lcl = declareLocal(nameGen.newName(), ca.mcgill.sable.soot.BooleanType.v(), 0);
03496             trueBranch = jimple.newAssignStmt(lcl, IntConstant.v(1));
03497             falseBranch = jimple.newAssignStmt(lcl, IntConstant.v(0));
03498         }
03499 
03500         Node n = (Node) node.clone();
03501         PushComplement.push(n);
03502         n = ((AUnaryExp) n).getExp();
03503         n.apply(new BooleanExpression(this, trueBranch, falseBranch));
03504         if (!(currentValue instanceof Local)) {
03505             Local l = declareLocal(nameGen.newName(), ca.mcgill.sable.soot.BooleanType.v(), 0);
03506             currentStmts.addElement(jimple.newAssignStmt(l, currentValue));
03507             currentValue = l;
03508         }
03509 
03510         if (lcl != null) {
03511             Stmt endStmt = jimple.newNopStmt();
03512             currentStmts.addElement(falseBranch);
03513             currentStmts.addElement(jimple.newGotoStmt(endStmt));
03514             currentStmts.addElement(trueBranch);
03515             currentStmts.addElement(endStmt);
03516             trueBranch = null;
03517             falseBranch = null;
03518             currentValue = lcl;
03519         }
03520     }
03521 }
03522 /**
03523  * 
03524  * @param node edu.ksu.cis.bandera.jjjc.node.AVariableDeclaratorId
03525  */
03526 public void caseAVariableDeclaratorId(AVariableDeclaratorId node) {
03527     currentName = new String(node.getId().toString().trim());
03528     
03529     int dimensions = node.getDim().size();
03530     
03531     if (dimensions > 0)
03532         if (currentType instanceof ca.mcgill.sable.soot.ArrayType) {
03533             ca.mcgill.sable.soot.ArrayType arrayType = (ca.mcgill.sable.soot.ArrayType) currentType;
03534             currentType = ca.mcgill.sable.soot.ArrayType.v(arrayType.baseType, arrayType.numDimensions + dimensions);
03535         } else
03536             currentType = ca.mcgill.sable.soot.ArrayType.v((ca.mcgill.sable.soot.BaseType) currentType, dimensions);
03537 }
03538 /**
03539  * 
03540  * @param node edu.ksu.cis.bandera.jjjc.node.AVoidExp
03541  */
03542 public void caseAVoidExp(AVoidExp node) {
03543     System.out.println("Unsupported feature of Java: " + node);
03544     exceptions.addElement(new CompilerException("Unsupported feature of Java: " + node));
03545     throw new Error("Unsupported feature of Java: " + node);
03546 }
03547 /**
03548  * 
03549  * @param node edu.ksu.cis.bandera.jjjc.node.AWhileStmt
03550  */
03551 public void caseAWhileStmt(AWhileStmt node) {
03552     Stmt blockStmt = jimple.newNopStmt();
03553     Stmt testStmt = jimple.newNopStmt();
03554     Stmt endStmt = jimple.newNopStmt();
03555     Stmt initStmt = jimple.newGotoStmt(testStmt);
03556 
03557     WhileStmtAnnotation ann = new WhileStmtAnnotation(node);
03558     LineColumn lc = TokenLineColumnNumberExtractor.getLineColumn(node);
03559     ann.setFirstLine(lc.getFirstLine());
03560     ann.setFirstColumn(lc.getFirstColumn());
03561     ann.setLastLine(lc.getLastLine());
03562     ann.setLastColumn(lc.getLastColumn());
03563     am.putFilenameLinePairAnnotation(
03564             new FilenameLinePair(currentClassOrInterfaceType.getPath(),
03565                     LineExtractor.extractLine(node)),
03566             ann);
03567     BlockStmtAnnotation prevAnnotation = currentAnnotation;
03568 
03569     Object prevLastSynch = lastFinallySynchBeforeControl;
03570     if (synchAnnotations.size() > 0)
03571         lastFinallySynchBeforeControl = (Annotation) synchAnnotations.lastElement();
03572     
03573     Stmt prevTrueBranch = trueBranch;
03574     Stmt prevFalseBranch = falseBranch;
03575     trueBranch = blockStmt;
03576     falseBranch = endStmt;
03577 
03578     Stmt prevBreakTarget = currentBreakTarget;
03579     Stmt prevContinueTarget = currentContinueTarget;
03580     currentBreakTarget = endStmt;
03581     currentContinueTarget = testStmt;
03582     
03583     currentStmts.addElement(initStmt);
03584     
03585     currentStmts.addElement(blockStmt);
03586 
03587     currentAnnotation = new BlockStmtAnnotation(node.getBlock());
03588     node.getBlock().apply(this);
03589 
03590     SequentialAnnotation sann = new SequentialAnnotation(null);
03591     sann.addStmt(initStmt);
03592     ann.setInitAnnotation(sann);
03593     ann.setBlockAnnotation(getFirstEnclosedAnnotation(currentAnnotation));
03594     
03595     currentStmts.addElement(testStmt);
03596 
03597     int start = currentStmts.size();
03598     
03599     Node n = (Node) node.getExp().clone();
03600     PushComplement.push(n);
03601     if (node.getExp() instanceof AUnaryExp)
03602         if ("!".equals(((AUnaryExp) node.getExp()).getUnaryOperator().toString().trim()))
03603             n = ((AUnaryExp) n).getExp();
03604     n.apply(new BooleanExpression(this, trueBranch, falseBranch));
03605 
03606     ann.setIndefinite(currentStmts.elementAt(currentStmts.size() - 1) instanceof JGotoStmt);
03607     
03608     int end = currentStmts.size();
03609     
03610     for (int i = start; i < end; i++) {
03611         ann.addStmt((Stmt) currentStmts.elementAt(i));
03612     }
03613 
03614     currentStmts.addElement(endStmt);
03615 
03616     trueBranch = prevTrueBranch;
03617     falseBranch = prevFalseBranch;
03618     currentBreakTarget = prevBreakTarget;
03619     currentContinueTarget = prevContinueTarget;
03620 
03621     lastFinallySynchBeforeControl = prevLastSynch;
03622     
03623     currentAnnotation = prevAnnotation;
03624     currentAnnotation.addAnnotation(ann);
03625 }
03626 /**
03627  * 
03628  * @param node edu.ksu.cis.bandera.jjjc.node.Start
03629  */
03630 public void caseStart(Start node) {
03631     node.getPCompilationUnit().apply(this);
03632 }
03633 /**
03634  * 
03635  * @param annotation edu.ksu.cis.bandera.annotations.Annotation
03636  * @param body ca.mcgill.sable.soot.jimple.JimpleBody
03637  */
03638 private void checkAnnotation(Annotation annotation, JimpleBody body) {
03639     String line = System.getProperty("line.separator");
03640     boolean failed = false;
03641     
03642     String name = currentSootMethod.toString();
03643     System.out.print("Checking annotation for " + name + ", phase 1...");
03644     
03645     StmtList stmtList = body.getStmtList();
03646 
03647     for (Iterator i = stmtList.iterator(); i.hasNext();) {
03648         Stmt stmt = (Stmt) i.next();
03649         int idx = stmtList.indexOf(stmt);
03650         try {
03651             if (annotation.getContainingAnnotation(stmt) == null) {
03652                 System.out.println(line + name + ", statement index: " + idx + ", " + stmt);
03653                 failed = true;
03654             }
03655         } catch (Exception e) {
03656             System.out.println(line + e + name + ", statement index: " + idx + ", " + stmt);
03657             failed = true;
03658         }
03659     }
03660 
03661     if (failed) System.out.println("Phase 1 failed");
03662     else System.out.println(" passed");
03663 
03664     Object[] bodyStmts = stmtList.toArray();
03665     Stmt[] stmts = annotation.getStatements();
03666 
03667     System.out.println("Checking annotation for " + name + ", phase 2... "
03668             + ((bodyStmts.length == stmts.length) ? "passed" : "failed"));
03669 
03670     System.out.print("Checking annotation for " + name + ", phase 3...");
03671 
03672     failed = false;
03673 
03674     try {
03675     
03676         for (int i = 0; i < stmts.length; i++) {
03677             if (stmts[i] != bodyStmts[i]) {
03678                 System.out.println(line + name + ", statement index: " + i + ":" + line
03679                         + bodyStmts[i] + " <!=> " + stmts[i]);
03680                 Annotation a = annotation.getContainingAnnotation(stmts[i]);
03681                 System.out.println(a.getClass().getName());
03682                 System.out.println(stmtList.contains(stmts[i]));
03683                 failed = true;
03684             }
03685         }
03686     } catch (Exception e) {
03687         failed = true;
03688     }
03689 
03690     if (failed) System.out.println(line + "Phase 3 failed");
03691     else System.out.println(" passed");
03692 }
03693 /**
03694  * 
03695  * @param body ca.mcgill.sable.soot.jimple.JimpleBody
03696  */
03697 private void convertLocalTypes(JimpleBody body) {
03698     for (Iterator i = body.getLocals().iterator(); i.hasNext();) {
03699         Local l = (Local) i.next();
03700         ca.mcgill.sable.soot.Type type = l.getType();
03701         
03702         if ((type instanceof ca.mcgill.sable.soot.BooleanType) || (type instanceof ca.mcgill.sable.soot.ByteType)
03703                 || (type instanceof ca.mcgill.sable.soot.CharType) || (type instanceof ca.mcgill.sable.soot.ShortType)) {
03704             l.setType(ca.mcgill.sable.soot.IntType.v());
03705         }
03706     }
03707 }
03708 /**
03709  * 
03710  * @return ca.mcgill.sable.soot.jimple.Unit
03711  * @param labelName java.lang.String
03712  */
03713 private Unit declareLabel(String labelName) throws CompilerException {
03714     for (Iterator i = labels.iterator(); i.hasNext();) {
03715         Hashtable labelTable = (Hashtable) i.next();
03716         if (labelTable == null) continue;
03717         if (labelTable.get(labelName) != null)
03718             throw new CompilerException("Labeled statement cannot contain the same label identifier " + labelName);
03719     }
03720     Stmt stmt = jimple.newNopStmt();
03721     currentStmts.addElement(stmt);
03722     currentLabels.put(labelName, stmt);
03723     Vector v = new Vector();
03724     v.addElement(lastFinallySynchBeforeControl);
03725     currentLabels.put(stmt, v);
03726     return stmt;
03727 }
03728 /**
03729  * 
03730  * @return ca.mcgill.sable.soot.jimple.Local
03731  * @param name java.lang.String
03732  * @param type ca.mcgill.sable.soot.Type
03733  * @param modifiers int
03734  */
03735 private Local declareLocal(String name, ca.mcgill.sable.soot.Type type, int modifiers) {
03736     if ("$ret".equals(name)) {
03737         if (currentLocalNames.get(name) != null) {
03738             return (Local) currentLocals.get(name);
03739         }
03740     }
03741     if (type instanceof ca.mcgill.sable.soot.NullType) {
03742         type = RefType.v("java.lang.Object");
03743     } 
03744     
03745     String localName;
03746     if (currentLocalNames.get(name) != null) {
03747         currentLocalNames.remove(name);
03748         localName = getUniqueName(name);
03749         if (symbolTable.getNumScopeLevels() != 0) {
03750             if (symbolTable.hasLocalVariableDeclared(new Name(name)))
03751                 exceptions.addElement(new CompilerException("Local variable " + name + " has already been declared"));
03752         }
03753     } else
03754         localName = name;
03755         
03756     currentLocalNames.put(name, localName);
03757     if (symbolTable.getNumScopeLevels() != 0) {
03758         try {
03759             // modifiers doesn't matter
03760             symbolTable.declareLocalVariable(new Variable(0, Util.convertType(type, symbolTable),
03761                     new Name(name)));
03762         } catch (CompilerException e) {
03763             exceptions.addElement(e);
03764         }
03765     }
03766     
03767     Local tempLocal = jimple.newLocal(localName, type);
03768     currentLocals.put(tempLocal.getName(), tempLocal);
03769     return tempLocal;
03770 }
03771 /**
03772  * 
03773  * @param lhs boolean
03774  * @param caller ca.mcgill.sable.soot.jimple.Value
03775  * @param className java.lang.String
03776  * @param fieldName java.lang.String
03777  */
03778 private void fieldAccess(boolean lhs, Value caller, String className, String fieldName) throws CompilerException {
03779     SootField sf = getSootField(className, fieldName);
03780     if (!lhs) {
03781         String tempName = nameGen.newName();
03782         Local lcl = declareLocal(tempName, sf.getType(), 0);
03783         if (Modifier.isStatic(sf.getModifiers())) {
03784             currentStmts.addElement(jimple.newAssignStmt(lcl, jimple.newStaticFieldRef(sf)));
03785             currentValue = lcl;
03786         } else {
03787             if (caller != null) {
03788                 currentStmts.addElement(jimple.newAssignStmt(lcl, jimple.newInstanceFieldRef(caller, sf)));
03789                 currentValue = lcl;
03790             } else {
03791                 exceptions.addElement(new CompilerException("Could not access instance field " + fieldName + " in static method " + currentSootMethod.getName()));
03792                 return;
03793             }
03794         }
03795         currentValue = lcl;
03796     } else {
03797         if (Modifier.isStatic(sf.getModifiers())) {
03798             currentValue = jimple.newStaticFieldRef(sf);
03799         } else {
03800             if (caller != null) {
03801                 currentValue = jimple.newInstanceFieldRef(caller, sf);
03802             } else {
03803                 exceptions.addElement(new CompilerException("Could not access instance field " + fieldName + " in static method " + currentSootMethod.getName()));
03804                 currentValue = null;
03805                 return;
03806             }
03807         }
03808     }
03809 }
03810 /**
03811  * 
03812  * @return java.util.Vector
03813  */
03814 public Vector getCompiledClasses() {
03815     return compiledClasses;
03816 }
03817 /**
03818  * 
03819  * @return java.util.Vector
03820  */
03821 public Vector getCurrentStmts() {
03822     return currentStmts;
03823 }
03824 /**
03825  * 
03826  * @return ca.mcgill.sable.soot.Type
03827  */
03828 public ca.mcgill.sable.soot.Type getCurrentType() {
03829     return currentType;
03830 }
03831 /**
03832  * 
03833  * @return ca.mcgill.sable.soot.jimple.Value
03834  */
03835 public Value getCurrentValue() {
03836     return currentValue;
03837 }
03838 /**
03839  * 
03840  * @return java.util.Vector
03841  */
03842 public Vector getExceptions() {
03843     return exceptions;
03844 }
03845 /**
03846  * 
03847  * @return edu.ksu.cis.bandera.annotations.Annotation
03848  * @param annotation edu.ksu.cis.bandera.annotations.BlockStmtAnnotation
03849  */
03850 private Annotation getFirstEnclosedAnnotation(BlockStmtAnnotation annotation) {
03851     Vector annotations = annotation.getContainedAnnotations();
03852     return (annotations.size() > 0) ? (Annotation) annotations.elementAt(0)
03853             : new EmptyStmtAnnotation(null);
03854 }
03855 /**
03856  * 
03857  * @return java.lang.Object
03858  * @param unit ca.mcgill.sable.soot.jimple.Unit
03859  */
03860 private Object getLabelObject(Unit unit) {
03861     for (Iterator i = labels.iterator(); i.hasNext();) {
03862         Hashtable labelTable = (Hashtable) i.next();
03863         if (labelTable.get(unit) != null)
03864             return labelTable.get(unit);
03865     }
03866     return null;
03867 }
03868 /**
03869  * 
03870  * @return ca.mcgill.sable.soot.jimple.Unit
03871  * @param name java.lang.String
03872  */
03873 private Unit getLabelUnit(String name) {
03874     for (Iterator i = labels.iterator(); i.hasNext();) {
03875         Hashtable labelTable = (Hashtable) i.next();
03876         if (labelTable.get(name) != null)
03877             return (Unit) labelTable.get(name);
03878     }
03879     return null;
03880 }
03881 /**
03882  * 
03883  * @param q edu.ksu.cis.bandera.specification.datastructure.Quantifier
03884  */
03885 private Value getPlaceHolder(QuantifiedVariable q) {
03886     String fName = "quantification$" + q.getName();
03887     
03888     SootField f;
03889 
03890     if (CompilationManager.getFieldForQuantifier(fName) == null) {
03891         f = new SootField(fName, RefType.v(q.getType().toString()), Modifier.PUBLIC | Modifier.STATIC);
03892         CompilationManager.addFieldForQuantifier(f);
03893     } else {
03894         f = CompilationManager.getFieldForQuantifier(fName);
03895     }
03896     
03897     return jimple.newStaticFieldRef(f);
03898 }
03899 /**
03900  * 
03901  * @return ca.mcgill.sable.soot.Type
03902  * @param firstType ca.mcgill.sable.soot.Type
03903  * @param secondType ca.mcgill.sable.soot.Type
03904  */
03905 private ca.mcgill.sable.soot.Type getResultType(ca.mcgill.sable.soot.Type firstType, ca.mcgill.sable.soot.Type secondType) {
03906     if (((firstType instanceof RefType) && ("java.lang.String".equals(((RefType) firstType).className)))
03907             || ((secondType instanceof RefType) && ("java.lang.String".equals(((RefType) secondType).className)))) {
03908         return RefType.v("java.lang.String");
03909     } else if ((firstType instanceof ca.mcgill.sable.soot.DoubleType)
03910             || (secondType instanceof ca.mcgill.sable.soot.DoubleType)) {
03911         return ca.mcgill.sable.soot.DoubleType.v();
03912     } else if ((firstType instanceof ca.mcgill.sable.soot.FloatType)
03913             || (secondType instanceof ca.mcgill.sable.soot.FloatType)) {
03914         return ca.mcgill.sable.soot.FloatType.v();
03915     } else if ((firstType instanceof ca.mcgill.sable.soot.LongType)
03916             || (secondType instanceof ca.mcgill.sable.soot.LongType)) {
03917         return ca.mcgill.sable.soot.LongType.v();
03918     } else if ((firstType instanceof RefType) || (secondType instanceof RefType)) {
03919         return null;
03920     } else {
03921         return ca.mcgill.sable.soot.IntType.v();
03922     }
03923 }
03924 /**
03925  * 
03926  * @return ca.mcgill.sable.soot.SootClass
03927  * @param name java.lang.String
03928  */
03929 private SootClass getSootClass(String name) throws CompilerException {
03930     ClassOrInterfaceType type = symbolTable.resolveClassOrInterfaceType(new Name(name));
03931     type.loadReferences();
03932     String typeName = type.getName().toString();
03933     
03934     if (scm.managesClass(typeName))
03935         return scm.getClass(typeName);
03936 
03937     SootClass sc = new SootClass(typeName);
03938     sc.setResolved(true);
03939     scm.addClass(sc);
03940 
03941     int modifiers = Util.convertModifiers(type.getModifiers());
03942 
03943     if (type.isInterface())
03944         modifiers |= Modifier.INTERFACE;
03945     
03946     sc.setModifiers(modifiers);
03947 
03948     if (type.getDirectSuperClass() != null)
03949         sc.setSuperClass(getSootClass(type.getDirectSuperClass().getName().toString()));
03950 
03951     for (Enumeration e = type.getDirectSuperInterfaces(); e.hasMoreElements();) {
03952         sc.addInterface(getSootClass(((ClassOrInterfaceType) e.nextElement()).getName().toString()));
03953     }
03954 
03955     return sc;
03956 }
03957 /**
03958  * 
03959  * @return ca.mcgill.sable.soot.SootField
03960  * @param typeName java.lang.String
03961  * @param fieldName java.lang.String
03962  */
03963 private SootField getSootField(String typeName, String fieldName) throws CompilerException {
03964     try {
03965         ClassOrInterfaceType classType = symbolTable.resolveClassOrInterfaceType(new Name(typeName));
03966         classType.loadReferences();
03967         Field f = (Field) classType.getField(new Name(fieldName));
03968         String declaringType = f.getDeclaringClassOrInterface().toString();
03969         SootClass sc = getSootClass(declaringType);
03970         if (sc.declaresField(fieldName))
03971             return sc.getField(fieldName);
03972         int modifiers = Util.convertModifiers(f.getModifiers());
03973         if (f.getDeclaringClassOrInterface().isInterface())
03974             modifiers = Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL;
03975         SootField sf = new SootField(fieldName, Util.convertType(f.getType()), modifiers);
03976         sc.addField(sf);
03977         return sf;
03978     } catch (CompilerException e) {
03979         throw e;
03980     }
03981 }
03982 /**
03983  * 
03984  * @return ca.mcgill.sable.soot.SootMethod
03985  * @param typeName java.lang.String
03986  * @param methodName java.lang.String
03987  * @param parameterTypes ca.mcgill.sable.util.LinkedList
03988  */
03989 private SootMethod getSootMethod(String typeName, String methodName, Vector parameterTypes) throws CompilerException {
03990     if ("Bandera".equals(typeName)) {
03991         if ("assert".equals(methodName)) {
03992             return assertMethod;
03993         } else if ("choose".equals(methodName)) {
03994             return chooseMethod;
03995         }
03996     }
03997     try {
03998         LinkedList parmTypes = new LinkedList();
03999         Method m;
04000         SootMethod sm;
04001         if ("<init>".equals(methodName)) {
04002             m = symbolTable.resolveConstructor(new Name(typeName), parameterTypes);
04003             for (Enumeration e = m.getParameterTypes().elements(); e.hasMoreElements();) {
04004                 parmTypes.addLast(Util.convertType((edu.ksu.cis.bandera.jjjc.symboltable.Type) e.nextElement()));
04005             }
04006             SootClass sc = getSootClass(m.getDeclaringClassOrInterface().getName().toString());
04007             if (sc.declaresMethod(methodName, parmTypes))
04008                 return sc.getMethod(methodName, parmTypes);
04009             sm = new SootMethod(methodName, parmTypes, ca.mcgill.sable.soot.VoidType.v());
04010             sc.addMethod(sm);
04011         } else {
04012             m = symbolTable.resolveMethod(new Name(typeName), new Name(methodName), parameterTypes);
04013             for (Enumeration e = m.getParameterTypes().elements(); e.hasMoreElements();) {
04014                 parmTypes.addLast(Util.convertType((edu.ksu.cis.bandera.jjjc.symboltable.Type) e.nextElement()));
04015             }
04016             String declaringType = m.getDeclaringClassOrInterface().getName().toString();
04017             SootClass sc = getSootClass(declaringType);
04018             if (sc.declaresMethod(methodName, parmTypes))
04019                 return sc.getMethod(methodName, parmTypes);
04020             sm = new SootMethod(methodName, parmTypes, Util.convertType(m.getReturnType()));
04021             sc.addMethod(sm);
04022         }
04023         int modifiers = Util.convertModifiers(m.getModifiers());
04024         if (m.getDeclaringClassOrInterface().isInterface())
04025             modifiers |= Modifier.ABSTRACT;
04026         sm.setModifiers(modifiers);
04027         for (Enumeration e = m.getExceptions(); e.hasMoreElements();) {
04028             ClassOrInterfaceType exceptionType = (ClassOrInterfaceType) e.nextElement();
04029             SootClass exceptionSootClass = getSootClass(exceptionType.getName().toString());
04030             Name throwableName = new Name("java.lang.Throwable");
04031             if (exceptionType.hasSuperClass(throwableName) || throwableName.equals(exceptionType.getName())) {
04032                 sm.addException(exceptionSootClass);
04033             } else {
04034                 exceptions.addElement(new  NotThrowableException("Cannot have an unthrowable exception type named '" + exceptionType.getName() + "'"));
04035             }
04036         }
04037         return sm;
04038     } catch (CompilerException e) {
04039         throw e;
04040     }
04041 }
04042 /**
04043  * 
04044  * @return java.lang.String
04045  * @param varName java.lang.String
04046  */
04047 private String getUniqueName(String varName) {
04048     String result;
04049     Integer iteration;
04050     if (currentLocalNamesIterator.get(varName) == null)
04051         iteration = new Integer(0);
04052     else
04053         iteration = new Integer(((Integer) currentLocalNamesIterator.get(varName)).intValue() + 1);
04054     result = varName + "$" + iteration.toString();
04055     currentLocalNamesIterator.put(varName, iteration);
04056     return result;
04057 }
04058 /**
04059  * 
04060  * @param q edu.ksu.cis.bandera.specification.datastructure.Quantifier
04061  * @param c ca.mcgill.sable.soot.jimple.Local
04062  */
04063 private void inlineAvailable(QuantifiedVariable q, Local c) {
04064     /*
04065     if (MainClass.P == null) {
04066     temp = choose(true,false);
04067     if (temp && constraint) MainClass.P = c;
04068     }
04069     */
04070     /*
04071     lcl = MainClass.P;
04072     if lcl != null goto [nop];
04073     if !constraint goto [nop];
04074     temp = choose(1, 0);
04075     if temp == 0 goto [nop];
04076     MainClass.P = c;
04077     nop;
04078     */
04079 
04080     if (qtNameGen == null) qtNameGen = new NameGenerator("qtvar_");
04081     
04082     Stmt s = jimple.newNopStmt();
04083 
04084     Local lcl = declareLocal(qtNameGen.newName(), c.getType(), 0);
04085     Value ph = getPlaceHolder(q);
04086     currentStmts.addElement(jimple.newAssignStmt(lcl, ph));
04087     currentStmts.addElement(jimple.newIfStmt(jimple.newNeExpr(lcl, NullConstant.v()), s));
04088     Local temp = declareLocal(qtNameGen.newName(), ca.mcgill.sable.soot.IntType.v(), 0);
04089     LinkedList l = new LinkedList();
04090     l.addLast(IntConstant.v(0));
04091     l.addLast(IntConstant.v(1));
04092     Stmt ts = jimple.newAssignStmt(temp, new ChooseExpr(l));
04093     currentStmts.addElement(ts);
04094     currentStmts.addElement(jimple.newIfStmt(jimple.newEqExpr(temp, IntConstant.v(0)), s));
04095     currentStmts.addElement(jimple.newAssignStmt(ph, c));
04096     currentStmts.addElement(s);
04097 }
04098 /**
04099  * 
04100  * @return boolean
04101  * @param value ca.mcgill.sable.soot.jimple.Value
04102  */
04103 private boolean isNumberConstant(Value value) {
04104     return ((value instanceof IntConstant) || (value instanceof LongConstant) || (value instanceof DoubleConstant)
04105             || (value instanceof FloatConstant));
04106 }
04107 /**
04108  * 
04109  * @return boolean
04110  * @param typeName1 java.lang.String
04111  * @param typeName2 java.lang.String
04112  */
04113 private boolean isSubtypeOf(String typeName1, String typeName2) {
04114     try {
04115         Name superName = new Name(typeName1);
04116         ClassOrInterfaceType type = symbolTable.resolveClassOrInterfaceType(superName);
04117         return type.hasSuperClass(superName) || type.hasSuperInterface(superName);
04118     } catch (Exception e) {
04119         exceptions.addElement(e);
04120     }
04121     return false;
04122 }
04123 /**
04124  * 
04125  */
04126 private void labelEnterBlock() {
04127     if (!labels.contains(currentLabels)) {
04128         labels.add(currentLabels);
04129     }
04130     currentLabels = new Hashtable();
04131     labels.addLast(currentLabels);
04132 }
04133 /**
04134  * 
04135  */
04136 private void labelExitBlock() {
04137     currentLabels = (Hashtable) labels.removeLast();
04138 }
04139 /**
04140  * 
04141  * @param name java.lang.String
04142  * @param args ca.mcgill.sable.util.List
04143  * @param specialInvoke boolean
04144  */
04145 private void methodInvocation(String name, List args, Vector types, boolean specialInvoke) {
04146     LinkedList newArgs = new LinkedList();
04147     for (Iterator i = args.iterator(); i.hasNext();) {
04148         Value value = (Value) i.next();
04149         if (!(value instanceof Local) && !(value instanceof Constant)) {
04150             Local lcl = declareLocal(nameGen.newName(), value instanceof ConditionExpr ? ca.mcgill.sable.soot.BooleanType.v() : value.getType(), 0);
04151             currentStmts.addElement(jimple.newAssignStmt(lcl, value));
04152             newArgs.addLast(lcl);
04153         } else {
04154             newArgs.addLast(value);
04155         }
04156     }
04157 
04158     args = newArgs;
04159     
04160     String methodName = name.trim();
04161     Name qName = new Name(methodName);
04162     Value caller;
04163     String className;
04164     if (qName.isSimpleName()) {
04165         caller = currentThisLocal;
04166         className = currentSootClass.getName();
04167     } else {
04168         Name superName = qName.getSuperName();
04169         methodName = qName.getLastIdentifier().toString();
04170         try {
04171             symbolTable.resolveFieldOrLocal(superName);
04172             
04173             nameFieldOrLocalExp(false, superName.toString());
04174             caller = currentValue;
04175             currentValue = null;
04176             if (caller.getType() instanceof ca.mcgill.sable.soot.ArrayType)
04177                 className = "java.lang.Object";
04178             else 
04179                 className = ((RefType) caller.getType()).className;
04180         } catch (Exception e) {
04181             className = superName.toString();
04182             caller = null;
04183         }
04184     }
04185     methodInvoke(caller, className, methodName, args, types, specialInvoke);
04186 }
04187 /**
04188  * 
04189  * @param caller ca.mcgill.sable.soot.jimple.Value
04190  * @param className java.lang.String
04191  * @param methodName java.lang.String
04192  * @param args ca.mcgill.sable.util.List
04193  * @param boolean specialInvoke
04194  */
04195 private void methodInvoke(Value caller, String className, String methodName, List args, Vector types, boolean specialInvoke) {
04196     try {
04197         if (caller != null) {
04198             if (!(caller instanceof Local)) {
04199                 Local lcl = declareLocal(nameGen.newName(), caller.getType(), 0);
04200                 currentStmts.addElement(jimple.newAssignStmt(lcl, caller));
04201                 caller = lcl;
04202             }
04203         }
04204         SootMethod sm;
04205         try {
04206             sm = getSootMethod(className, methodName, types);
04207         } catch (CompilerException e) {
04208             if (Modifier.isInterface(scm.getClass(className).getModifiers())) {
04209                 sm = getSootMethod("java.lang.Object", methodName, types);
04210             } else {
04211                 throw e;
04212             }
04213         }
04214         if (Modifier.isStatic(sm.getModifiers())) {
04215             currentValue = jimple.newStaticInvokeExpr(sm, args);
04216         } else {
04217             if (caller != null) {
04218                 if (Modifier.isInterface(sm.getDeclaringClass().getModifiers())) 
04219                     currentValue = jimple.newInterfaceInvokeExpr((Local) caller, sm, args);
04220                 else if (specialInvoke || Modifier.isPrivate(sm.getModifiers()))
04221                     currentValue = jimple.newSpecialInvokeExpr((Local) caller, sm, args);
04222                 else
04223                     currentValue = jimple.newVirtualInvokeExpr((Local) caller, sm, args);
04224             } else {
04225                 exceptions.addElement(new CompilerException("Could not invoke instance method " + methodName + " in " + sm.getName()));
04226                 return;
04227             }
04228         }
04229         Value methodValue = currentValue;
04230         currentValue = null;
04231         if (sm.getReturnType() instanceof ca.mcgill.sable.soot.VoidType) {
04232             currentStmts.addElement(jimple.newInvokeStmt(methodValue));
04233         } else {
04234             Local lcl = declareLocal(nameGen.newName(), sm.getReturnType(), 0);
04235             currentStmts.addElement(jimple.newAssignStmt(lcl, methodValue));
04236             currentValue = lcl;
04237         }
04238     } catch (CompilerException e) {
04239         exceptions.addElement(e);
04240     }
04241 }
04242 /**
04243  * 
04244  * @param lhs boolean
04245  * @param name java.lang.String
04246  */
04247 private void nameExp(boolean lhs, String name) {
04248     String expName = name.trim();
04249     if (expName.endsWith(".length")) {
04250         if (lhs) {
04251             currentValue = null;
04252             exceptions.addElement(new CompilerException("Cannot have array length expression in left hand side of assignment"));
04253             return;
04254         }
04255         String arrayName = name.substring(0, name.length() - 7);
04256         nameFieldOrLocalExp(lhs, arrayName);
04257         if (currentValue != null) {
04258             String tempName = nameGen.newName();
04259             Local lcl = declareLocal(tempName, ca.mcgill.sable.soot.IntType.v(), 0);
04260             currentStmts.addElement(jimple.newAssignStmt(lcl, jimple.newLengthExpr(currentValue)));
04261             currentValue = lcl;
04262         } else {
04263             exceptions.addElement(new CompilerException("Could not resolve array name " + arrayName + " in " + expName));
04264         }
04265     } else {
04266         nameFieldOrLocalExp(lhs, expName);
04267     }
04268 }
04269 /**
04270  * 
04271  * @param lhs boolean
04272  * @param name java.lang.String
04273  */
04274 private void nameFieldOrLocalExp(boolean lhs, String name) {
04275     name = name.trim();
04276 
04277     Value caller;
04278     if (currentLocalNames.get(name) != null) {
04279         currentValue = (Local) currentLocals.get(currentLocalNames.get(name));
04280         return;
04281     } else {
04282         Name qName = new Name(name);
04283         String className;
04284         String fieldName;
04285         if (qName.isSimpleName()) {
04286             className = currentSootClass.getName();
04287             fieldName = name;
04288             caller = currentThisLocal;
04289         } else {
04290             fieldName = qName.getLastIdentifier();
04291             Name superName = qName.getSuperName();
04292             boolean isTypeName;
04293             try {
04294                 superName = symbolTable.resolveClassOrInterfaceType(superName).getName();
04295                 isTypeName = true;
04296             } catch (Exception e) {
04297                 isTypeName = false;
04298             }
04299             if (isTypeName) {
04300                 className = superName.toString();
04301                 caller = null;
04302             } else {
04303                 nameFieldOrLocalExp(lhs, superName.toString());
04304                 className = ((RefType) currentValue.getType()).className;
04305                 caller = currentValue;
04306                 currentValue = null;
04307                 Local lcl = declareLocal(nameGen.newName(), caller.getType(), 0);
04308                 currentStmts.addElement(jimple.newAssignStmt(lcl, caller));
04309                 caller = lcl;
04310             }
04311         }
04312         try {
04313             symbolTable.resolveExpression(new Name(name));
04314             fieldAccess(lhs, caller, className, fieldName);
04315         } catch (CompilerException e) {
04316             exceptions.addElement(e);
04317         }
04318     }
04319 }
04320 /**
04321  * 
04322  * @param operator java.lang.String
04323  * @param firstValue ca.mcgill.sable.soot.jimple.Value
04324  * @param secondValue ca.mcgill.sable.soot.jimple.Value
04325  */
04326 private void numericOperation(String operator, Value firstValue, Value secondValue) throws CompilerException {
04327     ca.mcgill.sable.soot.Type firstType = firstValue.getType();
04328     ca.mcgill.sable.soot.Type secondType = secondValue.getType();
04329     ca.mcgill.sable.soot.Type resultType = getResultType(firstType, secondType);
04330     Local lcl;
04331     if (resultType == null) {
04332         exceptions.addElement(new CompilerException("Cannot perform operation " + firstType + " " + operator + " " + secondType));
04333         currentValue = null;
04334         return;
04335     } else if (resultType instanceof RefType) {
04336         if ("+".equals(operator)) {
04337             RefType refType = ca.mcgill.sable.soot.RefType.v("java.lang.String");
04338             ClassOrInterfaceType stringType = symbolTable.resolveClassOrInterfaceType(new Name("java.lang.String"));
04339             Vector types = new Vector();
04340             types.addElement(stringType);
04341             LinkedList values = new LinkedList();
04342             if (!(firstType instanceof RefType)) {
04343                 values.addLast(firstValue);
04344                 SootMethod valueOf1 = getSootMethod("java.lang.String", "valueOf", types);
04345                 Local lcl1 = declareLocal(nameGen.newName(), refType, 0);
04346                 currentStmts.addElement(jimple.newAssignStmt(lcl1, jimple.newStaticInvokeExpr(valueOf1, values)));
04347                 firstValue = lcl1;
04348             } else if (!(secondType instanceof RefType)) {
04349                 values.addLast(secondValue);
04350                 SootMethod valueOf2 = getSootMethod("java.lang.String", "valueOf", types);
04351                 Local lcl2 = declareLocal(nameGen.newName(), refType, 0);
04352                 currentStmts.addElement(jimple.newAssignStmt(lcl2, jimple.newStaticInvokeExpr(valueOf2, values)));
04353                 secondValue = lcl2;
04354             }
04355             SootMethod concat = getSootMethod("java.lang.String", "concat", types);
04356             lcl = declareLocal(nameGen.newName(), refType, 0);
04357             if (!(firstValue instanceof Local)) {
04358                 Local tempLocal = declareLocal(nameGen.newName(), refType, 0);
04359                 currentStmts.addElement(jimple.newAssignStmt(tempLocal, firstValue));
04360                 firstValue = tempLocal;
04361             }
04362             String secondTypeString = secondValue.getType().toString().trim();
04363             if (!"java.lang.String".equals(secondTypeString)) {
04364                 Local tempLocal = declareLocal(nameGen.newName(), refType, 0);
04365                 currentStmts.addElement(jimple.newAssignStmt(tempLocal, jimple.newVirtualInvokeExpr((Local) secondValue,
04366                     getSootMethod("java.lang.Object", "toString", new Vector()), new LinkedList())));
04367                 secondValue = tempLocal;
04368             }
04369             values = new LinkedList();
04370             values.addLast(secondValue);
04371             currentStmts.addElement(jimple.newAssignStmt(lcl, jimple.newVirtualInvokeExpr((Local) firstValue, concat, values)));
04372             currentValue = lcl;
04373             return;
04374         } else {
04375             exceptions.addElement(new CompilerException("Cannot perform operation " + firstType + " + " + secondType));
04376             currentValue = null;
04377             return;
04378         }
04379     } else {
04380         lcl = declareLocal(nameGen.newName(), resultType, 0);
04381     }
04382     if ("+".equals(operator)) {
04383         currentValue = jimple.newAddExpr(firstValue, secondValue);
04384     } else if ("-".equals(operator)) {
04385         currentValue = jimple.newSubExpr(firstValue, secondValue);
04386     } else if ("*".equals(operator)) {
04387         currentValue = jimple.newMulExpr(firstValue, secondValue);
04388     } else if ("%".equals(operator)) {
04389         currentValue = jimple.newRemExpr(firstValue, secondValue);
04390     } else if ("/".equals(operator)) {
04391         currentValue = jimple.newDivExpr(firstValue, secondValue);
04392     } else if ("&".equals(operator)) {
04393         currentValue = jimple.newAndExpr(firstValue, secondValue);
04394     } else if ("|".equals(operator)) {
04395         currentValue = jimple.newOrExpr(firstValue, secondValue);
04396     } else if (">>".equals(operator)) {
04397         currentValue = jimple.newShrExpr(firstValue, secondValue);
04398     } else if (">>>".equals(operator)) {
04399         currentValue = jimple.newUshrExpr(firstValue, secondValue);
04400     } else if ("<<".equals(operator)) {
04401         currentValue = jimple.newShlExpr(firstValue, secondValue);
04402     } else {
04403         currentValue = jimple.newXorExpr(firstValue, secondValue);
04404     }
04405     currentStmts.addElement(jimple.newAssignStmt(lcl, currentValue));
04406     currentValue = lcl;
04407 }
04408 /**
04409  * 
04410  */
04411 private void patchBody(JimpleBody body) {
04412     StmtList stmts = body.getStmtList();
04413     Local thisLocal = null;
04414     for (ca.mcgill.sable.util.Iterator i = stmts.iterator(); i.hasNext();) {
04415         Stmt s = (Stmt) i.next();
04416         if (s instanceof IdentityStmt) {
04417             IdentityStmt is = (IdentityStmt) s;
04418             if (is.getRightOp() instanceof ThisRef) {
04419                 thisLocal = (Local) is.getLeftOp();
04420                 thisLocal.setName("JJJCTEMP$0");
04421                 return;
04422             }
04423         }
04424     }
04425 }
04426 /**
04427  * 
04428  * @param node edu.ksu.cis.bandera.jjjc.node.PExp
04429  * @param isPlus boolean
04430  */
04431 private void postIncDecExp(PExp node, boolean isPlus) {
04432     String name = null;
04433     if (isPlus) {
04434         if (((APostIncrementExp) node).getExp() instanceof ANameExp) {
04435             name = (new Name((((ANameExp) ((APostIncrementExp) node).getExp()).getName()).toString())).toString();
04436             nameExp(node.parent() instanceof ANameLeftHandSide, name);
04437         } else {
04438             ((APostIncrementExp) node).getExp().apply(this);
04439         }
04440     } else {
04441         if (((APostDecrementExp) node).getExp() instanceof ANameExp) {
04442             name = (new Name((((ANameExp) ((APostDecrementExp) node).getExp()).getName()).toString())).toString();
04443             nameExp(node.parent() instanceof ANameLeftHandSide, name);
04444         } else {
04445             ((APostDecrementExp) node).getExp().apply(this);
04446         }
04447     }
04448     Value postValue = currentValue;
04449     currentValue = null;
04450     Local lcl = declareLocal(nameGen.newName(), postValue.getType(), 0);
04451     currentStmts.addElement(jimple.newAssignStmt(lcl, postValue));
04452     Value operandValue;
04453     if (postValue.getType() instanceof ca.mcgill.sable.soot.IntType)
04454         operandValue = IntConstant.v(1);
04455     else
04456         operandValue = LongConstant.v(1);
04457     if (isPlus)
04458         currentStmts.addElement(jimple.newAssignStmt(postValue, jimple.newAddExpr(postValue, operandValue)));
04459     else
04460         currentStmts.addElement(jimple.newAssignStmt(postValue, jimple.newSubExpr(postValue, operandValue)));
04461     if (name != null) {
04462         nameExp(true, name);
04463     } else {
04464         assignExp = true;
04465         if (isPlus) {
04466             ((APostIncrementExp) node).getExp().apply(this);
04467         } else {
04468             ((APostDecrementExp) node).getExp().apply(this);
04469         }
04470     }
04471     currentStmts.addElement(jimple.newAssignStmt(currentValue, postValue));
04472     currentValue = lcl;
04473 }
04474 /**
04475  * 
04476  * @param node edu.ksu.cis.bandera.jjjc.node.AUnaryExp
04477  * @param isPlus boolean
04478  */
04479 private void preIncDecExp(AUnaryExp node, boolean isPlus) {
04480     String name = null;
04481     if (node.getExp() instanceof ANameExp) {
04482         name = (new Name((((ANameExp) node.getExp()).getName()).toString())).toString();
04483         nameExp(node.parent() instanceof ANameLeftHandSide, name);
04484     } else {
04485         node.getExp().apply(this);
04486     }
04487     
04488     Value preValue = currentValue;
04489     currentValue = null;
04490     Value operandValue;
04491     if (preValue.getType() instanceof ca.mcgill.sable.soot.IntType)
04492         operandValue = IntConstant.v(1);
04493     else
04494         operandValue = LongConstant.v(1);
04495     if (isPlus)
04496         currentStmts.addElement(jimple.newAssignStmt(preValue, jimple.newAddExpr(preValue, operandValue)));
04497     else
04498         currentStmts.addElement(jimple.newAssignStmt(preValue, jimple.newSubExpr(preValue, operandValue)));
04499         
04500     if (name != null) {
04501         nameExp(true, name);
04502     } else {
04503         assignExp = true;
04504         node.getExp().apply(this);
04505     }
04506     
04507     currentStmts.addElement(jimple.newAssignStmt(currentValue, preValue));
04508     currentValue = preValue;
04509 }
04510 }

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