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

PostProcess.java

00001 package edu.ksu.cis.bandera.pdgslicer;
00002 
00003 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00004  * Bandera, a Java(TM) analysis and transformation toolkit           *
00005  * Copyright (C) 1998, 1999   Hongjun Zheng (zheng@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 
00036 
00037 import ca.mcgill.sable.util.*;
00038 import ca.mcgill.sable.soot.*;
00039 import ca.mcgill.sable.soot.jimple.*;
00040 
00041 import edu.ksu.cis.bandera.pdgslicer.exceptions.*;
00042 import edu.ksu.cis.bandera.annotation.*;
00043 
00044 import java.io.*;
00045 import java.util.Enumeration;
00046 import java.util.Vector;
00047 import java.util.BitSet;
00048 
00049 /**
00050  * This class is for constructing residual program for
00051  * each sliced class and method.
00052  */
00053 public class PostProcess
00054 {
00055   /**
00056    * A list of {@link ClassInfo ClassInfo} for each class.
00057    */
00058   private List classList;
00059   /**
00060    * A list of {@link ClassInfo ClassInfo} which is sliced away.
00061    */
00062   List removableClasses = new ArrayList();
00063   /**
00064    * A list of {@link SootMethod SootMethod} such that
00065    * return value should be changed to return void due to
00066    * the irrelevance of return value.
00067    */
00068   List changeReturnTypeToVoidMds = new ArrayList();
00069   /** 
00070    * A set of {@link Value Value} which is relevant in 
00071    * the residual program.
00072    */
00073   private Set relevantFields = new ArraySet();
00074     private Set relevantExceptionClassNames = new ArraySet();
00075   private AnnotationManager cfanns = null;
00076 
00077 /**
00078    * @param ct a list of {@link ClassInfo ClassInfo}.
00079    * @param cfs annotation manager.
00080    */
00081 public PostProcess(List ct, AnnotationManager cfs) {
00082     classList = ct;
00083     cfanns = cfs;
00084 }
00085 /**
00086  * Add all statements in <code>catch</code> block into
00087  * a set <code>removedSet</code> except for those
00088  * in the given slice set.
00089  * <p>
00090  * @param removedSet a set of {@link Stmt Stmt} which is
00091  * the result of this method.
00092  * @param catches a vector of {@link Annotation Annotation}
00093  * which is that of catch clause.
00094  * @param stmtList statement list for indexing.
00095  * @param linePropList a set of {@link Stmt Stmt} which
00096  * is slice point.
00097  * @param slcSet slice set indexed in a BitSet.
00098  */
00099 private void addCatchesToRemovedSet(Set removedSet, Vector catches, StmtList stmtList, Set linePropList, BitSet slcSet) {
00100     for (Enumeration e2 = catches.elements(); e2.hasMoreElements();) {
00101         Annotation catchClauseCFANN = (Annotation) e2.nextElement();
00102         Stmt trapStmts[] = catchClauseCFANN.getStatements();
00103         for (int i = 0; i < trapStmts.length; i++) {
00104             Stmt stmt = trapStmts[i];
00105             int stmtIndex = stmtList.indexOf(trapStmts[i]);
00106             if (linePropList.contains(stmt))
00107                 continue;
00108             removedSet.add(stmt);
00109             if (slcSet.get(stmtIndex))
00110                 slcSet.set(stmtIndex);
00111         }
00112     }
00113 }
00114 /**
00115  * Add all statements in catch blocks into the given slice set.
00116  * <p>
00117  * @param slcSet slice set indexed in a BitSet.
00118  * @param catches a vector of {@link Annotation Annotation}.
00119  * @param stmtList statement list for indexing.
00120  */
00121 private void addCatchesToSliceSet(BitSet slcSet, Vector catches, StmtList stmtList) {
00122     for (Enumeration e2 = catches.elements(); e2.hasMoreElements();) {
00123         Annotation catchClauseCFANN = (Annotation) e2.nextElement();
00124         Stmt trapStmts[] = catchClauseCFANN.getStatements();
00125         for (int i = 0; i < trapStmts.length; i++) {
00126             slcSet.set(stmtList.indexOf(trapStmts[i]));
00127             if (i == 0) {
00128                 Stmt caughtStmt = trapStmts[0];
00129                 if (caughtStmt instanceof IdentityStmt) {
00130                     IdentityStmt idCaughtStmt = (IdentityStmt) caughtStmt;
00131                     Value leftOp = idCaughtStmt.getLeftOp();
00132                     Value rightOp = idCaughtStmt.getRightOp();
00133                     if (leftOp instanceof Local) {
00134                         Local leftOpValue = (Local) leftOp;
00135                         Type valueType = leftOpValue.getType();
00136                         String exceptionName = valueType.toString();
00137                         if (!exceptionName.startsWith("java.lang."))
00138                         this.relevantExceptionClassNames.add(exceptionName);
00139                         //System.out.println("left value type: " + valueType);
00140                     }
00141                     /*
00142                     if (rightOp instanceof CaughtExceptionRef) {
00143                         CaughtExceptionRef rightOpEx = (CaughtExceptionRef) rightOp;
00144                         Type caughtType = rightOpEx.getType();
00145                         //System.out.println("Caught tyep: " + caughtType);
00146                     }
00147                     */
00148                 }
00149             }
00150         }
00151     }
00152 }
00153 /**
00154  * Get all variables appeared in one statement.
00155  * <p>
00156  * @return a set of {@link Value Value}.
00157  * @param stmt query statement.
00158  */
00159 static Set allVarsOf(Stmt stmt) {
00160     Set buff = new ArraySet();
00161     for (Iterator useBoxIt = stmt.getUseAndDefBoxes().iterator(); useBoxIt.hasNext();)
00162         buff.add(((ValueBox) useBoxIt.next()).getValue());
00163     return buff;
00164 }
00165   /**
00166    * Chang arguments of an invoke expression.
00167    * <br> Since parameters of the invoked method has been changed 
00168    * because of slicing: some of the parameter has been discarded
00169    * due to irrelevance, correspondingly all invoke expression
00170    * to that method should also be changed in arguments.
00171    * <br> For example, given one sliced method like:
00172    * <br> <code> method(farg1, farg3)</code>
00173    * <br> , the original invoke expression is
00174    * <br> <code> obj.method(aarg1, aarg2, aarg3)</code>
00175    * <br> and it has been modified, in terms of sliced method
00176    * declaration, into
00177    * <br> <code>obj.method(aarg1, aarg3, aarg3)</code>
00178    * <br> This mehtod is to change the argument number from 
00179    * 3 to 2, for example, to make the invoke expression
00180    * be consistent with the method declaration:
00181    * <br> <code>obj.method(aarg1, aarg3)</code>
00182    * <p>
00183    * @param inovkeExpr invoke expression.
00184    */
00185   private InvokeExpr buildNewInvokeExpr(InvokeExpr invokeExpr)
00186     {
00187       //InvokeExpr newInvokeExpr = null;
00188 
00189       SootMethod invokedMethod = invokeExpr.getMethod();
00190       int paraCount = invokedMethod.getParameterCount();
00191       //List argList = new ArrayList();
00192       for (int i=0; i<paraCount; i++)
00193         //argList.add(i,invokeExpr.getArg(i));
00194         invokeExpr.setArg(i, invokeExpr.getArg(i));
00195       invokeExpr.setArgCount(paraCount);
00196       /*
00197       if (invokeExpr instanceof VirtualInvokeExpr)
00198     {
00199       VirtualInvokeExpr virtualInvokeExpr = 
00200         (VirtualInvokeExpr) invokeExpr;
00201       newInvokeExpr = Jimple.v().newVirtualInvokeExpr(
00202                           (Local) virtualInvokeExpr.getBase(),
00203                       invokedMethod,
00204                       argList);
00205     }
00206       else if (invokeExpr instanceof StaticInvokeExpr)
00207     {
00208       newInvokeExpr =
00209         Jimple.v().newStaticInvokeExpr(invokedMethod, argList);
00210     }
00211       else if (invokeExpr instanceof SpecialInvokeExpr)
00212     {
00213       SpecialInvokeExpr specialInvoke = (SpecialInvokeExpr) invokeExpr;
00214       newInvokeExpr =
00215         Jimple.v().newSpecialInvokeExpr((Local) specialInvoke.getBase(),
00216                         invokedMethod, 
00217                         argList);
00218     }
00219       */
00220       return invokeExpr;
00221     }
00222   /**
00223    * Process parameters of a call site in slice. Change parameters of an invoke expression
00224    * in terms of changes in called method.
00225    * <p>
00226    * @param callSiteIndexMap a map from {@link Stmt Stmt} to {@link CallSite CallSite}.
00227    * @param callSiteMap a map from {@link CallSite CallSite} to {@link SootMethod SootMethod}.
00228    * @param stmt a statement with an invoke expression.
00229    * <p>
00230    * @see {#buildNewInvokeExpr(InvokeExpr)}
00231    */
00232 private void callSiteInSlice(Map callSiteIndexMap, Map callSiteMap, Stmt stmt) {
00233     CallSite callSite = (CallSite) callSiteIndexMap.get(stmt);
00234     SootMethod callee = (SootMethod) callSiteMap.get(callSite);
00235     MethodInfo calleeMdInfo = (MethodInfo) Slicer.sootMethodInfoMap.get(callee);
00236     if (calleeMdInfo == null) return;
00237     if (calleeMdInfo.sCriterion == null) {
00238     } else {
00239         LinkedList keepedParaOriginalIndex = getKeepedParaOriginalIndex(calleeMdInfo);
00240         InvokeExpr invokeExpr = callSite.invokeExpr;
00241         int argCount = invokeExpr.getArgCount();
00242         LinkedList keepedParameters = new LinkedList();
00243         for (int i = 0; i < argCount; i++) {
00244             Value arg = invokeExpr.getArg(i);
00245             if (keepedParaOriginalIndex.contains(new Integer(i)))
00246                 keepedParameters.addLast(arg);
00247         }
00248         if (keepedParameters.size() < argCount) {
00249             for (int i = 0; i < keepedParameters.size(); i++)
00250                 invokeExpr.setArg(i, (Value) keepedParameters.get(i));
00251         }
00252     }
00253 }
00254   /**
00255    * Change the target of a control transferring statement, if that target is 
00256    * not in slice. For example,
00257    * <br> ...;
00258    * <br> goto label-1;
00259    * <br> ....
00260    * <br> label-1: stmt;
00261    * <br> .....
00262    * <br> if the statement <code>label-1: stmt</code> is not in slice, 
00263    * while <code>goto label-1</code> is in slice, then <code>label-1</code>
00264    * should be changed to its immediate postdominator.
00265    * <p>
00266    * @param stmtList statement list for indexing.
00267    * @param newTarget new target.
00268    * @param oldTarget old target.
00269    * @param jumpTargetMap a map from jump target {@link Stmt Stmt} to jump sources of the 
00270    * target {@link BitSet BitSet}.
00271    */
00272 private void changeTarget(StmtList stmtList, Stmt newTarget, Stmt oldTarget, Map jumpTargetMap) {
00273   //System.out.println("newTarget: " + newTarget);
00274   //System.out.println("oldTarget: " + oldTarget);
00275     BitSet jumpSources = (BitSet) jumpTargetMap.get(oldTarget);
00276     for (int h = 0; h < jumpSources.size(); h++) {
00277         if (!jumpSources.get(h))
00278             continue;
00279         Stmt jumpSource = (Stmt) stmtList.get(h);
00280         if (jumpSource instanceof GotoStmt)
00281              ((GotoStmt) jumpSource).setTarget(newTarget);
00282         else
00283             if (jumpSource instanceof IfStmt)
00284                  ((IfStmt) jumpSource).setTarget(newTarget);
00285     }
00286     jumpTargetMap.remove(oldTarget);
00287     if (jumpTargetMap.containsKey(newTarget)) {
00288         BitSet sources = (BitSet) jumpTargetMap.get(newTarget);
00289         sources.or(jumpSources);
00290     } else
00291         jumpTargetMap.put(newTarget, jumpSources);
00292 }
00293 /**
00294  * See if all statements in an array of statement are not in a slice set.
00295  * <p>
00296  * @return <code>true</code> if all statements in the array are not in the slice set,
00297  * <code>false</code> otherwise.
00298  * @param bodyStmts an array of statement.
00299  * @param sliceSet slice set.
00300  * @param stmtList statement list for indexing.
00301  */
00302 private boolean emptyBody(Stmt[] bodyStmts, BitSet sliceSet, StmtList stmtList) {
00303     for (int i = 0; i < bodyStmts.length; i++) {
00304         if (sliceSet.get(stmtList.indexOf(bodyStmts[i])))
00305             return false;
00306     }
00307     return true;
00308 }
00309 /**
00310  * See if all statements in a set of statement are not in a slice set.
00311  * <p>
00312  * @return <code>true</code> if all statements in the set are not in the slice set,
00313  * <code>false</code> otherwise.
00314  * @param bodyStmts a set of statement.
00315  * @param sliceSet slice set.
00316  * @param stmtList statement list for indexing.
00317  */
00318 private boolean emptyBody(Set bodyStmts, BitSet sliceSet, StmtList stmtList) {
00319     for (Iterator i = bodyStmts.iterator(); i.hasNext();) {
00320         Stmt stmt = (Stmt) i.next();
00321         if (sliceSet.get(stmtList.indexOf(stmt)))
00322             return false;
00323     }
00324     return true;
00325 }
00326 /**
00327  * Collect soot fields from a set of field references.
00328  * <p>
00329  * @param fieldRefSet a set of {@link FieldRef FieldRef}.
00330  * @return a set of {@link SootField SootField}.
00331  */
00332 private Set fieldRefToField(Set fieldRefSet) {
00333     Set fieldSet = new ArraySet();
00334     for (Iterator refIt = fieldRefSet.iterator(); refIt.hasNext();)
00335         fieldSet.add(((FieldRef) refIt.next()).getField());
00336     return fieldSet;
00337 }
00338 //filering from used variable instead of relevant variabls
00339 /**
00340    * Collect all {@link FieldRef FieldRef} from a set of {@link Value Value}
00341    * into the field {@link #relevantFields relevantFields}.
00342    * <p>
00343    * @param variableSet a set of {@link Value Value}.
00344    */
00345 private void filterOutFields(Set variableSet) {
00346     for (Iterator kk = variableSet.iterator(); kk.hasNext();) {
00347         Value loc = (Value) kk.next();
00348         if (loc instanceof FieldRef)
00349             relevantFields.add(loc);
00350     }
00351 }
00352 /**
00353    * Get all {@link Value Value} used/defined in a set of statements.
00354    * <p>
00355    * @param ostmtList statement list for indexing.
00356    * @param stmtIndexSet a set of statements.
00357    * @return a set of {@link Value Value}
00358    */
00359 static Set getAllVarsOf(StmtList ostmtList, BitSet stmtIndexSet) {
00360     Set allVars = new ArraySet();
00361     for (int i = 0; i < stmtIndexSet.size(); i++) {
00362         if (!stmtIndexSet.get(i))
00363             continue;
00364         Stmt stmt = (Stmt) ostmtList.get(i);
00365         allVars.addAll(allVarsOf(stmt));
00366     }
00367     return allVars;
00368 }
00369   /**
00370    * Get all {@link Value Value} used/defined in a method body.
00371    * <p>
00372    * @param mdInfo query method.
00373    * @return a set {@link Value Value}
00374    */
00375 private Set getAllVarsOf(MethodInfo mdInfo) {
00376     StmtList originalStmtList = mdInfo.originalStmtList;
00377     Set allVars = new ArraySet();
00378     for (int i = 0; i < originalStmtList.size(); i++) {
00379         Stmt stmt = (Stmt) originalStmtList.get(i);
00380         allVars.addAll(allVarsOf(stmt));
00381     }
00382     return allVars;
00383 }
00384   /**
00385    * Get residual parameters for a method.
00386    * <p>
00387    * @param mdInfo query method.
00388    * @return a {@link LinkedList LinkedList} of Integer which
00389    * is the index of parameter.
00390    */
00391 private LinkedList getKeepedParaOriginalIndex(MethodInfo mdInfo) {
00392     Local paraLocals[] = mdInfo.indexMaps.getParaLocalSet();
00393     Map relevantVars = mdInfo.sCriterion.relVarMap();
00394     Set relLocs = getRelevantLocals(mdInfo.originalStmtList, mdInfo.sliceSet, relevantVars);
00395     LinkedList keepedParaOriginalIndex = new LinkedList();
00396     for (int i = 0; i < paraLocals.length; i++) {
00397         Local paraLocal = paraLocals[i];
00398         if (relLocs.contains(paraLocal)) {
00399             keepedParaOriginalIndex.addLast(new Integer(i));
00400         }
00401     }
00402     return keepedParaOriginalIndex;
00403 }
00404   /**
00405    * Get new jump target from a given current target. The new target should
00406    * be the immediate postdominator of current target.
00407    * <p>
00408    * @param currentTarget index of current target (statement).
00409    * @param bpdg PDG for the method for getting immediate postdominator.
00410    * @param rmStmtSet a set statement which should not be in residual program.
00411    * @return the index of new target.
00412    */
00413 private int getNewJumpTarget(int currentTarget, BuildPDG bpdg, BitSet rmStmtSet) {
00414     int newTarget = -1;
00415     boolean foundNewTarget = false;
00416 
00417     while (!foundNewTarget) {
00418         newTarget = bpdg.immediatePostdominatorOf(currentTarget);
00419         if (newTarget<0) newTarget = currentTarget+1;
00420         if (rmStmtSet.get(newTarget))
00421             currentTarget = newTarget;
00422         else
00423             foundNewTarget = true;
00424     }
00425     return newTarget;
00426 }
00427 /**
00428 * Get all relevant variables in given slice set.
00429 * <p>
00430 * @param stmtList statement list for indexing.
00431 * @param sliceSet slice set indexed with statement list.
00432 * @param relevantVars a map of relevant variables for every statement,
00433 * from {@link Stmt Stmt} to a {@link Set Set} of {@link Value Value}.
00434 */
00435 static Set getRelevantLocals(StmtList stmtList, BitSet sliceSet, Map relevantVars) {
00436     Set relLocs = new ArraySet();
00437     for (int i = 0; i < sliceSet.size(); i++) {
00438         if (!sliceSet.get(i))
00439             continue;
00440         Set stmtRelLocs = (Set) relevantVars.get((Stmt) stmtList.get(i));
00441         if (stmtRelLocs != null)
00442             relLocs.addAll(stmtRelLocs);
00443     }
00444     return relLocs;
00445 }
00446   /**
00447    * Get all trap hanlders from jimple body.
00448    * <p>
00449    * @param jimpBody jimple body
00450    * @return a set of {@link Stmt Stmt} which is trap handler.
00451    */
00452 private Set getTrapHandlers(JimpleBody jimpBody) {
00453     Set trapsHandlerSet = new ArraySet();
00454     Iterator trapIt = jimpBody.getTraps().iterator();
00455     while (trapIt.hasNext()) {
00456         Trap trap = (Trap) trapIt.next();
00457         Stmt handler = (Stmt) trap.getHandlerUnit();
00458         trapsHandlerSet.add(handler);
00459     }
00460     return trapsHandlerSet;
00461 }
00462 /**
00463  * Insert the method's description here.
00464  * Creation date: (00-11-14 11:18:28)
00465  * @return boolean
00466  * @param superClass ca.mcgill.sable.soot.SootClass
00467  * @param sm ca.mcgill.sable.soot.SootMethod
00468  */
00469 private boolean isImplementingOneAbstractMd(SootClass superClass, SootMethod sm) {
00470     int modifiers = superClass.getModifiers();
00471     if (!Modifier.isAbstract(modifiers))
00472         return false;
00473     SootMethod abstractMd = null;
00474     try {
00475         abstractMd = superClass.getMethod(sm.getName(), sm.getParameterTypes(), sm.getReturnType());
00476     } catch (ca.mcgill.sable.soot.NoSuchMethodException nse) {
00477         return false;
00478     }
00479     modifiers = abstractMd.getModifiers();
00480     if (Modifier.isAbstract(modifiers))
00481         return true;
00482     return false;
00483 }
00484 /**
00485  * Insert the method's description here.
00486  * Creation date: (00-11-14 10:59:21)
00487  * @return boolean
00488  * @param sm ca.mcgill.sable.soot.SootMethod
00489  */
00490 private boolean isImplementingOneAbstractMd(SootMethod sm) {
00491     boolean isImplementingMd = false;
00492     SootClass declaringClass = sm.getDeclaringClass();
00493     while (declaringClass.hasSuperClass()) {
00494         SootClass superClass = declaringClass.getSuperClass();
00495         isImplementingMd = isImplementingOneAbstractMd(superClass, sm);
00496         if (isImplementingMd)
00497             return isImplementingMd;
00498         declaringClass = superClass;
00499     }
00500     for (Iterator interfaceIt = declaringClass.getInterfaces().iterator(); interfaceIt.hasNext();) {
00501         SootClass interfaceClass = (SootClass) interfaceIt.next();
00502         isImplementingMd = isImplementingOneInterfaceMd(interfaceClass, sm);
00503         if (isImplementingMd)
00504             return isImplementingMd;
00505         while (interfaceClass.hasSuperClass()) {
00506             SootClass superClass = interfaceClass.getSuperClass();
00507             isImplementingMd = isImplementingOneInterfaceMd(interfaceClass, sm);
00508             if (isImplementingMd)
00509                 return isImplementingMd;
00510         }
00511     }
00512     return isImplementingMd;
00513 }
00514 /**
00515  * Insert the method's description here.
00516  * Creation date: (00-11-14 11:29:00)
00517  * @return boolean
00518  * @param interfaceClas ca.mcgill.sable.soot.SootClass
00519  * @param sm ca.mcgill.sable.soot.SootMethod
00520  */
00521 private boolean isImplementingOneInterfaceMd(SootClass interfaceClass, SootMethod sm) {
00522     int modifiers = interfaceClass.getModifiers();
00523     if (!Modifier.isInterface(modifiers))
00524         return false;
00525     try {
00526         SootMethod abstractMd = interfaceClass.getMethod(sm.getName(), sm.getParameterTypes(), sm.getReturnType());
00527     } catch (ca.mcgill.sable.soot.NoSuchMethodException nse) {
00528         return false;
00529     }
00530     return true;
00531 }
00532   /**
00533    * See if a given modifier is public and static.
00534    * <p>
00535    * @param modifier modifier.
00536    * @return boolean.
00537    */
00538   private boolean isPublicAndStatic(int modifier)
00539     {
00540       if (Modifier.isPublic(modifier) && 
00541       Modifier.isStatic(modifier)) 
00542     return true;
00543       else return false;
00544     }
00545   /**
00546    * Keep all parameters for <code>main</code> method, even those parameters are irrelevant.
00547    * <p>
00548    * @param mdInfo query method.
00549    * @param relevantVars relevant variables map.
00550    * @param stmtList statement list
00551    * @param sliceSet slice set.
00552    */
00553 private void keepParasOfMainMd(MethodInfo mdInfo, Map relevantVars, StmtList stmtList, BitSet sliceSet) {
00554     //to see if there is main method and then keep all parameter identity statement.
00555 
00556     if (mdInfo.sootMethod.getName().equals("main") && isPublicAndStatic(mdInfo.sootMethod.getModifiers())) {
00557         Stmt[] paraIds = mdInfo.indexMaps.getParaIdentityStmts();
00558 
00559         //add all parameter identitise into slice set of main method
00560         for (int ids = 0; ids < paraIds.length; ids++) {
00561             int idIndex = stmtList.indexOf(paraIds[ids]);
00562             sliceSet.set(idIndex);
00563             relevantVars.put(paraIds[ids], SlicingMethod.allLocalVarsOf(paraIds[ids]));
00564         }
00565     }
00566 }
00567 /**
00568  * Insert the method's description here.
00569  * Creation date: (00-11-14 13:21:07)
00570  * @param sm ca.mcgill.sable.soot.SootMethod
00571  */
00572 private void makeMethodEmpty(MethodInfo methodInfo, Annotation annForSm) {
00573     if (methodInfo == null)
00574         return;
00575     IndexMaps indexMaps = methodInfo.indexMaps;
00576     Set removableStmts = new ArraySet();
00577     Set keepStmts = new ArraySet();
00578     int thisRefStmtIndex = indexMaps.getThisRefStmtIndex().intValue();
00579     Stmt thisRefStmt = (Stmt) methodInfo.stmtList.get(thisRefStmtIndex);
00580     Stmt[] paraIdentities = indexMaps.getParaIdentityStmts();
00581     //extract return statement and assignment to $ret
00582     Stmt returnStmt = null;
00583     Stmt ret$Stmt = null;
00584     Object[] returnAnns = indexMaps.getReturnAnnotations().toArray();
00585     if (returnAnns.length > 0) {
00586         Stmt[] returnStmts = ((Annotation) returnAnns[0]).getStatements();
00587         Type returnType = methodInfo.sootMethod.getReturnType();
00588         if (returnType instanceof VoidType) {
00589             for (int i = 0; i < returnStmts.length; i++) {
00590                 if (returnStmts[i] instanceof ReturnVoidStmt) {
00591                     returnStmt = returnStmts[i];
00592                     break;
00593                 }
00594             }
00595         } else
00596             for (int i = 0; i < returnStmts.length; i++) {
00597                 if (returnStmts[i] instanceof ReturnStmt)
00598                     returnStmt = returnStmts[i];
00599                 else
00600                     if (returnStmts[i] instanceof AssignStmt) {
00601                         Value leftOp = ((AssignStmt) returnStmts[i]).getLeftOp();
00602                         if (leftOp instanceof Local)
00603                             if (((Local) leftOp).getName().equals("$ret"))
00604                                 ret$Stmt = returnStmts[i];
00605                     }
00606             }
00607     }
00608     // calculate keeped statement set
00609     keepStmts.add(thisRefStmt);
00610     if (returnStmt != null)
00611         keepStmts.add(returnStmt);
00612     if (ret$Stmt != null)
00613         keepStmts.add(ret$Stmt);
00614     for (int i = 0; i < paraIdentities.length; i++)
00615         keepStmts.add(paraIdentities[i]);
00616     //calculate removable statements
00617     for (Iterator stmtIt = methodInfo.stmtList.iterator(); stmtIt.hasNext();) {
00618         Stmt stmt = (Stmt) stmtIt.next();
00619         if (!keepStmts.contains(stmt))
00620             removableStmts.add(stmt);
00621     }
00622     //remove statement from annotation
00623     for (Iterator stmtIt = removableStmts.iterator(); stmtIt.hasNext();) {
00624         try {
00625             annForSm.removeStmt((Stmt) stmtIt.next());
00626         } catch (Exception e) {
00627         }
00628     }
00629     //remove statement from statement list
00630     if (!removableStmts.isEmpty())
00631         for (Iterator stmtIt = removableStmts.iterator(); stmtIt.hasNext();)
00632             methodInfo.stmtList.remove(stmtIt.next());
00633         //change assignment statement $ret=value into $ret=null;
00634     if (ret$Stmt != null) {
00635         NullConstant nullCons = NullConstant.v();
00636         Value leftOp = ((AssignStmt) ret$Stmt).getLeftOp();
00637         AssignStmt newRetAssign = Jimple.v().newAssignStmt(leftOp, nullCons);
00638         int k = methodInfo.stmtList.indexOf(ret$Stmt);
00639         methodInfo.stmtList.remove(k);
00640         try {
00641             cfanns.putInlineStmt(newRetAssign, ret$Stmt, methodInfo.sootMethod);
00642             annForSm.replaceStmt(ret$Stmt, newRetAssign);
00643         } catch (Exception e) {
00644         }
00645         methodInfo.stmtList.add(k, newRetAssign);
00646     }
00647 }
00648   /**
00649    * Modify jump target map in terms of a changed statement map.
00650    * <p>
00651    * @param stmtList statement list.
00652    * @param changedStmtMap a map from {@link Stmt Stmt} to {@link Stmt Stmt}.
00653    * @param jumpTargetMap jump target map.
00654    */
00655 private void modifyJumpTargetMap(StmtList stmtList, Map changedStmtMap, Map jumpTargetMap) {
00656     for (Iterator changedStmtIt = changedStmtMap.keySet().iterator();
00657     changedStmtIt.hasNext();) {
00658         Stmt changedStmt = (Stmt) changedStmtIt.next();
00659         if (jumpTargetMap.containsKey(changedStmt)) {
00660             Stmt newTarget = (Stmt) changedStmtMap.get(changedStmt);
00661             changeTarget(stmtList, newTarget, changedStmt, jumpTargetMap);
00662         }
00663     }
00664 }
00665 /**
00666    * Construct residual method.
00667    * <p>
00668    * @param mdInfo method to be constructed.
00669    */
00670 private void modifyMethod(MethodInfo mdInfo) {
00671     JimpleBody jimpBody = (JimpleBody) mdInfo.sootMethod.getBody(Jimple.v());
00672     StmtList stmtList = mdInfo.stmtList;
00673     StmtList stmtListClone = mdInfo.originalStmtList;
00674     BitSet sliceSet = mdInfo.sliceSet;
00675     int stmtListSize = stmtListClone.size();
00676     Map jumpTargetMap = mdInfo.indexMaps.getJumpTargetMap();
00677     Integer thisRefIndex = mdInfo.indexMaps.getThisRefStmtIndex();
00678     Integer specialInvokeIndex = null;
00679 
00680     //add for every instance method this reference stmt to initSliceSet required by Robby 1/7/2000
00681 
00682     if (thisRefIndex != null)
00683         sliceSet.set(thisRefIndex.intValue());
00684     /*
00685     //to see if the method is <init method, if it is, include the special
00686     //invoke into the slice set
00687     if (mdInfo.sootMethod.getName().equals("<init>")) {
00688     for (Iterator si = mdInfo.indexMaps.getSpecialInvokeList().iterator(); si.hasNext();) {
00689     SpecialInvokeStmt invoke = (SpecialInvokeStmt) si.next();
00690     SpecialInvokeExpr specInvoke = (SpecialInvokeExpr) invoke.invokeExpr;
00691     if (mdInfo.indexMaps.getThisRefLocal().equals(specInvoke.getBase())) {
00692     if (specInvoke.getMethod().getName().equals("<init>")) {
00693     if (mdInfo.sootClass.getSuperClass().equals(specInvoke.getMethod().getDeclaringClass())) {
00694     int specialInvokeInt = stmtListClone.indexOf(invoke.invokeStmt);
00695     specialInvokeIndex = new Integer(specialInvokeInt);
00696     sliceSet.set(specialInvokeInt);
00697     }
00698     }
00699     }
00700     
00701     //String specSignature = invoke.invokeExpr.getMethod().getSignature();
00702     //if (specSignature.startsWith("java.lang")) {
00703     //int specialInvokeInt = stmtListClone.indexOf(invoke.invokeStmt);
00704     //specialInvokeIndex = new Integer(specialInvokeInt);
00705     //sliceSet.set(specialInvokeInt);
00706     //}
00707     
00708     }
00709     }
00710     }
00711     */
00712     Map changedStmtMap = new HashMap();
00713     BuildPDG pdg = mdInfo.methodPDG;
00714     Map relevantVars = mdInfo.sCriterion.relVarMap();
00715     Map callSiteMap = mdInfo.indexMaps.getCallSiteMap();
00716     Map callSiteIndexMap = SlicingMethod.callSiteIndex(callSiteMap);
00717     BitSet stmtIndexToNop = new BitSet(stmtListSize);
00718     BitSet removedStmtIndexSet = new BitSet(stmtListSize);
00719     StmtGraph sg = mdInfo.indexMaps.getStmtGraph();
00720     Set trapsHandlerSet = getTrapHandlers(jimpBody);
00721     SootMethod sm = mdInfo.sootMethod;
00722     SootClass sootClass = mdInfo.sootClass;
00723     Annotation annForSm = cfanns.getAnnotation(sootClass, sm);
00724     Vector currentCFANNs = annForSm.getAllAnnotations(true);
00725     keepParasOfMainMd(mdInfo, relevantVars, stmtList, sliceSet);
00726     Set removedStmtByEmptyBlock = new ArraySet();
00727 
00728     /*  
00729     if (mdInfo.sootClass.getName().equals("Consumer") && mdInfo.sootMethod.getName().equals("run")){
00730     System.out.println("Consumer.run");
00731     }
00732     */
00733     removeEmptyBlock(mdInfo, removedStmtByEmptyBlock, currentCFANNs, stmtList, jimpBody);
00734 
00735     //get relevant variables from sliceSet
00736     Set relLocs = getRelevantLocals(stmtList, sliceSet, relevantVars);
00737     boolean changedReturnToVoid = false;
00738     //operating on stmtList, using stmtListClone to index
00739     for (int k = 0; k < stmtList.size(); k++) {
00740         Stmt stmt = (Stmt) stmtList.get(k);
00741         int stmtIndex = stmtListClone.indexOf(stmt);
00742         if (sliceSet.get(stmtIndex)) {
00743             if (thisRefIndex != null) {
00744                 if (stmtIndex == thisRefIndex.intValue())
00745                     continue;
00746             }
00747             if (specialInvokeIndex != null) {
00748                 if (stmtIndex == specialInvokeIndex.intValue())
00749                     continue;
00750             }
00751             if (stmt instanceof ReturnStmt) {
00752 
00753                 //at this moment we only consider the return value is just
00754                 //a local variable
00755                 Value retVal = ((ReturnStmt) stmt).getReturnValue();
00756                 if (!(retVal instanceof Local)) {
00757                     if (changedReturnToVoid) {
00758                         //change return stmt to return void stmt
00759                         Stmt s = (Stmt) stmtList.remove(k);
00760                         ReturnVoidStmt rtvs = Jimple.v().newReturnVoidStmt();
00761                         try {
00762                             cfanns.putInlineStmt(rtvs, s, mdInfo.sootMethod);
00763                             annForSm.replaceStmt(s, rtvs);
00764                         } catch (Exception e) {
00765                         }
00766                         stmtList.add(k, rtvs);
00767                         changedStmtMap.put(stmt, rtvs);
00768 
00769                         //change return type of the method into void
00770                         changeReturnTypeToVoidMds.add(mdInfo.sootMethod);
00771                     }
00772                 } else
00773                     if (retVal instanceof Local) {
00774                         if (relLocs.contains(retVal)) {
00775                         } else {
00776                             //change return stmt to return void stmt
00777                             Stmt s = (Stmt) stmtList.remove(k);
00778                             ReturnVoidStmt rtvs = Jimple.v().newReturnVoidStmt();
00779                             try {
00780                                 //annForSm.replaceStmt(s, rtvs);
00781                                 cfanns.putInlineStmt(rtvs, s, mdInfo.sootMethod);
00782                                 annForSm.replaceStmt(s, rtvs);
00783                             } catch (Exception e) {
00784                             }
00785                             stmtList.add(k, rtvs);
00786                             changedStmtMap.put(stmt, rtvs);
00787 
00788                             //change return type of the method into void
00789                             changeReturnTypeToVoidMds.add(mdInfo.sootMethod);
00790                             changedReturnToVoid = true;
00791                         }
00792                     }
00793                     //previous part is for method need to change return value to return void.
00794             } else
00795                 if (trapsHandlerSet.contains(stmt)) {
00796                 } else
00797                     if (callSiteIndexMap.containsKey(stmt)) {
00798                         callSiteInSlice(callSiteIndexMap, callSiteMap, stmt);
00799                     } else {
00800                         Set allRefVariablesInStmt = SlicingMethod.refVarsOf(stmt);
00801                         //Set allVariablesInStmt = allLocalVarsOf(stmt, sg);        
00802                         //if (SetUtil.setIntersection(allVariablesInStmt, relLocs).size() !=0 
00803                         if (relLocs.containsAll(allRefVariablesInStmt) || (stmt instanceof ThrowStmt) || (stmt instanceof ReturnVoidStmt)) {
00804                         } else {
00805 
00806                             //it must be a line proposition without relvant variables
00807                             //we can change it to nop
00808                             //and can not be removed after refining
00809 
00810                             //the line proposition can be checked in slicing stage, and let them be not in initial slice set, the problem is that if there is some statement on which the line propostion control depend on , so we decide to omit the line proposition statement and change it into nops
00811 
00812                             stmtIndexToNop.set(stmtIndex);
00813                             Stmt nopStmt = Jimple.v().newNopStmt();
00814                             Stmt s = (Stmt) stmtList.remove(k);
00815                             try {
00816                                 cfanns.putInlineStmt(nopStmt, s, mdInfo.sootMethod);
00817                                 annForSm.replaceStmt(s, nopStmt);
00818                             } catch (Exception e) {
00819                             }
00820                             stmtList.add(k, nopStmt);
00821                             changedStmtMap.put(stmt, nopStmt);
00822                         }
00823                     }
00824         } else {
00825             //stmt not in slice
00826             if ((stmt instanceof GotoStmt) && !removedStmtByEmptyBlock.contains(stmt)) {
00827             } else
00828                 if (stmt instanceof ReturnStmt) {
00829 
00830                     //at this moment we only consider the return value is just
00831                     //a local variable
00832                     Value retVal = ((ReturnStmt) stmt).getReturnValue();
00833                     /*
00834                     if (!(retVal instanceof Local)) {
00835                     } else
00836                     */
00837                     if (retVal instanceof Local) {
00838                         if (!relLocs.contains(retVal)) {
00839                             //} else {
00840                             //change return stmt to return void stmt
00841                             Stmt s = (Stmt) stmtList.remove(k);
00842                             ReturnVoidStmt rtvs = Jimple.v().newReturnVoidStmt();
00843                             try {
00844                                 cfanns.putInlineStmt(rtvs, s, mdInfo.sootMethod);
00845                                 annForSm.replaceStmt(s, rtvs);
00846                             } catch (Exception e) {
00847                             }
00848                             stmtList.add(k, rtvs);
00849                             changedStmtMap.put(stmt, rtvs);
00850                             //stmtList.set ...
00851 
00852                             //change return type of the method into void
00853                             changeReturnTypeToVoidMds.add(mdInfo.sootMethod);
00854                         }
00855                     }
00856                 } else
00857                     if ((stmt instanceof ReturnVoidStmt) || (stmt instanceof RetStmt)) {
00858                     } else {
00859                         //change current stmt into nop if debug
00860                         //remove current stmt from stmtList
00861                         try {
00862                             annForSm.removeStmt((Stmt) stmtList.remove(k));
00863                         } catch (Exception e) {
00864                         }
00865                         k--;
00866                         //remove it from source set of the jump target map
00867                         removeSourceFor(jumpTargetMap, stmtIndex);
00868                         //if the removing stmt is a target of some jumps, we should
00869                         //change all the target of those jumps to the immediate post
00870                         //dominator of the current target
00871 
00872                         if (jumpTargetMap.containsKey(stmt)) {
00873                             int newTargetIndex = getNewJumpTarget(stmtIndex, pdg, removedStmtIndexSet);
00874                             //System.out.println("newTargetIndex: " + newTargetIndex);
00875                             //System.out.println("stmt list size: " + stmtListClone.size());
00876                             if (newTargetIndex < stmtListClone.size()) {
00877                                 //newTargetIndex = stmtListClone.size()-1;
00878                                 Stmt newTarget = (Stmt) stmtListClone.get(newTargetIndex);
00879                                 changeTarget(stmtListClone, newTarget, stmt, jumpTargetMap);
00880                             }
00881                         }
00882                         removedStmtIndexSet.set(stmtIndex);
00883                     }
00884         }
00885     }
00886 
00887     /*
00888     //* test for stmtgraph
00889     try {
00890     System.out.println("method: " + mdInfo.sootMethod);
00891     System.out.println("stmtList: " + stmtList);
00892     StmtGraph sgraph = new CompleteStmtGraph(stmtList);
00893     StmtBody sb = sgraph.getBody();
00894     List traps = sb.getTraps();
00895     System.out.println("traps: " + traps);
00896     sb.printTo(new PrintWriter(System.out));
00897     } catch (Throwable ee) {
00898     ee.printStackTrace();
00899     }
00900     */
00901     modifyJumpTargetMap(stmtListClone, changedStmtMap, jumpTargetMap);
00902     Set useAndDefVarsInSlice = getAllVarsOf(stmtListClone, SetUtil.bitSetAndNot(sliceSet, stmtIndexToNop));
00903 
00904     //filering from used variable instead of relevant variabls
00905     filterOutFields(useAndDefVarsInSlice);
00906 }
00907 /**
00908  * Insert the method's description here.
00909  * Creation date: (00-11-10 9:18:31)
00910  */
00911 private void relevantExceptionClasses() {
00912     Set relevantExceptionClassInfo = new ArraySet();
00913     if (relevantExceptionClassNames.isEmpty())
00914         return;
00915     for (Iterator classIt = classList.iterator(); classIt.hasNext();) {
00916         ClassInfo classInfo = (ClassInfo) classIt.next();
00917         String className = classInfo.sootClass.getName();
00918         if (this.relevantExceptionClassNames.contains(className))
00919             relevantExceptionClassInfo.add(classInfo);
00920     }
00921     /*
00922     if (relevantExceptionClassInfo.isEmpty())
00923         throw new SlicerException("Could not find any class information for all relevant exception classes.");
00924     if (relevantExceptionClassInfo.size() != relevantExceptionClassNames.size())
00925         throw new SlicerException("Could not find class information for some relevant exception classes.");
00926         */
00927     for (Iterator classIt = relevantExceptionClassInfo.iterator(); classIt.hasNext();) {
00928         ClassInfo classInfo = (ClassInfo) classIt.next();
00929         if (this.removableClasses.contains(classInfo))
00930             this.removableClasses.remove(classInfo);
00931     }
00932 }
00933 /**
00934    * Filter out the classes such that there is no method left in the class, but there are
00935    * some fields are relevant, i.e., accessible by other relvant classes. So those classes
00936    * are not removable.
00937    */
00938 private void relevantFDClass() {
00939     List restoredClasses = new ArrayList();
00940     for (Iterator listIt = removableClasses.iterator(); listIt.hasNext();) {
00941         ClassInfo classInfo = (ClassInfo) listIt.next();
00942         if (Slicer.isObjectClass(classInfo.sootClass))
00943             continue;
00944         for (Iterator i = relevantFields.iterator(); i.hasNext();) {
00945             FieldRef oneField = (FieldRef) i.next();
00946             SootClass declareClass = oneField.getField().getDeclaringClass();
00947             if (classInfo.sootClass.equals(declareClass))
00948                 if (!restoredClasses.contains(classInfo))
00949                     restoredClasses.add(classInfo);
00950         }
00951     }
00952     removableClasses.removeAll(restoredClasses);
00953 
00954 }
00955   /**
00956    * Remove all empty block in one method. 
00957    * It's including: <code> removeEmptyLock, removeEmeptyTry, removeEmptyTryFinally, 
00958    * removeEmptyConditionalBlock</code>.
00959    * <p>
00960    * @param mdInfo query method.
00961    * @param rmedStmtByEmptBlck a set of statement removed.
00962    * @param currentCFANNS a vector of annotations need to be analysed.
00963    * @param stmtList statement list.
00964    */
00965 private void removeEmptyBlock(MethodInfo mdInfo, Set rmedStmtByEmptBlck, Vector currentCFANNs, StmtList stmtList, JimpleBody jimpleBody) {
00966     //remove empty lock pair: entermonitor and exitmonitor
00967     BitSet sliceSet = mdInfo.sliceSet;
00968     {
00969         LockAnalysis lockAna = mdInfo.methodPDG.getLockAnalysis();
00970         if (lockAna != null)
00971             removeEmptyLock(lockAna.getLockPairList(), sliceSet, mdInfo.sCriterion.getSlicePoints(), rmedStmtByEmptBlck, stmtList);
00972     }
00973     removeEmptyTry(currentCFANNs, sliceSet, mdInfo.sCriterion.getSlicePoints(), rmedStmtByEmptBlck,stmtList, jimpleBody);
00974     removeEmptyTryFinally(currentCFANNs, sliceSet, mdInfo.sCriterion.getSlicePoints(), rmedStmtByEmptBlck, stmtList, jimpleBody);
00975     removeEmptyConditionalBlock(currentCFANNs, sliceSet, mdInfo.sCriterion.getSlicePoints(), rmedStmtByEmptBlck, stmtList);
00976 
00977     //including removing empty sequential block   
00978 }
00979   /**
00980    * Remove empty conditional block.
00981    * <p>
00982    * @param currentCfanns a vector of annotations need to be analysed.
00983    * @param slcSet slice set.
00984    * @param linePropList a set of statement.
00985    * @param removedStmtByEmptyB removed statements.
00986    * @param stmtList statement list.
00987    */
00988 private void removeEmptyConditionalBlock(Vector currentCfanns, BitSet slcSet, Set linePropList, Set removedStmtByEmptyB, StmtList stmtList) {
00989     for (Enumeration e = currentCfanns.elements(); e.hasMoreElements();) {
00990         Annotation cfann = (Annotation) e.nextElement();
00991         if (cfann instanceof ConditionalAnnotation) {
00992             ConditionalAnnotation conditionalStmtAnn = (ConditionalAnnotation) cfann;
00993             Set condStmts = new ArraySet(conditionalStmtAnn.getStatements());
00994             Set bodyStmts = new ArraySet();
00995             bodyStmts.addAll(condStmts);
00996             Set testStmts = new ArraySet(conditionalStmtAnn.getTestStatements());
00997             bodyStmts.removeAll(testStmts);
00998             if (emptyBody(bodyStmts, slcSet, stmtList)) {
00999                 for (Iterator i = condStmts.iterator(); i.hasNext();) {
01000                     Stmt stmt = (Stmt) i.next();
01001                     if (linePropList.contains(stmt))
01002                         continue;
01003                     removedStmtByEmptyB.add(stmt);
01004                 }
01005             }
01006         } //end of if instanceof IfStmtAnnotation
01007         else
01008             if (cfann instanceof ControlFlowAnnotation) {
01009                 ControlFlowAnnotation controlFlowStmtAnn = (ControlFlowAnnotation) cfann;
01010                 Stmt bodyStmts[] = controlFlowStmtAnn.getBlockAnnotation().getStatements();
01011                 if (emptyBody(bodyStmts, slcSet, stmtList)) {
01012                     bodyStmts = controlFlowStmtAnn.getStatements();
01013                     for (int i = 0; i < bodyStmts.length; i++) {
01014                         Stmt stmt = bodyStmts[i];
01015                         if (linePropList.contains(stmt))
01016                             continue;
01017                         removedStmtByEmptyB.add(stmt);
01018                     }
01019                 }
01020             }
01021 
01022             /*
01023               else if ((cfann instanceof SequentialAnnotation)
01024                && (!(cfann instanceof BreakStmtAnnotation)))
01025                 {
01026                   SequentialAnnotation sequentialAnn = 
01027             (SequentialAnnotation) cfann;
01028                   Stmt bodyStmts[] = sequentialAnn.getStatements();
01029             
01030                   //printout the bodyStmts[] for debug
01031                   System.out.println("Print out the bodyStmts");
01032                   for (int ss=0; ss<bodyStmts.length; ss++)
01033             {
01034               System.out.println(bodyStmts[ss]);
01035             }
01036             
01037                   System.out.println("SliceSet: " + slcSet);
01038                   System.out.println("emptyBody? " + emptyBody(bodyStmts, slcSet, stmtToIndex));
01039             
01040                   if (emptyBody(bodyStmts, slcSet, stmtToIndex))
01041             {
01042               // bodyStmts = sequentialAnn.getStatements(); 
01043               for (int i=0; i<bodyStmts.length; i++)
01044                 {
01045                   Index stmtIndex = (Index) stmtToIndex.get(bodyStmts[i]);
01046                   if (linePropList.contains(stmtIndex)) continue;
01047             
01048                   removedStmtByEmptyB.addElemToSet(stmtIndex);
01049                  
01050                   //if (slcSet.contains(stmtIndex))
01051                   //slcSet.remove(stmtIndex);
01052                   
01053                 }
01054             System.out.println("since SequentialAnn: " +removedStmtByEmptyB);      
01055             }   
01056                 }
01057               */
01058 
01059     } //end of for enumeration
01060 }
01061   /**
01062    * Remove empty lock.
01063    * <p>
01064    * @param lockPairList a list of {@link LockPair LockPair}.
01065    * @param slcSet slice set.
01066    * @param linePropList a set of statement.
01067    * @param removedStmtByEmptyB removed statements.
01068    * @param stmtList statement list.
01069    */
01070 private void removeEmptyLock(List lockPairList, BitSet slcSet, Set linePropList, Set removedStmtByEmptyB, StmtList stmtList) {
01071     for (Iterator lockPairIt = lockPairList.iterator(); lockPairIt.hasNext();) {
01072         MonitorPair lockPair = (MonitorPair) lockPairIt.next();
01073         Stmt monitorStmt = (Stmt) lockPair.getEnterMonitor();
01074         Annotation synchroBodyAnn = lockPair.getSynchroBodyAnn();
01075         Stmt bodyStmts[] = synchroBodyAnn.getStatements();
01076         if (emptyBody(bodyStmts, slcSet, stmtList)) {
01077             //remove all stmt between monitor (synchronized stmt)
01078             monitorStmt = lockPair.getEndSynchroStmt();
01079             int exitIndex = stmtList.indexOf(monitorStmt);
01080             monitorStmt = lockPair.getBeginSynchroStmt();
01081             int enterIndex = stmtList.indexOf(monitorStmt);
01082             for (int i = enterIndex; i <= exitIndex; i++) {
01083                 Stmt stmt = (Stmt) stmtList.get(i);
01084                 if (linePropList.contains(stmt))
01085                     continue;
01086                 removedStmtByEmptyB.add(stmt);
01087                 if (slcSet.get(i)) {
01088                     slcSet.clear(i);
01089                 }
01090             }
01091         } else
01092             
01093             //not empty, add exception handling into slice set
01094             {
01095             Annotation catchCFANN = lockPair.getCatchAnn();
01096             Stmt catchStmts[] = catchCFANN.getStatements();
01097             for (int i = 0; i < catchStmts.length; i++) {
01098                 slcSet.set(stmtList.indexOf(catchStmts[i]));
01099             }
01100         }
01101     }
01102 }
01103 /**
01104    * Remove empty try block.
01105    * <p>
01106    * @param currentCfanns a vector of annotations need to be analysed.
01107    * @param slcSet slice set.
01108    * @param linePropList a set of statement.
01109    * @param removedStmtByEmptyB removed statements.
01110    * @param stmtList statement list.
01111    */
01112 private void removeEmptyTry(Vector currentCfanns, BitSet slcSet, Set linePropList, Set removedStmtByEmptyB, StmtList stmtList, JimpleBody jimpleBody) {
01113     for (Enumeration e = currentCfanns.elements(); e.hasMoreElements();) {
01114         Annotation cfann = (Annotation) e.nextElement();
01115         if (cfann instanceof TryStmtAnnotation) {
01116             TryStmtAnnotation tryCFANN = (TryStmtAnnotation) cfann;
01117             Annotation tryBody = tryCFANN.getBlockAnnotation();
01118             Stmt bodyStmts[] = tryBody.getStatements();
01119 
01120             //to see if the sliceset includes any statements in bodyStms
01121 
01122             if (emptyBody(bodyStmts, slcSet, stmtList)) {
01123                 Stmt allBodyStmts[] = tryCFANN.getStatements();
01124                 for (int i = 0; i < allBodyStmts.length; i++) {
01125                     Stmt stmt = allBodyStmts[i];
01126                     int stmtIndex = stmtList.indexOf(stmt);
01127                     if (linePropList.contains(stmt))
01128                         continue;
01129                     removedStmtByEmptyB.add(stmt);
01130                     if (slcSet.get(stmtIndex))
01131                         slcSet.clear(stmtIndex);
01132                 }
01133                 addCatchesToRemovedSet(removedStmtByEmptyB, tryCFANN.getCatchClauses(), stmtList, linePropList, slcSet);
01134                 //remove all traps about this body
01135                 removeTrapsOf(bodyStmts,jimpleBody);
01136             } else {
01137 
01138                 //add exception handling into slice set
01139                 //System.out.println("add catch of try");
01140                 Vector catches = tryCFANN.getCatchClauses();
01141                 addCatchesToSliceSet(slcSet, catches, stmtList);
01142             }
01143         }
01144     }
01145 }
01146   /**
01147    * Remove empty try finally block.
01148    * <p>
01149    * @param currentCfanns a vector of annotations need to be analysed.
01150    * @param slcSet slice set.
01151    * @param linePropList a set of statement.
01152    * @param removedStmtByEmptyB removed statements.
01153    * @param stmtList statement list.
01154    */
01155 private void removeEmptyTryFinally(Vector currentCfanns, BitSet slcSet, Set linePropList, Set removedStmtByEmptyB, StmtList stmtList, JimpleBody jimpleBody) {
01156     for (Enumeration e = currentCfanns.elements(); e.hasMoreElements();) {
01157         Annotation cfann = (Annotation) e.nextElement();
01158 
01159 
01160         if (cfann instanceof TryFinallyStmtAnnotation) {
01161 
01162             TryFinallyStmtAnnotation tryFinallyCFANN = (TryFinallyStmtAnnotation) cfann;
01163             Annotation tryBody = tryFinallyCFANN.getBlockAnnotation();
01164             Stmt bodyStmts[] = tryBody.getStatements();
01165 
01166             //to see if the sliceset includes any statements in bodyStms
01167 
01168             if (emptyBody(bodyStmts, slcSet, stmtList)) {
01169                 for (int i = 0; i < bodyStmts.length; i++) {
01170                     Stmt stmt = bodyStmts[i];
01171                     int stmtIndex = stmtList.indexOf(stmt);
01172                     if (linePropList.contains(stmt))
01173                         continue;
01174                     removedStmtByEmptyB.add(stmt);
01175                     if (slcSet.get(stmtIndex))
01176                         slcSet.clear(stmtIndex);
01177                 }
01178                 addCatchesToRemovedSet(removedStmtByEmptyB, tryFinallyCFANN.getCatchClauses(), stmtList, linePropList, slcSet);
01179             } else
01180                 //add exception handling into slice set
01181                 {
01182                 //System.out.println("add catch of try");
01183                 Vector catches = tryFinallyCFANN.getCatchClauses();
01184                 addCatchesToSliceSet(slcSet, catches, stmtList);
01185             }
01186 
01187             // the fianlly part of the try statement should be included in the slice set, whether the body of the try is empty or not
01188             bodyStmts = tryFinallyCFANN.getFinallyAnnotation().getStatements();
01189             for (int i = 0; i < bodyStmts.length; i++)
01190                 slcSet.set(stmtList.indexOf(bodyStmts[i]));
01191             bodyStmts = tryFinallyCFANN.getFinallyExceptionAnnotation().getStatements();
01192             for (int i = 0; i < bodyStmts.length; i++)
01193                 slcSet.set(stmtList.indexOf(bodyStmts[i]));
01194         }
01195     }
01196 }
01197 /**
01198  * Insert the method's description here.
01199  * Creation date: (00-12-20 13:56:57)
01200  * @param sootClass ca.mcgill.sable.soot.SootClass
01201  * @param sootField ca.mcgill.sable.soot.SootField
01202  */
01203 private void removeFieldInClinit(SootClass sootClass, SootField sootField) {
01204     if (!sootClass.declaresMethod("<clinit>"))
01205         return;
01206     SootMethod sootMethod = sootClass.getMethod("<clinit>");
01207     JimpleBody jimpleBody = (JimpleBody) sootMethod.getBody(Jimple.v());
01208     StmtList stmtList = jimpleBody.getStmtList();
01209     Set removableStmts = new ArraySet();
01210     for (Iterator stmtIt = stmtList.iterator(); stmtIt.hasNext();) {
01211         Stmt stmt = (Stmt) stmtIt.next();
01212         if (stmt instanceof AssignStmt) {
01213             Value leftValue = ((AssignStmt) stmt).getLeftOp();
01214             if (leftValue instanceof FieldRef) {
01215                 SootField leftField = ((FieldRef) leftValue).getField();
01216                 if (leftField.equals(sootField))
01217                     removableStmts.add(stmt);
01218             }
01219         }
01220     }
01221     if (removableStmts.isEmpty())
01222         return;
01223     Annotation annForSm = cfanns.getAnnotation(sootClass, sootMethod);
01224     for (Iterator stmtIt = removableStmts.iterator(); stmtIt.hasNext();) {
01225         Stmt stmt = (Stmt) stmtIt.next();
01226         stmtList.remove(stmt);
01227         try {
01228             annForSm.removeStmt(stmt);
01229         } catch (Exception e) {
01230         }
01231     }
01232 }
01233 /*
01234   private boolean isNextNextRef(Stmt s)
01235 {
01236   if (! (s instanceof DefinitionStmt)) return false;
01237 
01238   Value rightOp = ((DefinitionStmt) s).getRightOp();
01239 
01240   if (rightOp instanceof NextNextStmtRef) return true;
01241 
01242   return false;
01243 }
01244   */
01245 
01246 
01247 // remove irrelevant fields in terms of relevant fields
01248 /**
01249    * Remove irrelevant fileds for a class.
01250    * <p>
01251    * @param classInfo query class.
01252    */
01253 private void removeIrrelevantFields(ClassInfo classInfo) {
01254     SootClass sootClass = classInfo.sootClass;
01255     List fields = sootClass.getFields();
01256     Set relevantSootFields = fieldRefToField(relevantFields);
01257     Set removableFields = new ArraySet();
01258     for (Iterator fieldsIt = fields.iterator(); fieldsIt.hasNext();) {
01259         SootField sootField = (SootField) fieldsIt.next();
01260         if (!relevantSootFields.contains(sootField))
01261             removableFields.add(sootField);
01262     }
01263     for (Iterator rf = removableFields.iterator(); rf.hasNext();) {
01264         SootField rmSootField = (SootField) rf.next();
01265         sootClass.removeField(rmSootField);
01266         removeFieldInClinit(sootClass,rmSootField);
01267     }
01268 
01269     //reset the relevant fiels set for next class
01270 }
01271   /**
01272    * Remove one jump source from a jump target map.
01273    * <p>
01274    * @param jumpTarMap a map from target {@link Stmt Stmt} to 
01275    * source {@link BitSet BitSet}.
01276    * @param removingStmtIndex the source need to be removed.
01277    */
01278 private void removeSourceFor(Map jumpTarMap, int removingStmtIndex) {
01279     Set removableTargets = new ArraySet();
01280     for (Iterator keyIt = jumpTarMap.keySet().iterator(); keyIt.hasNext();) {
01281         Stmt keyStmt = (Stmt) keyIt.next();
01282         BitSet jumpSources = (BitSet) jumpTarMap.get(keyStmt);
01283         if (jumpSources.get(removingStmtIndex))
01284             jumpSources.clear(removingStmtIndex);
01285         if (SetUtil.emptyBitSet(jumpSources))
01286             removableTargets.add(keyStmt);
01287     }
01288     for (Iterator i = removableTargets.iterator(); i.hasNext();)
01289         jumpTarMap.remove(i.next());
01290 }
01291 /**
01292  * Insert the method's description here.
01293  * Creation date: (00-11-7 18:30:48)
01294  * @param bodyStmts ca.mcgill.sable.soot.jimple.Stmt[]
01295  * @param stmtList ca.mcgill.sable.soot.jimple.StmtList
01296  */
01297 private void removeTrapsOf(Stmt[] bodyStmts, JimpleBody jimpleBody) {
01298     Set removableTraps = new ArraySet();
01299     List traps = jimpleBody.getTraps();
01300     Stmt firstStmtInBody = bodyStmts[0];
01301     Stmt lastStmtInBody = bodyStmts[bodyStmts.length - 1];
01302     for (Iterator trapIt = traps.iterator(); trapIt.hasNext();) {
01303         Trap trap = (Trap) trapIt.next();
01304         //if (emptyBodyTrap(bodyStmts, trap))
01305         Stmt beginStmt = (Stmt) trap.getBeginUnit();
01306         Stmt endStmt = (Stmt) trap.getEndUnit();
01307         if (beginStmt.equals(firstStmtInBody) && endStmt.equals(lastStmtInBody))
01308             removableTraps.add(trap);
01309     }
01310     for (Iterator trapIt = removableTraps.iterator(); trapIt.hasNext();) {
01311         Trap removableTrap = (Trap) trapIt.next();
01312         jimpleBody.removeTrap(removableTrap);
01313     }
01314 }
01315 /**
01316    * Construct residual classes.
01317    */
01318 public void resClassCons() {
01319     Map removableMdMap = new HashMap();
01320     for (Iterator classIt = classList.iterator(); classIt.hasNext();) {
01321         ClassInfo classInfo = (ClassInfo) classIt.next();
01322         if (Slicer.unreachableClasses.contains(classInfo.sootClass)) {
01323             removableClasses.add(classInfo);
01324             continue;
01325         }
01326         //if (classInfo.sootClass.getName().equals("java.lang.Object") || classInfo.sootClass.getName().equals("Object"))
01327         if (Slicer.isObjectClass(classInfo.sootClass))
01328             continue;
01329         List mdList = classInfo.methodsInfoList;
01330         MethodInfo initMethodInfo = null;
01331         List removableMethods = new ArrayList();
01332         boolean containsStartMethod = false;
01333         for (Iterator mdIt = mdList.iterator(); mdIt.hasNext();) {
01334             MethodInfo mdInfo = (MethodInfo) mdIt.next();
01335             if (mdInfo.sliceSet == null) {
01336                 if (mdInfo.sootMethod.getName().equals("<init>")) {
01337                     SootMethod sm = mdInfo.sootMethod;
01338                     if (sm.getParameterCount() == 0) {
01339                         initMethodInfo = mdInfo;
01340                     }
01341                     removableMethods.add(mdInfo);
01342                 } else
01343                     if (Modifier.isAbstract(mdInfo.sootMethod.getModifiers())) {
01344                     }
01345                     // this else is for the abpstest examples, and will be 
01346                     // eliminated finally
01347                     else
01348                         if (mdInfo.sootMethod.getName().equals("start")) {
01349                             containsStartMethod = true;
01350                         } else
01351                             removableMethods.add(mdInfo);
01352             } else
01353                 modifyMethod(mdInfo);
01354         }
01355         if (removableMethods.size() != 0) {
01356             if (removableMethods.size() == mdList.size() || (removableMethods.size() == (mdList.size() - 1) && containsStartMethod)) {
01357                 removableClasses.add(classInfo);
01358             } else {
01359                 if (initMethodInfo != null) {
01360                     Set varsOfInit = getAllVarsOf(initMethodInfo);
01361                     filterOutFields(varsOfInit);
01362                     removableMethods.remove(initMethodInfo);
01363                 }
01364                 Set implementingMethods = new ArraySet();
01365                 for (Iterator mdInfoIt = removableMethods.iterator(); mdInfoIt.hasNext();) {
01366                     MethodInfo rmvableMdInfo = (MethodInfo) mdInfoIt.next();
01367                     SootMethod rmvableMd = rmvableMdInfo.sootMethod;
01368                     if (isImplementingOneAbstractMd(rmvableMd)) {
01369                         implementingMethods.add(rmvableMdInfo);
01370                         Annotation annForSm = cfanns.getAnnotation(rmvableMd.getDeclaringClass(), rmvableMd);
01371                         makeMethodEmpty(rmvableMdInfo, annForSm);
01372                     }
01373                 }
01374                 if (!implementingMethods.isEmpty())
01375                     removableMethods.removeAll(implementingMethods);
01376                 mdList.removeAll(removableMethods);
01377             }
01378         }
01379 
01380         //put removable methods list into the map
01381         removableMdMap.put(classInfo.sootClass, removableMethods);
01382     }
01383 
01384     //check relevantField and removableClassses to see if there
01385     //are any relevant fields is in one class (CLS) which is in 
01386     //removableClasses, where all methods in CLS are going to be
01387     //removed, but the fields are relevant maybe for other class.
01388 
01389     relevantFDClass();
01390     relevantExceptionClasses();
01391     rmMethodAndClass(removableMdMap);
01392     returnToVoid();
01393     rmIrrelevantFds();
01394     rmIrrelevantParasForMd();
01395     rmIrrelevantParasForInvoke();
01396 }
01397 /**
01398    * Construct residual parameter for a given method.
01399    * <p>
01400    * @param mdInfo query method.
01401    */
01402 private void residualParameters(MethodInfo mdInfo) {
01403     SootMethod sootMethod = mdInfo.sootMethod;
01404     StmtList stmtList = mdInfo.originalStmtList; //should use the original stmtList
01405     StmtList slicedStmtList = mdInfo.stmtList;
01406     List parameterTypes = sootMethod.getParameterTypes();
01407     Local paraLocals[] = mdInfo.indexMaps.getParaLocalSet();
01408     Stmt paraIdStmt[] = mdInfo.indexMaps.getParaIdentityStmts();
01409     Map changedStmtMap = new HashMap();
01410     BitSet sliceSet = mdInfo.sliceSet;
01411     Map relevantVars = mdInfo.sCriterion.relVarMap();
01412     //Set relLocs = getRelevantLocals(stmtList, sliceSet, relevantVars);
01413     Set relLocs = getAllVarsOf(stmtList, sliceSet);
01414     Set removableParas = new ArraySet();
01415     LinkedList keepedParaOriginalIndex = new LinkedList();
01416     for (int i = 0; i < paraLocals.length; i++) {
01417         Local paraLocal = paraLocals[i];
01418         if (!relLocs.contains(paraLocal)) {
01419             removableParas.add(parameterTypes.get(i));
01420         } else {
01421             keepedParaOriginalIndex.addLast(new Integer(i));
01422         }
01423     }
01424     for (Iterator i = removableParas.iterator(); i.hasNext();) {
01425         Object type = (Object) i.next();
01426         parameterTypes.remove(type);
01427     }
01428     if (removableParas.size() > 0) {
01429         sootMethod.setParameterTypes(parameterTypes);
01430         //change parameter index
01431         for (int i = 0; i < keepedParaOriginalIndex.size(); i++) {
01432             int originalParaIndex = ((Integer) keepedParaOriginalIndex.get(i)).intValue();
01433             if (originalParaIndex == i)
01434                 continue;
01435             Stmt stmtForThisPara = paraIdStmt[originalParaIndex];
01436             if (!(stmtForThisPara instanceof IdentityStmt))
01437                 throw new NonIdParaAssignmentException("parameter assignment should be identity statement");
01438             IdentityStmt idStmtForThisPara = (IdentityStmt) stmtForThisPara;
01439             ParameterRef newParameterRef = Jimple.v().newParameterRef(sootMethod, i);
01440             IdentityStmt newIdStmt = Jimple.v().newIdentityStmt(idStmtForThisPara.getLeftOp(), newParameterRef);
01441 
01442             //change original id stmt to new id stmt
01443             int indexOfIdStmt = slicedStmtList.indexOf(stmtForThisPara);
01444             slicedStmtList.remove(indexOfIdStmt);
01445             slicedStmtList.add(indexOfIdStmt, newIdStmt);
01446             //modiy jumptarget map
01447             changedStmtMap.put(stmtForThisPara, newIdStmt);
01448         }
01449         modifyJumpTargetMap(stmtList, changedStmtMap, mdInfo.indexMaps.getJumpTargetMap());
01450     }
01451 }
01452 /**
01453    * Change return types of methods in {@link #changeReturnTypeToVoidMds changeReturnTypeToVoidMds}
01454    * into void.
01455    */
01456 private void returnToVoid() {
01457     //change return type to void if necessary
01458     for (int i = 0; i < changeReturnTypeToVoidMds.size(); i++) {
01459         SootMethod sootMd = (SootMethod) changeReturnTypeToVoidMds.get(i);
01460         sootMd.setReturnType(VoidType.v());
01461     }
01462 }
01463 /**
01464    * Remove irrelevant fields in every classes.
01465    */
01466 private void rmIrrelevantFds() {
01467     //remove irrelevant fields
01468     for (Iterator classIt = classList.iterator(); classIt.hasNext();) {
01469         ClassInfo classInfo = (ClassInfo) classIt.next();
01470         if (//keepingClasses.contains(classInfo) ||
01471             Slicer.isObjectClass(classInfo.sootClass) || removableClasses.contains(classInfo)) {
01472         } else
01473             removeIrrelevantFields(classInfo);
01474     }
01475 }
01476 /**
01477    * Remove irrelevant parameters for invoke expression.
01478    */
01479 private void rmIrrelevantParasForInvoke() {
01480     //remove irrelevant actual parameters for every invokeExpr 
01481     for (Iterator classIt = classList.iterator(); classIt.hasNext();) {
01482         ClassInfo classInfo = (ClassInfo) classIt.next();
01483         if (Slicer.isObjectClass(classInfo.sootClass))
01484             continue;
01485         for (Iterator mdIt = classInfo.methodsInfoList.iterator(); mdIt.hasNext();) {
01486             MethodInfo mdInfo = (MethodInfo) mdIt.next();
01487             if (mdInfo.sliceSet != null)
01488                 rmParasOfInvokeExpr(mdInfo);
01489             JimpleBody body = (JimpleBody) mdInfo.sootMethod.getBody(Jimple.v());
01490             Transformations.removeUnusedLocals(body);
01491             cfanns.getAnnotation(mdInfo.sootClass, mdInfo.sootMethod).validate(body);
01492         }
01493     }
01494 }
01495 /**
01496    * Remove irrelevant parameters for method declaration.
01497    */
01498 private void rmIrrelevantParasForMd() {
01499     //remove irrelevant parameters for method declaration
01500     Iterator classIt = classList.iterator();
01501     while (classIt.hasNext()) {
01502         ClassInfo classInfo = (ClassInfo) classIt.next();
01503         if (Slicer.isObjectClass(classInfo.sootClass))
01504             continue;
01505         List mdList = classInfo.methodsInfoList;
01506         Iterator mdIt = mdList.iterator();
01507         while (mdIt.hasNext()) {
01508             MethodInfo mdInfo = (MethodInfo) mdIt.next();
01509             if (mdInfo.sliceSet == null)
01510                 continue;
01511             if (mdInfo.sootMethod.getName().equals("main")) {
01512             } else
01513                 residualParameters(mdInfo);
01514             JimpleBody body = (JimpleBody) mdInfo.sootMethod.getBody(Jimple.v());
01515             //Transformations.removeUnusedLocals(body);
01516             cfanns.getAnnotation(mdInfo.sootClass, mdInfo.sootMethod).validate(body);
01517         }
01518     }
01519 }
01520 /**
01521    * Remove methods and classes in terms of given removable method map.
01522    * <p>
01523    * @param removableMdMap a map from {@link SootClass SootClass} to 
01524    * a {@link List List} of {@link SootMethod SootMethod}.
01525    */
01526 private void rmMethodAndClass(Map removableMdMap) {
01527     //remove method from sootClass
01528 
01529     for (Iterator classIt = removableMdMap.keySet().iterator(); classIt.hasNext();) {
01530         SootClass sootClass = (SootClass) classIt.next();
01531         List removableMethods = (List) removableMdMap.get(sootClass);
01532         for (int i = 0; i < removableMethods.size(); i++) {
01533             MethodInfo rmvableMdInfo = (MethodInfo) removableMethods.get(i);
01534             sootClass.removeMethod(rmvableMdInfo.sootMethod);
01535         }
01536         //remove all non-reachable methods
01537         Set unreachableMds = new ArraySet();
01538         for (Iterator mdIt = sootClass.getMethods().iterator(); mdIt.hasNext();) {
01539             SootMethod md = (SootMethod) mdIt.next();
01540             if (!Slicer.reachableMethods.contains(md))
01541                 unreachableMds.add(md);
01542         }
01543         for (Iterator unIt = unreachableMds.iterator(); unIt.hasNext();)
01544             sootClass.removeMethod((SootMethod) unIt.next());
01545     }
01546     if (removableClasses.size() != 0) {
01547         if (removableClasses.size() == classList.size())
01548             classList = null;
01549         else
01550             classList.removeAll(removableClasses);
01551     }
01552 }
01553   /**
01554    * Remove irrelevant parameters of invoke expressions in a given method.
01555    * <p>
01556    * @param mdInfo query method.
01557    */
01558 private void rmParasOfInvokeExpr(MethodInfo mdInfo) {
01559 
01560     StmtList originalStmtList = mdInfo.originalStmtList; //should use the original stmtList
01561     StmtList stmtList = mdInfo.stmtList;
01562     Map callSiteMap = mdInfo.indexMaps.getCallSiteMap();
01563     Map callSiteIndexMap = SlicingMethod.callSiteIndex(callSiteMap);
01564     BitSet sliceSet = mdInfo.sliceSet;
01565     Annotation annForSm = cfanns.getAnnotation(mdInfo.sootClass, mdInfo.sootMethod);
01566     for (Iterator siteIt = callSiteIndexMap.keySet().iterator(); siteIt.hasNext();) {
01567         Stmt callStmt = (Stmt) siteIt.next();
01568         if (!sliceSet.get(originalStmtList.indexOf(callStmt)))
01569             continue;
01570         if (callStmt instanceof InvokeStmt) {
01571             InvokeStmt invokeStmt = (InvokeStmt) callStmt;
01572             InvokeExpr invokeExpr = (InvokeExpr) invokeStmt.getInvokeExpr();
01573             InvokeExpr newInvokeExpr = buildNewInvokeExpr(invokeExpr);
01574             invokeStmt.setInvokeExpr(newInvokeExpr);
01575         } else
01576             if (callStmt instanceof AssignStmt) {
01577                 AssignStmt assignCallStmt = (AssignStmt) callStmt;
01578                 Value rightOp = assignCallStmt.getRightOp();
01579                 if (rightOp instanceof InvokeExpr) {
01580                     InvokeExpr newInvokeExpr = buildNewInvokeExpr((InvokeExpr) rightOp);
01581                     SootMethod invokedMd = ((InvokeExpr) rightOp).getMethod();
01582                     if (changeReturnTypeToVoidMds.contains(invokedMd)) {
01583                         int indexOfCallStmt = stmtList.indexOf(callStmt);
01584                         stmtList.remove(indexOfCallStmt);
01585                         InvokeStmt newInvokeStmt = Jimple.v().newInvokeStmt(newInvokeExpr);
01586                         try {
01587                             cfanns.putInlineStmt(newInvokeStmt, callStmt, mdInfo.sootMethod);
01588                             annForSm.replaceStmt(callStmt, newInvokeStmt);
01589                         } catch (Exception e) {
01590                         }
01591                         stmtList.add(indexOfCallStmt, newInvokeStmt);
01592                     } else
01593                         assignCallStmt.setRightOp(newInvokeExpr);
01594                 } else {
01595                     System.out.println("rightOp is not invokeExpr");
01596                 }
01597             } else {
01598                 System.out.println("callStmt is not invokeStmt nor DefinitionStmt");
01599             }
01600     }
01601 }
01602 }

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