KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > soot > dava > toolkits > base > AST > traversals > AllVariableUses


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

20
21 /*
22  * Maintained by: Nomair A. Naeem
23  */

24
25 /*
26  * CHANGE LOG: * 30th January 2006, Class created since FinalFieldDefinition wants
27  * info about uses of a particular field in a method. Writing a general
28  * analysis which finds all uses of Locals and SootFields
29  *
30  */

31
32
33
34
35 /*
36   Need to be very clear when a local can be used
37   It can be used in the following places:
38   a, a conditional in if, ifelse, while , do while, for condition TICK
39   b, in the for init or update TICK
40   c, in a switch choice TICK
41   d, in a syncrhnoized block TICK
42   d, in a statement TICK
43
44
45   Need to be very clear when a SootField can be used
46   It can be used in the following places:
47
48   a, NOT used inside a Synchronized Block ........ HOWEVER ADD IT SINCE I DONT SEE WHY THIS RESTRICTION EXISTS!!! TICK
49   b, CAN BE USED in a condition TICK
50   c, CAN BE USED in the for init for update TICK
51   d, CAN BE USED in a switch TICK
52   e, CAN BE USED in a stmt TICK
53 */

54
55
56
57 package soot.dava.toolkits.base.AST.traversals;
58
59 import soot.*;
60 import java.util.*;
61 import soot.util.*;
62 import soot.jimple.*;
63 import soot.dava.*;
64 import soot.dava.internal.asg.*;
65 import soot.dava.internal.AST.*;
66 //import soot.dava.internal.javaRep.*;
67
import soot.dava.toolkits.base.AST.analysis.*;
68 //import soot.dava.toolkits.base.AST.structuredAnalysis.*;
69

