KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > soot > javaToJimple > Util


1 /* Soot - a J*va Optimization Framework
2  * Copyright (C) 2004 Jennifer Lhotak
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.javaToJimple;
21
22 import java.util.*;
23
24 public class Util {
25
26     public static void addInnerClassTag(soot.SootClass sc, String JavaDoc innerName, String JavaDoc outerName, String JavaDoc simpleName, int access){
27         // maybe need file sep here - may break windows
28

29         innerName = soot.util.StringTools.replaceAll(innerName, ".", "/");
30         if (outerName != null){
31             outerName = soot.util.StringTools.replaceAll(outerName, ".", "/");
32         }
33         sc.addTag(new soot.tagkit.InnerClassTag(
34             innerName,
35             outerName,
36             simpleName,
37             access));
38     
39     }
40     
41     public static String JavaDoc getParamNameForClassLit(polyglot.types.Type type){
42         String JavaDoc name = "";
43         if (type.isArray()){
44             int dims = ((polyglot.types.ArrayType)type).dims();
45             polyglot.types.Type arrType = ((polyglot.types.ArrayType)type).base();
46             while (arrType instanceof polyglot.types.ArrayType) {
47               arrType = ((polyglot.types.ArrayType)arrType).base();
48             }
49             String JavaDoc fieldName = "";
50             if (arrType.isBoolean()){
51                 fieldName = "Z";
52             }
53             else if (arrType.isByte()){
54                 fieldName = "B";
55             }
56             else if (arrType.isChar()){
57                 fieldName = "C";
58             }
59             else if (arrType.isDouble()){
60                 fieldName = "D";
61             }
62             else if (arrType.isFloat()){
63                 fieldName = "F";
64             }
65             else if (arrType.isInt()){
66                 fieldName = "I";
67             }
68             else if (arrType.isLong()){
69                 fieldName = "J";
70             }
71             else if (arrType.isShort()){
72                 fieldName = "S";
73             }
74             else {
75                 String JavaDoc typeSt = getSootType(arrType).toString();
76                 fieldName = "L"+typeSt;
77             }
78             
79             for (int i = 0; i < dims; i++){
80                 name += "[";
81             }
82             name += fieldName;
83             if (!arrType.isPrimitive()){
84                 name += ";";
85             }
86         }
87         else {
88             name = getSootType(type).toString();
89         }
90         return name;
91     }
92     
93     public static String JavaDoc getFieldNameForClassLit(polyglot.types.Type type){
94         String JavaDoc fieldName = "";
95         if (type.isArray()){
96             int dims = ((polyglot.types.ArrayType)type).dims();
97             polyglot.types.Type arrType = ((polyglot.types.ArrayType)type).base();
98             while (arrType instanceof polyglot.types.ArrayType) {
99               arrType = ((polyglot.types.ArrayType)arrType).base();
100             }
101             fieldName = "array$";
102             for (int i = 0; i < (dims - 1); i++){
103                 fieldName += "$";
104             }
105             if (arrType.isBoolean()){
106                 fieldName += "Z";
107             }
108             else if (arrType.isByte()){
109                 fieldName += "B";
110             }
111             else if (arrType.isChar()){
112                 fieldName += "C";
113             }
114             else if (arrType.isDouble()){
115                 fieldName += "D";
116             }
117             else if (arrType.isFloat()){
118                 fieldName += "F";
119             }
120             else if (arrType.isInt()){
121                 fieldName += "I";
122             }
123             else if (arrType.isLong()){
124                 fieldName += "J";
125             }
126             else if (arrType.isShort()){
127                 fieldName += "S";
128             }
129             else {
130                 String JavaDoc typeSt = getSootType(arrType).toString();
131                 typeSt = soot.util.StringTools.replaceAll(typeSt, ".", "$");
132
133                 fieldName = fieldName+"L"+typeSt;
134             }
135        }
136        else {
137             fieldName = "class$";
138             String JavaDoc typeSt = getSootType(type).toString();
139             typeSt = soot.util.StringTools.replaceAll(typeSt, ".", "$");
140             fieldName = fieldName+typeSt;
141        }
142        
143        return fieldName;
144     }
145     
146     public static String JavaDoc getSourceFileOfClass(soot.SootClass sootClass){
147         String JavaDoc name = sootClass.getName();
148         int index = name.indexOf("$");
149         
150         // inner classes are found in the very outer class
151
if (index != -1){
152             name = name.substring(0, index);
153         }
154         return name;
155     }
156     
157     public static void addLnPosTags(soot.tagkit.Host host, polyglot.util.Position pos) {
158         if (pos != null) {
159             addLnPosTags(host, pos.line(), pos.endLine(), pos.column(), pos.endColumn());
160         }
161     }
162     
163     public static void addLnPosTags(soot.tagkit.Host host, int sline, int eline, int spos, int epos) {
164         if (soot.options.Options.v().keep_line_number()){
165             host.addTag(new soot.tagkit.SourceLnPosTag(sline, eline, spos, epos));
166         }
167     }
168     
169     /**
170      * Position Tag Adder
171      */

