KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > soot > dava > internal > AST > ASTMethodNode


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

21
22 /**
23  * Maintained by Nomair A. Naeem
24  */

25
26 /*
27  * CHANGE LOG: 23rd november 2005, Adding method getDeclaredLocals to return all locals
28  * declared in the declarations ASTStatementSequenceNode
29  */

30
31 package soot.dava.internal.AST;
32
33 import soot.*;
34 import java.util.*;
35 import soot.dava.*;
36 import soot.util.*;
37 import soot.jimple.*;
38 import soot.jimple.internal.*;
39
40 import soot.grimp.*;
41 import soot.grimp.internal.*;
42
43 import soot.dava.internal.javaRep.*;
44 import soot.dava.internal.asg.*;
45 import soot.dava.toolkits.base.AST.*;
46 import soot.dava.toolkits.base.AST.analysis.*;
47
48 public class ASTMethodNode extends ASTNode {
49     private List body;
50
51     private DavaBody davaBody;
52
53     private ASTStatementSequenceNode declarations;
54
55     /*
56      typeToLocals stores the type of the local and a list of all locals with that type
57      */

58     private Map typeToLocals;//Nomair A. Naeem 24th January why is this a field? why not a localVar of storeLocals???
59

60     public ASTStatementSequenceNode getDeclarations() {
61         return declarations;
62     }
63
64     public void setDeclarations(ASTStatementSequenceNode decl) {
65         declarations = decl;
66     }
67
68     public void setDavaBody(DavaBody bod) {
69         this.davaBody = bod;
70     }
71
72     public DavaBody getDavaBody() {
73         return davaBody;
74     }
75
76     public void storeLocals(Body OrigBody) {
77         if ((OrigBody instanceof DavaBody) == false)
78             throw new RuntimeException JavaDoc(
79                     "Only DavaBodies should invoke this method");
80
81         davaBody = (DavaBody) OrigBody;
82         typeToLocals = new DeterministicHashMap(
83                 OrigBody.getLocalCount() * 2 + 1, 0.7f);
84
85         HashSet params = new HashSet();
86         params.addAll(davaBody.get_ParamMap().values());
87         params.addAll(davaBody.get_CaughtRefs());
88         HashSet thisLocals = davaBody.get_ThisLocals();
89
90         //populating the typeToLocals Map
91
Iterator localIt = OrigBody.getLocals().iterator();
92         while (localIt.hasNext()) {
93             Local local = (Local) localIt.next();
94
95             if (params.contains(local) || thisLocals.contains(local))
96                 continue;
97
98             List localList;
99
100             String JavaDoc typeName;
101             Type t = local.getType();
102
103             typeName = t.toString();
104
105             if (typeToLocals.containsKey(t))
106                 localList = (List) typeToLocals.get(t);
107             else {
108                 localList = new ArrayList();
109                 typeToLocals.put(t, localList);
110             }
111
112             localList.add(local);
113         }
114
115         //create a StatementSequenceNode with all the declarations
116

117         List statementSequence = new ArrayList();
118
119         Iterator typeIt = typeToLocals.keySet().iterator();
120
121         while (typeIt.hasNext()) {
122             Type typeObject = (Type) typeIt.next();
123             String JavaDoc type = typeObject.toString();
124
125             List localList = (List) typeToLocals.get(typeObject);
126             Object JavaDoc[] locals = localList.toArray();
127
128             DVariableDeclarationStmt varStmt = null;
129             varStmt = new DVariableDeclarationStmt(typeObject,davaBody);
130
131             for (int k = 0; k < locals.length; k++) {
132                 varStmt.addLocal((Local) locals[k]);
133             }
134             AugmentedStmt as = new AugmentedStmt(varStmt);
135             statementSequence.add(as);
136         }
137
138         declarations = new ASTStatementSequenceNode(statementSequence);
139
140         body.add(0, declarations);
141         subBodies = new ArrayList();
142         subBodies.add(body);
143     }
144
145     public ASTMethodNode(List body) {
146         super();
147         this.body = body;
148
149         subBodies.add(body);
150     }
151
152     /*
153      Nomair A. Naeem 23rd November 2005
154      Need to efficiently get all locals being declared in the declarations node
155      Dont really care what type they are.. Interesting thing is that they are all different names :)
156      */

157     public List getDeclaredLocals() {
158         List toReturn = new ArrayList();
159
160         Iterator it = declarations.getStatements().iterator();
161
162         while (it.hasNext()) {//going through each stmt
163
Stmt s = ((AugmentedStmt) it.next()).get_Stmt();
164
165             if (!(s instanceof DVariableDeclarationStmt))
166                 continue;//shouldnt happen since this node only contains declarations
167

168             DVariableDeclarationStmt varStmt = (DVariableDeclarationStmt) s;
169
170             //get the locals of this particular type
171
List declarations = varStmt.getDeclarations();
172             Iterator decIt = declarations.iterator();
173             while (decIt.hasNext()) {
174                 //going through each local declared
175

176                 toReturn.add(decIt.next());
177             }//going through all locals of this type
178
}//going through all stmts
179
return toReturn;
180     }
181
182     /*
183      * Given a local first searches the declarations for the local
184      * Once it is found the local is removed from its declaring stmt
185      * If the declaring stmt does not declare any more locals the stmt itself is removed
186      * IT WOULD BE NICE TO ALSO CHECK IF THIS WAS THE LAST STMT IN THE NODE IN WHICH CASE THE NODE SHOULD BE REMOVED
187      * just afraid of its after effects on other analyses!!!!
188      */

189     public void removeDeclaredLocal(Local local) {
190         Stmt s = null;
191         Iterator it = declarations.getStatements().iterator();
192         while (it.hasNext()) {//going through each stmt
193
s = ((AugmentedStmt) it.next()).get_Stmt();
194
195             if (!(s instanceof DVariableDeclarationStmt))
196                 continue;//shouldnt happen since this node only contains declarations
197

198             DVariableDeclarationStmt varStmt = (DVariableDeclarationStmt) s;
199
200             //get the locals declared in this stmt
201
List declarations = varStmt.getDeclarations();
202             Iterator decIt = declarations.iterator();
203
204             boolean foundIt = false;//becomes true if the local was found in this stmt
205
while (decIt.hasNext()) {
206                 //going through each local declared
207
Local temp = (Local) decIt.next();
208                 if (temp.getName().compareTo(local.getName()) == 0) {
209                     //found it
210
foundIt = true;
211                     break;
212                 }
213             }
214
215             if (foundIt) {
216                 varStmt.removeLocal(local);
217                 break; //breaks going through other stmts as we already did what we needed to do
218
}
219         }
220         //the removal of a local might have made some declaration empty
221
//remove such a declaraion
222

223         List newSequence = new ArrayList();
224         it = declarations.getStatements().iterator();
225         while (it.hasNext()) {
226             AugmentedStmt as = (AugmentedStmt) it.next();
227             s = as.get_Stmt();
228
229             if (!(s instanceof DVariableDeclarationStmt))
230                 continue;
231
232             DVariableDeclarationStmt varStmt = (DVariableDeclarationStmt) s;
233
234             if (varStmt.getDeclarations().size() != 0)
235                 newSequence.add(as);
236
237         }
238         declarations.setStatements(newSequence);
239
240     }
241
242     /*
243      Nomair A Naeem 21-FEB-2005
244      Used by UselessLabeledBlockRemove to update a body
245      */

246     public void replaceBody(List body) {
247         this.body = body;
248         subBodies = new ArrayList();
249         subBodies.add(body);
250     }
251
252     public Object JavaDoc clone() {
253         ASTMethodNode toReturn = new ASTMethodNode(body);
254         toReturn.setDeclarations((ASTStatementSequenceNode) declarations
255                 .clone());
256         return toReturn;
257     }
258
259     public void perform_Analysis(ASTAnalysis a) {
260         perform_AnalysisOnSubBodies(a);
261     }
262
263     public void toString(UnitPrinter up) {
264         if (!(up instanceof DavaUnitPrinter))
265             throw new RuntimeException JavaDoc(
266                     "Only DavaUnitPrinter should be used to print DavaBody");
267
268         DavaUnitPrinter dup = (DavaUnitPrinter) up;
269
270         /*
271          Print out constructor first
272          */

273         if (davaBody != null) {
274             InstanceInvokeExpr constructorExpr = davaBody.get_ConstructorExpr();
275
276             if (constructorExpr != null) {
277                 if (davaBody.getMethod().getDeclaringClass().getName().equals(
278                         constructorExpr.getMethodRef().declaringClass()
279                                 .toString()))
280                     dup.printString(" this(");
281                 else
282                     dup.printString(" super(");
283
284                 Iterator ait = constructorExpr.getArgs().iterator();
285                 while (ait.hasNext()) {
286                     /*
287                      * January 12th, 2006
288                      * found a problem here. If a super has a method
289                      * call as one of the args then the toString prints the
290                      * jimple representation and does not convert it into java
291                      * syntax
292                      */

293                     Object JavaDoc arg = ait.next();
294                     if (arg instanceof Value) {
295                         //dup.printString(((Value)arg).toString());
296
//already in super no indentation required
297
dup.noIndent();
298                         ((Value) arg).toString(dup);
299                     } else {
300                         /**
301                          * Staying with the old style
302                          */

303                         dup.printString(arg.toString());
304                     }
305
306                     if (ait.hasNext())
307                         dup.printString(", ");
308                 }
309
310                 dup.printString(");\n");
311             }
312
313             // print out the remaining body
314
up.newline();
315         }//if //davaBody != null
316

317         //notice that for an ASTMethod Node the first element of the body list is the
318
//declared variables
319

320         //System.out.println("printing body from within MEthodNode\n\n"+body.toString());
321
body_toString(up, body);
322     }
323
324     public String JavaDoc toString() {
325         StringBuffer JavaDoc b = new StringBuffer JavaDoc();
326         /*
327          Print out constructor first
328          */

329         if (davaBody != null) {
330             InstanceInvokeExpr constructorExpr = davaBody.get_ConstructorExpr();
331             if (constructorExpr != null) {
332
333                 if (davaBody.getMethod().getDeclaringClass().getName().equals(
334                         constructorExpr.getMethodRef().declaringClass()
335                                 .toString()))
336                     b.append(" this(");
337                 else
338                     b.append(" super(");
339
340                 Iterator ait = constructorExpr.getArgs().iterator();
341                 while (ait.hasNext()) {
342                     b.append(ait.toString());
343
344                     if (ait.hasNext())
345                         b.append(", ");
346                 }
347
348                 b.append(");\n\n");
349             }
350         }
351
352         // print out the remaining body
353
b.append(body_toString(body));
354         return b.toString();
355     }
356
357     /*
358      Nomair A. Naeem, 7-FEB-05
359      Part of Visitor Design Implementation for AST
360      See: soot.dava.toolkits.base.AST.analysis For details
361      */

362     public void apply(Analysis a) {
363         a.caseASTMethodNode(this);
364     }
365 }
366
Popular Tags