KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > soot > dava > toolkits > base > renamer > infoGatheringAnalysis


1 /* Soot - a J*va Optimization Framework
2  * Copyright (C) 2005 Nomair A. Naeem
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */

19
20 package soot.dava.toolkits.base.renamer;
21
22 import soot.dava.toolkits.base.AST.analysis.*;
23 import soot.*;
24 import soot.jimple.*;
25 import java.util.*;
26 //import soot.util.*;
27
import soot.dava.*;
28 import soot.grimp.*;
29 import soot.grimp.internal.*;
30 import soot.dava.internal.javaRep.*;
31 import soot.dava.internal.asg.*;
32 import soot.jimple.internal.*;
33 import soot.dava.internal.AST.*;
34
35 public class infoGatheringAnalysis extends DepthFirstAdapter {
36     
37     public boolean DEBUG=false;
38     
39     public final static int CLASSNAME = 0; //used by renamer
40

41     public final static int METHODNAME = 1;
42
43     public final static int GETSET = 2;
44
45     public final static int IF = 3;
46
47     public final static int WHILE = 4;
48
49     public final static int SWITCH = 5;
50
51     public final static int ARRAYINDEX = 6;
52
53     public final static int MAINARG = 7; //used by renamer
54

55     public final static int FIELDASSIGN = 8; //used by renamer
56

57     public final static int FORLOOPUPDATE = 9; //used by renamer
58

59     public final static int CAST = 10;
60
61     public final static int NUMBITS = 11;
62
63     //dataset to store all information gathered
64
heuristicSet info;
65
66     //if we are within a subtree rooted at a definitionStmt this boolean is true
67
boolean inDefinitionStmt = false;
68
69     //whenever there is a definition to a local definedLocal will contain a ref to the local
70
Local definedLocal = null;
71
72     //if we are within a subtree rooted at a ifNode or IfElseNode this boolean is true
73
boolean inIf = false;
74
75     //if we are within a subtree rooted at a WhileNode or DoWhileNode this boolean is true
76
boolean inWhile = false;
77
78     //if we are within a subtree rooted at a ForLoop this boolean is true
79
boolean inFor = false;
80
81     public infoGatheringAnalysis(DavaBody davaBody) {
82         info = new heuristicSet();
83
84         List localList = new ArrayList();
85         /*
86          Get locals info out of davaBody
87          Copied with modifications from DavaPrinter method printLocalsInBody
88          */

89         HashSet params = new HashSet();
90         // params.addAll(davaBody.get_ParamMap().values());
91
//params.addAll(davaBody.get_CaughtRefs());
92
HashSet thisLocals = davaBody.get_ThisLocals();
93
94         //System.out.println("params"+params);
95

96         Iterator localIt = davaBody.getLocals().iterator();
97
98         while (localIt.hasNext()) {
99             Local local = (Local) localIt.next();
100
101             if (params.contains(local) || thisLocals.contains(local))
102                 continue;
103             localList.add(local);
104         }
105
106         //localList is a list with all locals
107
//initialize the info Set with empty info for each local
108
Iterator it = localList.iterator();
109         while (it.hasNext()) {
110             Local local = (Local) it.next();
111             info.add(local, NUMBITS);
112             debug("infoGatheringAnalysis","added "+local.getName()+ " to the heuristicset");
113         }
114
115         /*
116          Check if we are dealing with a main method
117          In which case set the MAINARG heuristic of the param
118          */

119         //System.out.println("METHOD:"+davaBody.getMethod());
120
SootMethod method = davaBody.getMethod();
121         //System.out.println(method.getSubSignature());
122
if (method.getSubSignature().compareTo("void main(java.lang.String[])") == 0) {
123             //means we are currently working on the main method
124
it = davaBody.get_ParamMap().values().iterator();
125             int num = 0;
126             Local param = null;
127             while (it.hasNext()) {
128                 num++;
129                 param = (Local) it.next();
130             }
131             if (num > 1) {
132                 throw new DecompilationException("main method has greater than 1 args!!");
133             } else {
134                 info.setHeuristic(param, infoGatheringAnalysis.MAINARG);
135             }
136         }
137     }
138
139     /*
140      This can be either an assignment or an identity statement.
141      We are however only concerned with stmts which assign values to locals
142      
143      The method sets the inDefinitionStmt flag to true and if this is a local assignment
144      The ref to the local is stored in definedLocal
145      */

146     public void inDefinitionStmt(DefinitionStmt s) {
147         inDefinitionStmt = true;
148         //System.out.println(s);
149
Value v = s.getLeftOp();
150         if (v instanceof Local) {
151             //System.out.println("This is a local:"+v);
152
/*
153              * We want definedLocal to be set only if we are interested in naming it
154              * Variables that are created by Dava itself e.g. handler (refer to SuperFirstStmtHandler)
155              * Need not be renamed. So we check whether definedLocal is present in the info set
156              * if it is we set this other wise we dont
157              */

158             if(info.contains((Local)v))
159                 definedLocal = (Local) v;
160             else
161                 definedLocal = null;
162             
163             
164         } else {
165             //System.out.println("Not a local"+v);
166
}
167     }
168
169     public void outDefinitionStmt(DefinitionStmt s) {
170         //checking casting here because we want to see if the expr
171
//on the right of def stmt is a cast expr not whether it contains a cast expr
172
if(definedLocal != null && s.getRightOp() instanceof CastExpr){
173             Type castType = ((CastExpr)s.getRightOp()).getCastType();
174             info.addCastString(definedLocal,castType.toString());
175         }
176         inDefinitionStmt = false;
177         definedLocal = null;
178     }
179
180     
181     
182     /*
183      Deals with cases in which a local is assigned a value from a static field
184      int local = field
185      int local = class.field
186      */

187     public void inStaticFieldRef(StaticFieldRef sfr) {
188         if (inDefinitionStmt && (definedLocal != null)) {
189             SootField field = sfr.getField();
190             info.setFieldName(definedLocal, field.getName());
191         }
192     }
193
194     /*
195      Deals with cases in which a local is assigned a value from a field
196      int local = field
197      or int local = obj.field
198      */

199
200     public void inInstanceFieldRef(InstanceFieldRef ifr) {
201         if (ifr instanceof AbstractInstanceFieldRef) {
202             if (inDefinitionStmt && (definedLocal != null)) {
203                 SootField field = ((AbstractInstanceFieldRef) ifr).getField();
204                 //System.out.println(definedLocal+" is being assigned field:"+field.getName());
205
info.setFieldName(definedLocal, field.getName());
206             }
207         }
208     }
209
210     /*
211      * (non-Javadoc)
212      * @see soot.dava.toolkits.base.AST.analysis.DepthFirstAdapter#outInvokeExpr(soot.jimple.InvokeExpr)
213      * If it is a newInvoke expr we know that the name of the class can come in handy
214      * while renaming because this could be a subtype
215      */

216     public void outInvokeExpr(InvokeExpr ie) {
217         //If this is within a definitionStmt of a local
218
if (inDefinitionStmt && (definedLocal != null)) {
219             //if its a new object being created
220
if (ie instanceof NewInvokeExpr) {
221                 //System.out.println("new object being created retrieve the name");
222
RefType ref = ((NewInvokeExpr) ie).getBaseType();
223                 String JavaDoc className = ref.getClassName();
224                 debug("outInvokeExpr","defined local is"+definedLocal);
225                 info.setObjectClassName(definedLocal, className);
226                 
227             } else {
228                 SootMethodRef methodRef = ie.getMethodRef();
229                 String JavaDoc name = methodRef.name();
230                 //System.out.println(name);
231
info.setMethodName(definedLocal, name);
232             }
233         }
234     }
235
236     /*
237      This is the object for a flag use in a conditional
238      If the value is a local set the appropriate heuristic
239      */

240     public void inASTUnaryCondition(ASTUnaryCondition uc) {
241         Value val = uc.getValue();
242         if (val instanceof Local) {
243             if (inIf)
244                 info.setHeuristic((Local) val, infoGatheringAnalysis.IF);
245             if (inWhile)
246                 info.setHeuristic((Local) val, infoGatheringAnalysis.WHILE);
247         }
248     }
249
250     public void inASTBinaryCondition(ASTBinaryCondition bc) {
251         ConditionExpr condition = bc.getConditionExpr();
252
253         Local local = checkBooleanUse(condition);
254         if (local != null) {
255             if (inIf)
256                 info.setHeuristic(local, infoGatheringAnalysis.IF);
257             if (inWhile)
258                 info.setHeuristic(local, infoGatheringAnalysis.WHILE);
259         }
260     }
261
262     /*
263      Setting if to true in inASTIfNode so that later we know whether this is a flag use in an if
264      */

265     public void inASTIfNode(ASTIfNode node) {
266         inIf = true;
267     }
268
269     /*
270      Going out of if set flag to false
271      */

272     public void outASTIfNode(ASTIfNode node) {
273         inIf = false;
274     }
275
276     /*
277      Setting if to true in inASTIfElseNode so that later we know whether this is a flag use in an ifElse
278      */

279     public void inASTIfElseNode(ASTIfElseNode node) {
280         inIf = true;
281     }
282
283     /*
284      Going out of ifElse set flag to false
285      */

286     public void outASTIfElseNode(ASTIfElseNode node) {
287         inIf = false;
288     }
289
290     /*
291      Setting if to true in inASTWhileNode so that later we know whether this is a flag use in a WhileNode
292      */

293     public void inASTWhileNode(ASTWhileNode node) {
294         inWhile = true;
295     }
296
297     /*
298      setting flag to false
299      */

300     public void outASTWhileNode(ASTWhileNode node) {
301         inWhile = false;
302     }
303
304     /*
305      Setting if to true in inASTDoWhileNode so that later we know whether this is a flag use in a WhileNode
306      */

307     public void inASTDoWhileNode(ASTDoWhileNode node) {
308         inWhile = true;
309     }
310
311     /*
312      setting flag to false
313      */

314     public void outASTDoWhileNode(ASTDoWhileNode node) {
315         inWhile = false;
316     }
317
318     /*
319      Check the key of the switch statement to see if its a local
320      */

321     public void inASTSwitchNode(ASTSwitchNode node) {
322         Value key = node.get_Key();
323         if (key instanceof Local)
324             info.setHeuristic((Local) key, infoGatheringAnalysis.SWITCH);
325     }
326
327     public void inArrayRef(ArrayRef ar) {
328         Value index = ar.getIndex();
329         if (index instanceof Local)
330             info.setHeuristic((Local) index, infoGatheringAnalysis.ARRAYINDEX);
331     }
332
333     public void inASTTryNode(ASTTryNode node) {
334
335     }
336
337     /*
338      setting flag to true
339      */

340     public void inASTForLoopNode(ASTForLoopNode node) {
341         inFor = true;
342
343         Iterator updateIt = node.getUpdate().iterator();
344         while (updateIt.hasNext()) {
345             AugmentedStmt as = (AugmentedStmt) updateIt.next();
346             Stmt s = as.get_Stmt();
347             if (s instanceof GAssignStmt) {
348                 Value leftOp = ((GAssignStmt) s).getLeftOp();
349                 if (leftOp instanceof Local) {
350                     info.setHeuristic((Local) leftOp,
351                             infoGatheringAnalysis.FORLOOPUPDATE);
352                 }
353             }
354         }
355     }
356
357     /*
358      setting flag to false
359      */

360     public void outASTForLoopNode(ASTForLoopNode node) {
361         inFor = false;
362     }
363
364     /*
365      If there are any locals at this point who do not have any className set
366      it might be a good idea to store that information
367      */

368     public void outASTMethodNode(ASTMethodNode node) {
369         if(DEBUG){
370             System.out.println("SET START");
371             info.print();
372             System.out.println("SET END");
373         }
374     }
375
376     /*
377      The method checks whether a particular ConditionExpr
378      is a comparison of a local with a boolean
379      If so the local is returned
380      */

381     private Local checkBooleanUse(ConditionExpr condition) {
382         boolean booleanUse = false;
383
384         //check whether the condition qualifies as a boolean use
385
if (condition instanceof NeExpr || condition instanceof EqExpr) {
386             Value op1 = condition.getOp1();
387             Value op2 = condition.getOp2();
388             if (op1 instanceof DIntConstant) {
389                 Type op1Type = ((DIntConstant) op1).type;
390                 if (op1Type instanceof BooleanType)
391                     booleanUse = true;
392             } else if (op2 instanceof DIntConstant) {
393                 Type op2Type = ((DIntConstant) op2).type;
394                 if (op2Type instanceof BooleanType)
395                     booleanUse = true;
396             }
397             if (booleanUse) {
398                 //at this point we know that one of the values op1 or op2 was a boolean
399
//check whether the other is a local
400
if (op1 instanceof Local)
401                     return (Local) op1;
402                 else if (op2 instanceof Local)
403                     return (Local) op2;
404             } else
405                 return null;//meaning no local used as boolean found
406
}
407         return null; //meaning no local used as boolean found
408
}
409
410     public heuristicSet getHeuristicSet() {
411         return info;
412     }
413     
414     public void debug(String JavaDoc methodName, String JavaDoc debug){
415         
416         if(DEBUG)
417             System.out.println(methodName+ " DEBUG: "+debug);
418     }
419
420
421 }
422
423
Popular Tags