172     public static void addPosTag(soot.tagkit.Host host, polyglot.util.Position pos) {
173         if (pos != null) {
174             addPosTag(host, pos.column(), pos.endColumn());
175         }
176     }
177
178     public static void addMethodPosTag(soot.tagkit.Host meth, int start, int end){
179     
180         meth.addTag(new soot.tagkit.SourcePositionTag(start, end));
181     }
182     
183     /**
184      * Position Tag Adder
185      */

186     public static void addPosTag(soot.tagkit.Host host, int sc, int ec) {
187
188         host.addTag(new soot.tagkit.SourcePositionTag(sc, ec));
189     }
190
191     public static void addMethodLineTag(soot.tagkit.Host host, int sline, int eline){
192         if (soot.options.Options.v().keep_line_number()){
193             host.addTag(new soot.tagkit.SourceLineNumberTag(sline, eline));
194         }
195     }
196     
197     /**
198      * Line Tag Adder
199      */

200     public static void addLineTag(soot.tagkit.Host host, polyglot.ast.Node node) {
201
202         if (soot.options.Options.v().keep_line_number()){
203             if (node.position() != null) {
204                 host.addTag(new soot.tagkit.SourceLineNumberTag(node.position().line(), node.position().line()));
205                 
206             }
207         }
208     }
209     
210     /**
211      * Line Tag Adder
212      */

