KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > soot > dava > toolkits > base > AST > transformations > OrAggregatorOne


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.AST.transformations;
21
22 import soot.*;
23 import java.util.*;
24 import soot.jimple.*;
25 import soot.dava.internal.SET.*;
26 import soot.dava.internal.AST.*;
27 import soot.dava.internal.asg.*;
28 import soot.dava.internal.javaRep.*;
29 import soot.dava.toolkits.base.AST.analysis.*;
30
31
32 /*
33   Nomair A. Naeem 18-FEB-2005
34
35   The class is responsible to do the following transformation on the AST
36   
37   label_1:{ label_1:{
38      label_0:{ if(cond1 || cond2){
39          if(cond1){ Body1
40             break label_0; }
41          } }
42          if(!cond2){ Body2
43             break label_1; ------>
44      } Cant remove label_1 as Body 1
45     }//end of label_0 might have reference to it
46     Body1 can however set some flag if we are
47   }//end of label_1 sure that label_1 is not broken
48   Body2 and later removed
49
50
51   TO MAKE CODE EFFECIENT BLOCK THE ANALYSIS TO GOING INTO STATEMENTS
52   this is done by overriding the caseASTStatementSequenceNode
53 */

54
55 public class OrAggregatorOne extends DepthFirstAdapter{
56
57     public OrAggregatorOne(){
58     }
59     public OrAggregatorOne(boolean verbose){
60     super(verbose);
61     }
62
63     public void caseASTStatementSequenceNode(ASTStatementSequenceNode node){
64     }
65
66     public void outASTLabeledBlockNode(ASTLabeledBlockNode node){
67     String JavaDoc outerLabel = node.get_Label().toString();
68     if(outerLabel==null)
69         return;
70
71     String JavaDoc innerLabel=null;
72
73     ASTLabeledBlockNode secondLabeledBlockNode = isLabelWithinLabel(node);
74     if(secondLabeledBlockNode == null){
75         //node doesnt have an immediate label following it
76
return;
77     }
78
79     //store the labelname
80
innerLabel=secondLabeledBlockNode.get_Label().toString();
81     if(innerLabel==null){
82         //empty or marked for deletion
83
return;
84     }
85     
86     List secondLabelsBodies= getSecondLabeledBlockBodies(secondLabeledBlockNode);
87
88     boolean allIfs = checkAllAreIfsWithProperBreaks(secondLabelsBodies.iterator(),outerLabel,innerLabel);
89     if(!allIfs){
90         //pattern doesnt match
91
return;
92     }
93
94     //the pattern has been matched do the transformation
95

96     // Create a list of conditions to be Ored together
97
// remembering that the last ones condition is to be flipped
98
List conditions = getConditions(secondLabelsBodies.iterator());
99
100     //create an aggregated condition
101
Iterator condIt = conditions.iterator();
102     ASTCondition newCond=null;;
103     while(condIt.hasNext()){
104         ASTCondition next = (ASTCondition)condIt.next();
105         if(newCond==null)
106         newCond=next;
107         else
108         newCond=new ASTOrCondition(newCond,next);
109     }
110     
111
112     //will contain the Body of the ASTIfNode
113
List newIfBody = new ArrayList();
114
115     //get_SubBodies of upper labeled block
116
List subBodies = node.get_SubBodies();
117     //we know that there is only one SubBody for this node retrieve that
118

119     List labeledBlockBody = (List)subBodies.get(0);
120     //from the isLabelWithinLabel method we know that the first is the labeled block
121
//discard that keep the rest
122
Iterator subBodiesIt = labeledBlockBody.iterator();
123     subBodiesIt.next();//discarding first
124
while(subBodiesIt.hasNext()){
125         ASTNode temp = (ASTNode)subBodiesIt.next();
126         newIfBody.add(temp);
127     }
128
129     ASTIfNode newNode = new ASTIfNode(new SETNodeLabel(),newCond,newIfBody);
130
131     List newLabeledBlockBody = new ArrayList();
132     newLabeledBlockBody.add(newNode);
133
134     G.v().ASTTransformations_modified = true;
135     //System.out.println("OR AGGREGATING ONE!!!");
136
node.replaceBody(newLabeledBlockBody);
137
138
139     /*
140       See if the outer label can be marked as useless
141     */

142
143     UselessLabelFinder.v().findAndKill(node);
144     }
145     
146
147     private ASTLabeledBlockNode isLabelWithinLabel(ASTLabeledBlockNode node){
148     List subBodies = node.get_SubBodies();
149     if(subBodies.size()==0){ //shouldnt happen
150
//labeledBlockNodes size is zero this is a useless label
151
//marked for removal by setting an empty SETNodeLabel
152
node.set_Label(new SETNodeLabel());
153         return null;
154     }
155     
156     //LabeledBlockNode had SubBody we know there is always only one
157
List bodies = (List)subBodies.get(0);
158     //these bodies should be a labelled block followed by something
159
if(bodies.size()==0){
160         //there is nothing inside this labeledBlock
161
//an empty Body is useless
162
node.set_Label(new SETNodeLabel());
163         return null;
164     }
165
166     //there is some ASTNode there
167
ASTNode firstBody = (ASTNode)bodies.get(0);
168     if(!(firstBody instanceof ASTLabeledBlockNode)){
169         //first body is not a labeledBlock node thus the pattern
170
//does not have the shape
171
// label_1:
172
// label_0
173
return null;
174     }
175     
176     //Pattern is fine return the ASTLabeledBlockNode found
177
return (ASTLabeledBlockNode)firstBody;
178     }
179     
180
181     private List getSecondLabeledBlockBodies(ASTLabeledBlockNode secondLabeledBlockNode){
182     //retrieve the SubBodies of this second labeledblock
183
List secondLabelsSubBodies = secondLabeledBlockNode.get_SubBodies();
184     if(secondLabelsSubBodies.size()==0){
185         //there is nothing in the labeledblock
186
//highlly unlikely but if yes then set labeledBlockNode for not printing/deletion
187
secondLabeledBlockNode.set_Label(new SETNodeLabel());
188         return null;
189     }
190     /*
191       there is atleast one body in there and infact it should be only one
192       since this is a labeledBlockNode
193     */

194     List secondLabelsBodies = (List)secondLabelsSubBodies.get(0);
195     
196     //return the list
197
return secondLabelsBodies;
198     }
199     
200     private boolean checkAllAreIfsWithProperBreaks(Iterator it,String JavaDoc outerLabel, String JavaDoc innerLabel){
201     //the pattern says that ALL bodies in this list should be IF statements
202
while(it.hasNext()){
203         ASTNode secondLabelsBody = (ASTNode)it.next();
204         
205         //check that this is a ifNode with a single statement
206
Stmt stmt = isIfNodeWithOneStatement(secondLabelsBody);
207         if(stmt == null){
208         //pattern is broken
209
return false;
210         }
211         //check if the single stmt is a break stmt
212
String JavaDoc labelBroken = breaksLabel(stmt);
213         if(labelBroken == null){
214         //stmt does not break a label
215
return false;
216         }
217         
218         //check if this is the inner label broken and is not the last in the iterator
219
if(labelBroken.compareTo(innerLabel)==0 && it.hasNext())
220         continue;
221         //check if this is the outer label broken and is the last in the iterator
222
if(labelBroken.compareTo(outerLabel)==0 && !it.hasNext())
223         continue;
224
225         //if we get here that means this is not a break breaking the label we want
226
return false;
227     }//end of while going through all the bodies of the secondlabel
228

229     //if we get here that means everything was according to the pattern
230
return true;
231     }
232
233
234
235
236     /*
237       If the stmt is a break stmt then this method
238       returns the labels name
239       else returns null
240     */

241     private String JavaDoc breaksLabel(Stmt stmt){
242     if(!(stmt instanceof DAbruptStmt)){
243         //this is not a break stmt
244
return null;
245     }
246     DAbruptStmt abStmt = (DAbruptStmt)stmt;
247     if(!abStmt.is_Break()){
248         //not a break stmt
249
return null;
250     }
251     SETNodeLabel label = abStmt.getLabel();
252     return label.toString();
253     }
254
255
256
257     private Stmt isIfNodeWithOneStatement(ASTNode secondLabelsBody){
258     if(!(secondLabelsBody instanceof ASTIfNode)){
259         //pattern broken as this should be a IfNode
260
return null;
261     }
262     //check that the body of ASTIfNode has a single ASTStatementSequence
263

264     ASTIfNode ifNode =(ASTIfNode)secondLabelsBody;
265     List ifSubBodies =ifNode.get_SubBodies();
266     if(ifSubBodies.size()!=1){
267         //if body should always have oneSubBody
268
return null;
269     }
270     
271     //if has one SubBody
272
List ifBody = (List)ifSubBodies.get(0);
273     
274     //Looking for a statement sequence node with a single stmt
275
if(ifBody.size()!=1){
276         //there should only be one body
277
return null;
278     }
279
280     //The only subBody has one ASTNode
281
ASTNode ifBodysBody = (ASTNode)ifBody.get(0);
282     if(!(ifBodysBody instanceof ASTStatementSequenceNode)){
283         //had to be a STMTSEQ node
284
return null;
285     }
286
287     //the only ASTnode is a ASTStatementSequence
288
List statements = ((ASTStatementSequenceNode)ifBodysBody).getStatements();
289     if(statements.size()!=1){
290         //there is more than one statement
291
return null;
292     }
293
294     //there is only one statement return the statement
295
AugmentedStmt as = (AugmentedStmt)statements.get(0);
296     Stmt s = as.get_Stmt();
297     return s;
298     }
299
300
301
302     /*
303       The method will go through the iterator because of the sequence
304       of methods called before in the outASTLabeledBlockNode
305       it knows the following:
306       1, All nodes are ASTIFNodes
307     */

308     private List getConditions(Iterator it){
309     List toReturn = new ArrayList();
310     while(it.hasNext()){
311         //safe cast since we know these are all ASTIfNodes
312
ASTIfNode node = (ASTIfNode)it.next();
313         
314         ASTCondition cond = node.get_Condition();
315         //check if this is the last in which case we need to flip
316
if(it.hasNext()){
317         //no need to flip
318
toReturn.add(cond);
319         }
320         else{
321         //need to flip condition
322
cond.flip();
323         toReturn.add(cond);
324         }
325     }//end of while
326
return toReturn;
327     }
328 }
Popular Tags