70
71
72
73 public class AllVariableUses extends DepthFirstAdapter{
74     ASTMethodNode methodNode;
75
76     //List declaredLocals;
77
//Chain declaredFields;
78

79     HashMap localsToUses;
80     HashMap fieldsToUses;
81
82     public AllVariableUses(ASTMethodNode node){
83     super();
84     this.methodNode=node;
85     init();
86     }
87
88     public AllVariableUses(boolean verbose, ASTMethodNode node){
89     super(verbose);
90     this.methodNode=node;
91     init();
92     }
93
94     
95
96     public void init(){
97
98     localsToUses = new HashMap();
99     fieldsToUses = new HashMap();
100
101     /*
102      //get all local variables declared in this method
103     declaredLocals = methodNode.getDeclaredLocals();
104
105     //if no locals dont bother set to null
106     if(declaredLocals.size()==0)
107         declaredLocals=null;
108     
109
110
111     //store all fields
112
113
114     DavaBody davaBody = methodNode.getDavaBody();
115     SootMethod sootMethod = davaBody.getMethod();
116     SootClass sootClass = sootMethod.getDeclaringClass();
117
118     declaredFields = sootClass.getFields();
119     
120     //if no fields dont bother set to null
121     if(declaredFields.size()==0)
122         declaredFields=null;
123     */

124
125        
126     }
127
128
129
130     /*
131      * Notice as things stand synchblocks cant have the use of a SootField
132      */

133     public void inASTSynchronizedBlockNode(ASTSynchronizedBlockNode node){
134     Local local = node.getLocal();
135
136     addLocalUse(local,node);
137     }
138
139
140
141
142     /*
143       The key in a switch stmt can be a local or a SootField or a value
144       which can contain Locals or SootFields
145
146       Hence the some what indirect approach
147     */

148     public void inASTSwitchNode(ASTSwitchNode node){
149     Value val = (Value)node.get_Key();
150     List localUses = new ArrayList();
151     List fieldUses = new ArrayList();
152
153     if(val instanceof Local){
154         localUses.add((Local)val);
155         System.out.println("Added "+val+" to local uses for switch");
156     }
157     else if(val instanceof FieldRef){
158         fieldUses.add((FieldRef)val);
159         System.out.println("Added "+val+" to field uses for switch");
160     }
161     else{
162         List useBoxes = val.getUseBoxes();
163
164         List localsOrFieldRefs= getUsesFromBoxes(useBoxes);
165         Iterator it = localsOrFieldRefs.iterator();
166
167         while(it.hasNext()){
168         Value temp = (Value)it.next();
169         if(temp instanceof Local){
170             localUses.add((Local)temp);
171             System.out.println("Added "+temp+" to local uses for switch");
172         }
173         else if(temp instanceof FieldRef){
174             fieldUses.add((FieldRef)temp);
175             System.out.println("Added "+temp+" to field uses for switch");
176         }
177         }
178     }
179
180     //localuses stores Locals used
181
Iterator it = localUses.iterator();
182     while(it.hasNext()){
183         Local local = (Local)it.next();
184
185         addLocalUse(local,node);
186     }//end of going through all locals uses in switch key
187

188
189
190     //fieldUses stores FieldRef
191
it = fieldUses.iterator();
192     while(it.hasNext()){
193        FieldRef field = (FieldRef)it.next();
194        SootField sootField = field.getField();
195
196         addFieldUse(sootField,node);
197     }//end of going through all FieldRef uses in switch key
198
}
199
200
201
202
203     public void inASTStatementSequenceNode(ASTStatementSequenceNode node){
204     List statements = node.getStatements();
205     Iterator it = statements.iterator();
206     
207     while(it.hasNext()){
208         AugmentedStmt as = (AugmentedStmt)it.next();
209         Stmt s = as.get_Stmt();
210         //in the case of stmtts in a stmtt sequence each stmt is considered an entity
211
//compared to the case where these stmts occur within other constructs
212
//where the node is the entity
213
checkStatementUses(s,s);
214     }
215     }
216
217
218
219
220
221
222     /*
223      * The init of a for loop can use a local/Sootfield
224      * The condition of a for node can use a local/SootField
225      * The update in a for loop can use a local/SootField
226      *
227      */

228     public void inASTForLoopNode(ASTForLoopNode node){
229
230     //checking uses in init
231
List init = node.getInit();
232     Iterator it = init.iterator();
233     while(it.hasNext()){
234         AugmentedStmt as = (AugmentedStmt)it.next();
235         Stmt s = as.get_Stmt();
236         checkStatementUses(s,node);
237     }
238
239     //checking uses in condition
240
ASTCondition cond = node.get_Condition();
241     checkConditionalUses(cond,node);
242
243     
244     //checking uses in update
245
List update = node.getUpdate();
246     it = update.iterator();
247     while(it.hasNext()){
248         AugmentedStmt as = (AugmentedStmt)it.next();
249         Stmt s = as.get_Stmt();
250         checkStatementUses(s,node);
251     }
252     }
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267     public void checkStatementUses(Stmt s,Object JavaDoc useNodeOrStatement){
268     List useBoxes = s.getUseBoxes();
269
270     //remeber getUsesFromBoxes returns both Locals and FieldRefs
271
List uses= getUsesFromBoxes(useBoxes);
272
273
274     Iterator it = uses.iterator();
275     while(it.hasNext()){
276         Value temp = (Value)it.next();
277         if(temp instanceof Local){
278         addLocalUse((Local)temp,useNodeOrStatement);
279         }
280         else if(temp instanceof FieldRef){
281         FieldRef field = (FieldRef)temp;
282         SootField sootField = field.getField();
283         addFieldUse(sootField,useNodeOrStatement);
284         }
285     }
286     }
287
288
289
290
291
292     /*
293      * This method gets a list of all uses of locals/Sootfield in the condition
294      * and stores a use by this node
295      */

296     public void checkConditionalUses(ASTCondition cond,ASTNode node){
297     List useList = getUseList(cond);
298         
299     //System.out.println("FOR NODE with condition:"+cond+"USE list is:"+useList);
300

301     //FOR EACH USE
302
Iterator it = useList.iterator();
303     while(it.hasNext()){
304         Value temp = (Value)it.next();
305         if(temp instanceof Local){
306         addLocalUse((Local)temp,node);
307         }
308         else if(temp instanceof FieldRef){
309         FieldRef field = (FieldRef)temp;
310         SootField sootField = field.getField();
311         addFieldUse(sootField,node);
312         }
313     }//end of going through all locals uses in condition
314
}
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332     /*
333      * The condition of an if node can use a local
334      *
335      */

336     public void inASTIfNode(ASTIfNode node){
337     ASTCondition cond = node.get_Condition();
338     checkConditionalUses(cond,node);
339     }
340
341
342     /*
343      * The condition of an ifElse node can use a local
344      *
345      */

346     public void inASTIfElseNode(ASTIfElseNode node){
347     ASTCondition cond = node.get_Condition();
348     checkConditionalUses(cond,node);
349     }
350
351
352
353
354     /*
355      * The condition of a while node can use a local
356      *
357      */

358     public void inASTWhileNode(ASTWhileNode node){
359     ASTCondition cond = node.get_Condition();
360     checkConditionalUses(cond,node);
361     }
362
363
364
365     /*
366      * The condition of a doWhile node can use a local
367      *
368      */

369     public void inASTDoWhileNode(ASTDoWhileNode node){
370     ASTCondition cond = node.get_Condition();
371     checkConditionalUses(cond,node);
372     }
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401     /*
402      * Given a unary/binary or aggregated condition this method is used
403      * to find the locals/SootFields used in the condition
404      * @param The condition to be checked for Local or FieldRef uses
405      * @return a list containing all Locals and FieldRefs used in this condition
406      */

407     public List getUseList(ASTCondition cond){
408     ArrayList useList = new ArrayList();
409     if(cond instanceof ASTAggregatedCondition){
410         useList.addAll(getUseList(((ASTAggregatedCondition)cond).getLeftOp()));
411         useList.addAll(getUseList(((ASTAggregatedCondition)cond).getRightOp()));
412         return useList;
413     }
414     else if(cond instanceof ASTUnaryCondition){
415         //get uses from unary condition
416
List uses = new ArrayList();
417
418         Value val = ((ASTUnaryCondition)cond).getValue();
419         if(val instanceof Local || val instanceof FieldRef){
420         uses.add(val);
421         }
422         else{
423         List useBoxes = val.getUseBoxes();
424         uses= getUsesFromBoxes(useBoxes);
425         }
426         return uses;
427     }
428     else if(cond instanceof ASTBinaryCondition){
429         //get uses from binaryCondition
430
Value val = ((ASTBinaryCondition)cond).getConditionExpr();
431         List useBoxes = val.getUseBoxes();
432         return getUsesFromBoxes(useBoxes);
433     }
434     else{
435         throw new RuntimeException JavaDoc("Method getUseList in ASTUsesAndDefs encountered unknown condition type");
436     }
437     }
438
439
440
441
442
443
444
445
446
447
448
449
450     private void addLocalUse(Local local, Object JavaDoc obj){
451
452     Object JavaDoc temp = localsToUses.get(local);
453     List uses;
454     if(temp == null)
455         uses = new ArrayList();
456     else
457         uses = (ArrayList)temp;
458
459     //add local to useList
460
uses.add(obj);
461
462     //update mapping
463
localsToUses.put(local,uses);
464     }
465
466
467
468
469
470
471     private void addFieldUse(SootField field, Object JavaDoc obj){
472
473     Object JavaDoc temp = fieldsToUses.get(field);
474     List uses;
475     if(temp == null)
476         uses = new ArrayList();
477     else
478         uses = (ArrayList)temp;
479
480     // add field to useList
481
uses.add(obj);
482
483     //update mapping
484
fieldsToUses.put(field,uses);
485     }
486
487
488
489
490
491
492     /*
493      * Method is used to strip away boxes from the actual values
494      * only those are returned which are locals or FieldRefs
495      */

496     private List getUsesFromBoxes(List useBoxes){
497     ArrayList toReturn = new ArrayList();
498     Iterator it = useBoxes.iterator();
499     while(it.hasNext()){
500         Value val =((ValueBox)it.next()).getValue();
501         if(val instanceof Local || val instanceof FieldRef)
502         toReturn.add(val);
503     }
504     //System.out.println("VALUES:"+toReturn);
505
return toReturn;
506     }
507
508
509
510
511
512     public List getUsesForField(SootField field){
513     Object JavaDoc temp = fieldsToUses.get(field);
514     if(temp == null)
515         return null;
516     else
517         return (List)temp;
518     }
519
520
521
522
523
524     public List getUsesForLocal(Local local){
525     Object JavaDoc temp = localsToUses.get(local);
526     if(temp == null)
527         return null;
528     else
529         return (List)temp;
530     }
531
532 }
Popular Tags