213     public static void addLineTag(soot.tagkit.Host host, int sLine, int eLine) {
214
215         host.addTag(new soot.tagkit.SourceLineNumberTag(sLine, eLine));
216                     
217     }
218     
219     
220     
221     public static soot.Local getThis(soot.Type sootType, soot.Body body, HashMap getThisMap, LocalGenerator lg){
222
223         if (InitialResolver.v().hierarchy() == null){
224             InitialResolver.v().hierarchy(new soot.FastHierarchy());
225         }
226         
227         soot.FastHierarchy fh = InitialResolver.v().hierarchy();
228        
229         //System.out.println("getting this for type: "+sootType);
230
// if this for type already created return it from map
231
//if (getThisMap.containsKey(sootType)){
232
// return (soot.Local)getThisMap.get(sootType);
233
//}
234
soot.Local specialThisLocal = body.getThisLocal();
235         // if need this just return it
236
if (specialThisLocal.getType().equals(sootType)) {
237            
238             getThisMap.put(sootType, specialThisLocal);
239             return specialThisLocal;
240         }
241        
242         // check to see if this method has a local of the correct type (it will
243
// if its an initializer - then ust use it)
244
// here we need an exact type I think
245
if (bodyHasLocal(body, sootType)){
246             soot.Local l = getLocalOfType(body, sootType);
247             getThisMap.put(sootType, l);
248             return l;
249         }
250         
251         // otherwise get this$0 for one level up
252
soot.SootClass classToInvoke = ((soot.RefType)specialThisLocal.getType()).getSootClass();
253         soot.SootField outerThisField = classToInvoke.getFieldByName("this$0");
254         soot.Local t1 = lg.generateLocal(outerThisField.getType());
255         
256         soot.jimple.FieldRef fieldRef = soot.jimple.Jimple.v().newInstanceFieldRef(specialThisLocal, outerThisField.makeRef());
257         soot.jimple.AssignStmt fieldAssignStmt = soot.jimple.Jimple.v().newAssignStmt(t1, fieldRef);
258         body.getUnits().add(fieldAssignStmt);
259          
260         if (fh.canStoreType(t1.getType(), sootType)){
261             getThisMap.put(sootType, t1);
262             return t1;
263         }
264         
265         // check to see if this method has a local of the correct type (it will
266
// if its an initializer - then ust use it)
267
// here we need an exact type I think
268
/*if (bodyHasLocal(body, sootType)){
269             soot.Local l = getLocalOfType(body, sootType);
270             getThisMap.put(sootType, l);
271             return l;
272         }*/

273         
274         // otherwise make a new access method
275
soot.Local t2 = t1;
276
277         return getThisGivenOuter(sootType, getThisMap, body, lg, t2);
278     }
279
280     private static soot.Local getLocalOfType(soot.Body body, soot.Type type) {
281         soot.FastHierarchy fh = InitialResolver.v().hierarchy();
282         Iterator stmtsIt = body.getUnits().iterator();
283         soot.Local correctLocal = null;
284         while (stmtsIt.hasNext()){
285             soot.jimple.Stmt s = (soot.jimple.Stmt)stmtsIt.next();
286             if (s instanceof soot.jimple.IdentityStmt && (s.hasTag("EnclosingTag") || s.hasTag("QualifyingTag"))){
287                 Iterator it = s.getDefBoxes().iterator();
288                 while (it.hasNext()){
289                     soot.ValueBox vb = (soot.ValueBox)it.next();
290                     if ((vb.getValue() instanceof soot.Local) && (fh.canStoreType(type, vb.getValue().getType()))){//(vb.getValue().getType().equals(type))){
291
correctLocal = (soot.Local)vb.getValue();
292                     }
293                 }
294             }
295         }
296         return correctLocal;
297     }
298     
299     private static boolean bodyHasLocal(soot.Body body, soot.Type type) {
300         soot.FastHierarchy fh = InitialResolver.v().hierarchy();
301         Iterator stmtsIt = body.getUnits().iterator();
302         soot.Local correctLocal = null;
303         while (stmtsIt.hasNext()){
304             soot.jimple.Stmt s = (soot.jimple.Stmt)stmtsIt.next();
305             if (s instanceof soot.jimple.IdentityStmt && (s.hasTag("EnclosingTag") || s.hasTag("QualifyingTag"))){
306                 Iterator it = s.getDefBoxes().iterator();
307                 while (it.hasNext()){
308                     soot.ValueBox vb = (soot.ValueBox)it.next();
309                     if ((vb.getValue() instanceof soot.Local) && (fh.canStoreType(type, vb.getValue().getType()))){//(vb.getValue().getType().equals(type))){
310
return true;
311                     }
312                 }
313             }
314         }
315         return false;
316         /*soot.FastHierarchy fh = InitialResolver.v().hierarchy();
317         Iterator it = body.getDefBoxes().iterator();
318         while (it.hasNext()){
319             soot.ValueBox vb = (soot.ValueBox)it.next();
320             if ((vb.getValue() instanceof soot.Local) && (fh.canStoreType(type, vb.getValue().getType()))){//(vb.getValue().getType().equals(type))){
321                 return true;
322             }
323         }
324         return false;*/

325     }
326
327     
328     public static soot.Local getThisGivenOuter(soot.Type sootType, HashMap getThisMap, soot.Body body, LocalGenerator lg, soot.Local t2){
329        
330         if (InitialResolver.v().hierarchy() == null){
331             InitialResolver.v().hierarchy(new soot.FastHierarchy());
332         }
333         
334         soot.FastHierarchy fh = InitialResolver.v().hierarchy();
335         
336         while (!fh.canStoreType(t2.getType(),sootType)){
337             soot.SootClass classToInvoke = ((soot.RefType)t2.getType()).getSootClass();
338             // make an access method and add it to that class for accessing
339
// its private this$0 field
340
soot.SootMethod methToInvoke = makeOuterThisAccessMethod(classToInvoke);
341             
342             // generate a local that corresponds to the invoke of that meth
343
soot.Local t3 = lg.generateLocal(methToInvoke.getReturnType());
344             ArrayList methParams = new ArrayList();
345             methParams.add(t2);
346             soot.Local res = getPrivateAccessFieldInvoke(methToInvoke.makeRef(), methParams, body, lg);
347             soot.jimple.AssignStmt assign = soot.jimple.Jimple.v().newAssignStmt(t3, res);
348             body.getUnits().add(assign);
349             t2 = t3;
350         }
351             
352         getThisMap.put(sootType, t2);
353
354         return t2;
355     }
356     
357
358     private static soot.SootMethod makeOuterThisAccessMethod(soot.SootClass classToInvoke){
359         String JavaDoc name = "access$"+soot.javaToJimple.InitialResolver.v().getNextPrivateAccessCounter()+"00";
360         ArrayList paramTypes = new ArrayList();
361         paramTypes.add(classToInvoke.getType());
362         
363         soot.SootMethod meth = new soot.SootMethod(name, paramTypes, classToInvoke.getFieldByName("this$0").getType(), soot.Modifier.STATIC);
364
365         classToInvoke.addMethod(meth);
366         PrivateFieldAccMethodSource src = new PrivateFieldAccMethodSource(
367             classToInvoke.getFieldByName("this$0").getType(),
368             "this$0",
369             classToInvoke.getFieldByName("this$0").isStatic(),
370             classToInvoke
371             );
372         meth.setActiveBody(src.getBody(meth, null));
373         meth.addTag(new soot.tagkit.SyntheticTag());
374         return meth;
375     }
376     
377     public static soot.Local getPrivateAccessFieldInvoke(soot.SootMethodRef toInvoke, ArrayList params, soot.Body body, LocalGenerator lg){
378         soot.jimple.InvokeExpr invoke = soot.jimple.Jimple.v().newStaticInvokeExpr(toInvoke, params);
379
380         soot.Local retLocal = lg.generateLocal(toInvoke.returnType());
381
382         soot.jimple.AssignStmt stmt = soot.jimple.Jimple.v().newAssignStmt(retLocal, invoke);
383         body.getUnits().add(stmt);
384
385         return retLocal;
386     }
387
388     public static boolean isSubType(polyglot.types.ClassType type, polyglot.types.ClassType superType){
389         if (type.equals(superType)) return true;
390         if (type.superType() == null) return false;
391         return isSubType((polyglot.types.ClassType)type.superType(), superType);
392     }
393     
394     /**
395      * Type handling
396      */

