KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > soot > dava > DavaStaticBlockCleaner


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;
21
22
23 import soot.Body;
24 import soot.G;
25 import soot.Modifier;
26 import soot.Singletons;
27 import soot.SootClass;
28 import soot.SootMethod;
29 import soot.dava.internal.AST.ASTMethodNode;
30 import soot.dava.internal.AST.ASTNode;
31 import soot.dava.internal.AST.ASTStatementSequenceNode;
32 import soot.util.Chain;
33
34
35 /*
36  * Coded to remove the static "final" bug from Dava. Usually occurs in AspectJ code
37  * **********The staticBlockInlining Method is invoked by PackManager**************
38  *
39  * In the bug this is what used to happen:
40  *
41  * public static final ClassName myField;
42  * static{
43                CLASSNAME.postClinit();
44             
45           }
46
47  * postClinit(){ myField = new ClassName(); }
48  *
49  * Now this causes a problem since final fields can not be defined using a method call
50  * So the solution was to inline just this method. to get something like
51  * static{
52              myField = new ClassName();
53       }
54  * At the same time the code in the method postClinit is removed and an exception is thrown if this method is invoked
55  */

56
57
58
59 public class DavaStaticBlockCleaner {
60     SootClass sootClass;
61
62
63     public DavaStaticBlockCleaner(Singletons.Global g) {
64     }
65
66     public static DavaStaticBlockCleaner v() {
67         return G.v().soot_dava_DavaStaticBlockCleaner();
68     }
69
70
71     //invoked by the PackManager
72
public void staticBlockInlining(SootClass sootClass){
73         this.sootClass=sootClass;
74         //retrieve the clinit method if any for sootClass
75
//the clinit method gets converted into the static block which could initialize the final variable
76
if(!sootClass.declaresMethod("void <clinit>()")){
77             //System.out.println("no clinit");
78
return;
79         }
80
81         SootMethod clinit = sootClass.getMethod("void <clinit>()");
82         //System.out.println(clinit);
83

84         //retireve the active body
85
if (!clinit.hasActiveBody())
86             throw new RuntimeException JavaDoc("method "+ clinit.getName()+ " has no active body!");
87
88     
89         Body clinitBody = clinit.getActiveBody();
90         Chain units = ((DavaBody) clinitBody).getUnits();
91
92         if (units.size() != 1) {
93             throw new RuntimeException JavaDoc("DavaBody AST doesn't have single root.");
94         }
95
96         ASTNode AST = (ASTNode) units.getFirst();
97         if(! (AST instanceof ASTMethodNode))
98             throw new RuntimeException JavaDoc("Starting node of DavaBody AST is not an ASTMethodNode");
99
100         //running methodCallFinder on the Clinit method
101
AST.apply(new MethodCallFinder(this));
102     }
103
104
105
106
107     /*
108      * Method called with a sootMethod to decide whether this method should be inlined or not
109      * returns null if it shouldnt be inlined
110      *
111      * A method can be inlined if it belongs to the same class and also if its static....(why???)
112      */

113     public ASTMethodNode inline(SootMethod maybeInline){
114     //check if this method should be inlined
115

116     if(sootClass !=null){
117         //1, method should belong to the same class as the clinit method
118
if(sootClass.declaresMethod(maybeInline.getSubSignature())){
119         //System.out.println("The method invoked is from the same class");
120
//2, method should be static
121

122         if (Modifier.isStatic(maybeInline.getModifiers())){
123             //decided to inline
124
//send the ASTMethod node of the TO BE INLINED METHOD
125

126             //retireve the active body
127
if (!maybeInline.hasActiveBody())
128             throw new RuntimeException JavaDoc("method "+ maybeInline.getName()+ " has no active body!");
129
130     
131             Body bod = maybeInline.getActiveBody();
132     
133             Chain units = ((DavaBody) bod).getUnits();
134
135             if (units.size() != 1) {
136             throw new RuntimeException JavaDoc("DavaBody AST doesn't have single root.");
137             }
138
139             ASTNode ASTtemp = (ASTNode) units.getFirst();
140             if(! (ASTtemp instanceof ASTMethodNode))
141             throw new RuntimeException JavaDoc("Starting node of DavaBody AST is not an ASTMethodNode");
142
143             //restricting to methods which do not have any variables declared
144
ASTMethodNode toReturn = (ASTMethodNode)ASTtemp;
145
146             ASTStatementSequenceNode declarations = toReturn.getDeclarations();
147             if(declarations.getStatements().size() == 0){
148             //inline only if there are no declarations in the method inlined
149
//System.out.println("No declarations in the method. we can inline this method");
150
return toReturn;
151             }
152         }
153         }
154     }
155     return null;//meaning dont inline
156
}
157     
158 }
Popular Tags