397     public static soot.Type getSootType(polyglot.types.Type type) {
398
399         if (type == null){
400             throw new RuntimeException JavaDoc("Trying to get soot type for null polyglot type");
401         }
402         soot.Type sootType = null;
403     
404         if (type.isInt()){
405             sootType = soot.IntType.v();
406         }
407         else if (type.isArray()){
408
409             polyglot.types.Type polyglotBase = ((polyglot.types.ArrayType)type).base();
410             while (polyglotBase instanceof polyglot.types.ArrayType) {
411               polyglotBase = ((polyglot.types.ArrayType)polyglotBase).base();
412             }
413             soot.Type baseType = getSootType(polyglotBase);
414             int dims = ((polyglot.types.ArrayType)type).dims();
415
416             // do something here if baseType is still an array
417
sootType = soot.ArrayType.v(baseType, dims);
418         }
419         else if (type.isBoolean()){
420             sootType = soot.BooleanType.v();
421         }
422         else if (type.isByte()){
423             sootType = soot.ByteType.v();
424         }
425         else if (type.isChar()){
426             sootType = soot.CharType.v();
427         }
428         else if (type.isDouble()){
429             sootType = soot.DoubleType.v();
430         }
431         else if (type.isFloat()){
432             sootType = soot.FloatType.v();
433         }
434         else if (type.isLong()){
435             sootType = soot.LongType.v();
436         }
437         else if (type.isShort()){
438             sootType = soot.ShortType.v();
439         }
440         else if (type.isNull()){
441             sootType = soot.NullType.v();
442         }
443         else if (type.isVoid()){
444             sootType = soot.VoidType.v();
445         }
446         else if (type.isClass()){
447             polyglot.types.ClassType classType = (polyglot.types.ClassType)type;
448             String JavaDoc className;
449             if (classType.isNested()) {
450                 if (classType.isAnonymous() && (soot.javaToJimple.InitialResolver.v().getAnonTypeMap() != null) && soot.javaToJimple.InitialResolver.v().getAnonTypeMap().containsKey(new polyglot.util.IdentityKey(classType))){
451                     className = (String JavaDoc)soot.javaToJimple.InitialResolver.v().getAnonTypeMap().get(new polyglot.util.IdentityKey(classType));
452                 }
453                 else if (classType.isLocal() && (soot.javaToJimple.InitialResolver.v().getLocalTypeMap() != null) && soot.javaToJimple.InitialResolver.v().getLocalTypeMap().containsKey(new polyglot.util.IdentityKey(classType))) {
454                     className = (String JavaDoc)soot.javaToJimple.InitialResolver.v().getLocalTypeMap().get(new polyglot.util.IdentityKey(classType));
455                 }
456                 else {
457                     String JavaDoc fullName = classType.fullName();
458                     String JavaDoc pkgName = "";
459                     if (classType.package_() != null){
460                         pkgName = classType.package_().fullName();
461                     }
462                     className = classType.name();
463                     
464                     if (classType.outer().isAnonymous() || classType.outer().isLocal()){
465                         className = getSootType(classType.outer()).toString()+"$"+className;
466                     }
467                     else {
468                         while (classType.outer() != null){
469                             className = classType.outer().name()+"$"+className;
470                             classType = classType.outer();
471                         }
472
473                         if (!pkgName.equals("")){
474                             className = pkgName+"."+className;
475                         }
476                     }
477                 }
478             }
479             else {
480                 className = classType.fullName();
481             }
482             
483             sootType = soot.RefType.v(className);
484         }
485         else{
486             throw new RuntimeException JavaDoc("Unknown Type");
487         }
488         return sootType;
489     }
490     
491     
492     /**
493      * Modifier Creation
494      */

495     public static int getModifier(polyglot.types.Flags flags) {
496
497         int modifier = 0;
498         
499         if (flags.isPublic()){
500             modifier = modifier | soot.Modifier.PUBLIC;
501         }
502         if (flags.isPrivate()){
503             modifier = modifier | soot.Modifier.PRIVATE;
504         }
505         if (flags.isProtected()){
506             modifier = modifier | soot.Modifier.PROTECTED;
507         }
508         if (flags.isFinal()){
509             modifier = modifier | soot.Modifier.FINAL;
510         }
511         if (flags.isStatic()){
512             modifier = modifier | soot.Modifier.STATIC;
513         }
514         if (flags.isNative()){
515             modifier = modifier | soot.Modifier.NATIVE;
516         }
517         if (flags.isAbstract()){
518             modifier = modifier | soot.Modifier.ABSTRACT;
519         }
520         if (flags.isVolatile()){
521             modifier = modifier | soot.Modifier.VOLATILE;
522         }
523         if (flags.isTransient()){
524             modifier = modifier | soot.Modifier.TRANSIENT;
525         }
526         if (flags.isSynchronized()){
527             modifier = modifier | soot.Modifier.SYNCHRONIZED;
528         }
529         if (flags.isInterface()){
530             modifier = modifier | soot.Modifier.INTERFACE;
531         }
532         if (flags.isStrictFP()) {
533             modifier = modifier | soot.Modifier.STRICTFP;
534         }
535         return modifier;
536     }
537 }
538
Popular Tags