KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > soot > dava > DavaPrinter


1 /* Soot - a J*va Optimization Framework
2  * Copyright (C) 2003 Jerome Miecznikowski
3  * Copyright (C) 2004-2005 Nomair A. Naeem
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 package soot.dava;
22
23 import java.io.PrintWriter JavaDoc;
24 import java.util.Iterator JavaDoc;
25 import java.util.Map JavaDoc;
26
27 import soot.Body;
28 import soot.BooleanType;
29 import soot.ByteType;
30 import soot.CharType;
31 import soot.DoubleType;
32 import soot.FloatType;
33 import soot.G;
34 import soot.IntType;
35 import soot.LongType;
36 import soot.Modifier;
37 import soot.PhaseOptions;
38 import soot.RefType;
39 import soot.Scene;
40 import soot.ShortType;
41 import soot.Singletons;
42 import soot.SootClass;
43 import soot.SootField;
44 import soot.SootMethod;
45 import soot.Type;
46 import soot.UnitPrinter;
47 import soot.dava.internal.AST.ASTNode;
48 import soot.options.Options;
49 import soot.tagkit.DoubleConstantValueTag;
50 import soot.tagkit.FloatConstantValueTag;
51 import soot.tagkit.IntegerConstantValueTag;
52 import soot.tagkit.LongConstantValueTag;
53 import soot.tagkit.StringConstantValueTag;
54 import soot.tagkit.Tag;
55 import soot.util.Chain;
56 import soot.util.IterableSet;
57
58 public class DavaPrinter {
59     public DavaPrinter(Singletons.Global g) {
60     }
61     public static DavaPrinter v() {
62         return G.v().soot_dava_DavaPrinter();
63     }
64
65     /** Prints the given <code>JimpleBody</code> to the specified <code>PrintWriter</code>.
66     
67         Nomair A Naeem 10-MARCH-2005
68     Method has become obsolete. Locals are now printed from within the ASTMethodNode.
69     This allows for any analyses to be carried out on these locals during the
70     many transformations on the AST
71     **/

72     /*
73       private void printLocalsInBody(Body body, java.io.PrintWriter out) {
74       if ((body instanceof DavaBody) == false)
75       throw new RuntimeException("Only DavaBodies should use the DavaLocalPrinter");
76       
77       DavaBody davaBody = (DavaBody) body;
78       
79       // Print out local variables
80       {
81       Map typeToLocals =
82       new DeterministicHashMap(body.getLocalCount() * 2 + 1, 0.7f);
83       
84       HashSet params = new HashSet();
85       params.addAll(davaBody.get_ParamMap().values());
86       params.addAll(davaBody.get_CaughtRefs());
87       HashSet thisLocals = davaBody.get_ThisLocals();
88       
89       // Collect locals
90       {
91       Iterator localIt = body.getLocals().iterator();
92       
93       while (localIt.hasNext()) {
94       Local local = (Local) localIt.next();
95       
96       if (params.contains(local) || thisLocals.contains(local))
97       continue;
98       
99       List localList;
100       
101       String typeName;
102       Type t = local.getType();
103       
104       typeName = t.toString();
105       
106       if (typeToLocals.containsKey(typeName))
107       localList = (List) typeToLocals.get(typeName);
108       else {
109       localList = new ArrayList();
110       typeToLocals.put(typeName, localList);
111       }
112       
113       localList.add(local);
114       }
115       }
116       
117       InstanceInvokeExpr constructorExpr = davaBody.get_ConstructorExpr();
118       if (constructorExpr != null) {
119       
120       if (davaBody.getMethod().getDeclaringClass().getName().equals(
121       constructorExpr.getMethodRef().declaringClass().toString()))
122       out.print(" this(");
123       else
124       out.print(" super(");
125       
126       Iterator ait = constructorExpr.getArgs().iterator();
127       while (ait.hasNext()) {
128       out.print(ait.next().toString());
129       
130       if (ait.hasNext())
131       out.print(", ");
132       }
133       
134       out.print(");\n\n");
135       }
136       
137       // Print locals
138       {
139       Iterator typeIt = typeToLocals.keySet().iterator();
140       
141       while (typeIt.hasNext()) {
142       String type = (String) typeIt.next();
143       
144       List localList = (List) typeToLocals.get(type);
145       Object[] locals = localList.toArray();
146       out.print(" ");
147       if (type.equals("null_type"))
148       out.print("Object");
149       else
150       out.print(type);
151       out.print(" ");
152       
153       for (int k = 0; k < locals.length; k++) {
154       if (k != 0)
155       out.print(", ");
156       
157       out.print(((Local) locals[k]).getName());
158       }
159       
160       out.println(";");
161       }
162       }
163       
164       if (!typeToLocals.isEmpty())
165       out.println();
166       }
167       }
168     */

169     private void printStatementsInBody(Body body, java.io.PrintWriter JavaDoc out) {
170         Chain units = ((DavaBody) body).getUnits();
171
172         if (units.size() != 1) {
173             throw new RuntimeException JavaDoc("DavaBody AST doesn't have single root.");
174         }
175
176         UnitPrinter up = new DavaUnitPrinter();
177         ((ASTNode) units.getFirst()).toString(up);
178         out.print( up.toString() );
179     }
180
181     public void printTo(SootClass cl, PrintWriter JavaDoc out) {
182         
183         
184         IterableSet packagesUsed = new IterableSet();
185         
186         {
187
188             String JavaDoc curPackage = cl.getJavaPackageName();
189
190             if (curPackage.equals("") == false) {
191                 out.println("package " + curPackage + ";");
192                 out.println();
193             }
194
195             if (cl.hasSuperclass()) {
196                 SootClass superClass = cl.getSuperclass();
197                 packagesUsed.add(superClass.getJavaPackageName());
198             }
199
200             Iterator JavaDoc interfaceIt = cl.getInterfaces().iterator();
201             while (interfaceIt.hasNext()) {
202                 String JavaDoc interfacePackage =
203                     ((SootClass) interfaceIt.next()).getJavaPackageName();
204                 if (packagesUsed.contains(interfacePackage) == false)
205                     packagesUsed.add(interfacePackage);
206             }
207
208             Iterator JavaDoc methodIt = cl.methodIterator();
209             while (methodIt.hasNext()) {
210                 SootMethod dm = (SootMethod) methodIt.next();
211
212                 if (dm.hasActiveBody())
213                     packagesUsed =
214                         packagesUsed.union(
215                             ((DavaBody) dm.getActiveBody()).get_PackagesUsed());
216
217                 Iterator JavaDoc eit = dm.getExceptions().iterator();
218                 while (eit.hasNext()) {
219                     String JavaDoc thrownPackage =
220                         ((SootClass) eit.next()).getJavaPackageName();
221                     if (packagesUsed.contains(thrownPackage) == false)
222                         packagesUsed.add(thrownPackage);
223                 }
224
225                 Iterator JavaDoc pit = dm.getParameterTypes().iterator();
226                 while (pit.hasNext()) {
227                     Type t = (Type) pit.next();
228
229                     if (t instanceof RefType) {
230                         String JavaDoc paramPackage =
231                             ((RefType) t).getSootClass().getJavaPackageName();
232                         if (packagesUsed.contains(paramPackage) == false)
233                             packagesUsed.add(paramPackage);
234                     }
235                 }
236
237                 Type t = dm.getReturnType();
238                 if (t instanceof RefType) {
239                     String JavaDoc returnPackage =
240                         ((RefType) t).getSootClass().getJavaPackageName();
241                     if (packagesUsed.contains(returnPackage) == false)
242                         packagesUsed.add(returnPackage);
243                 }
244             }
245
246             Iterator JavaDoc fieldIt = cl.getFields().iterator();
247             while (fieldIt.hasNext()) {
248                 SootField f = (SootField) fieldIt.next();
249
250                 if (f.isPhantom())
251                     continue;
252
253                 Type t = f.getType();
254
255                 if (t instanceof RefType) {
256                     String JavaDoc fieldPackage =
257                         ((RefType) t).getSootClass().getJavaPackageName();
258                     if (packagesUsed.contains(fieldPackage) == false)
259                         packagesUsed.add(fieldPackage);
260                 }
261             }
262
263             if (packagesUsed.contains(curPackage))
264                 packagesUsed.remove(curPackage);
265
266             if (packagesUsed.contains("java.lang"))
267                 packagesUsed.remove("java.lang");
268
269             Iterator JavaDoc pit = packagesUsed.iterator();
270             while (pit.hasNext())
271                 out.println("import " + (String JavaDoc) pit.next() + ".*;");
272
273             if (packagesUsed.isEmpty() == false)
274                 out.println();
275
276             packagesUsed.add("java.lang");
277             packagesUsed.add(curPackage);
278
279             Dava.v().set_CurrentPackageContext(packagesUsed);
280             Dava.v().set_CurrentPackage(curPackage);
281         }
282
283         // Print class name + modifiers
284
{
285             String JavaDoc classPrefix = "";
286
287             classPrefix =
288                 classPrefix + " " + Modifier.toString(cl.getModifiers());
289             classPrefix = classPrefix.trim();
290
291             if (!cl.isInterface()) {
292                 classPrefix = classPrefix + " class";
293                 classPrefix = classPrefix.trim();
294             }
295
296             out.print(classPrefix + " " + cl.getShortJavaStyleName());
297         }
298
299         // Print extension
300
if (cl.hasSuperclass()
301             && !(cl.getSuperclass().getName().equals("java.lang.Object"))){
302                 
303             String JavaDoc superClassName = cl.getSuperclass().getName();
304             
305             //Nomair Naeem 8th Feb 2006
306
//also check if the super class name is not a fully qualified
307
//name. in which case if the package is imported no need for
308
//the long name
309

310             Map JavaDoc options = PhaseOptions.v().getPhaseOptions("db.renamer");
311             boolean force = PhaseOptions.getBoolean(options, "remove-fully-qualified");
312             //System.out.println("In DVariableDeclarationStmt Force is"+force);
313

314
315             if (force) {
316                 superClassName = getShortName(superClassName,packagesUsed);
317             }
318             out.print(" extends " + superClassName + "");
319         }
320
321
322         // Print interfaces
323
{
324             Iterator JavaDoc interfaceIt = cl.getInterfaces().iterator();
325
326             if (interfaceIt.hasNext()) {
327                 if( cl.isInterface() ) out.print(" extends ");
328                 else out.print(" implements ");
329
330                 out.print("" + ((SootClass) interfaceIt.next()).getName() + "");
331
332                 while (interfaceIt.hasNext())
333                     out.print(
334                         ", " + ((SootClass) interfaceIt.next()).getName() + "");
335             }
336         }
337
338         out.println();
339         out.println("{");
340
341         // Print fields
342
{
343             Iterator JavaDoc fieldIt = cl.getFields().iterator();
344             if (fieldIt.hasNext()) {
345                 while (fieldIt.hasNext()) {
346                     SootField f = (SootField) fieldIt.next();
347
348                     if (f.isPhantom())
349                         continue;
350
351
352                     String JavaDoc declaration = null;
353                     
354                     Type fieldType = f.getType();
355                     
356                 
357                     String JavaDoc qualifiers = Modifier.toString(f.getModifiers()) + " ";
358                     
359                     
360                     //See if we want to shorten fully qualified names
361
Map JavaDoc options = PhaseOptions.v().getPhaseOptions("db.renamer");
362                     boolean force = PhaseOptions.getBoolean(options, "remove-fully-qualified");
363                     //System.out.println("In DVariableDeclarationStmt Force is"+force);
364

365                     if (force) {
366                         qualifiers += getShortName(fieldType.toString(),packagesUsed);
367                     }
368                     else
369                         qualifiers += fieldType.toString();
370                     
371                     
372                     
373                     qualifiers = qualifiers.trim();
374
375                     if(qualifiers.equals(""))
376                         declaration = Scene.v().quotedNameOf(f.getName());
377                     else
378                         declaration = qualifiers + " " + Scene.v().quotedNameOf(f.getName()) + "";
379
380
381                     if (f.isFinal() && f.isStatic()) {
382                                         
383                         if (fieldType instanceof DoubleType && f.hasTag("DoubleConstantValueTag")) {
384                             
385                             double val = ((DoubleConstantValueTag) f.getTag("DoubleConstantValueTag")).getDoubleValue();
386                             out.println(" " + declaration + " = "+ val + ";");
387                             
388                         } else if (fieldType instanceof FloatType && f.hasTag("FloatConstantValueTag")) {
389                             
390                             float val = ((FloatConstantValueTag) f.getTag("FloatConstantValueTag")).getFloatValue();
391                             out.println(" " + declaration + " = "+ val + "f;");
392                             
393                         } else if (fieldType instanceof LongType && f.hasTag("LongConstantValueTag")) {
394
395                             long val = ((LongConstantValueTag) f.getTag("LongConstantValueTag")).getLongValue();
396                             out.println(" " + declaration + " = "+ val + "l;");
397                             
398                         } else if (fieldType instanceof CharType && f.hasTag("IntegerConstantValueTag")) {
399
400                             int val = ((IntegerConstantValueTag) f.getTag("IntegerConstantValueTag")).getIntValue();
401                             out.println(" " + declaration + " = '" + ((char) val) + "';");
402
403                         } else if (fieldType instanceof BooleanType && f.hasTag("IntegerConstantValueTag")) {
404                             
405                             int val = ((IntegerConstantValueTag) f.getTag("IntegerConstantValueTag")).getIntValue();
406
407                             if (val == 0)
408                                 out.println(" " + declaration+ " = false;");
409                             else
410                                 out.println(" " + declaration+ " = true;");
411                             
412                         } else if ((fieldType instanceof IntType
413                                 || fieldType instanceof ByteType ||
414                                 fieldType instanceof ShortType)
415                                 && f.hasTag("IntegerConstantValueTag")) {
416                             
417                             int val = ((IntegerConstantValueTag) f.getTag("IntegerConstantValueTag")).getIntValue();
418                             out.println(" " + declaration + " = "+ val + ";");
419                             
420                         } else if (f.hasTag("StringConstantValueTag")) {
421
422                             String JavaDoc val = ((StringConstantValueTag) f.getTag("StringConstantValueTag")).getStringValue();
423                             out.println(" " + declaration + " = \""+ val + "\";");
424                             
425                         } else {
426                             // System.out.println("Couldnt find type of
427
// field"+f.getDeclaration());
428
out.println(" " + declaration + ";");
429                         }
430                     } // field is static final
431
else {
432                         out.println(" " + declaration + ";");
433                     }
434                 }
435             }
436         }
437
438         // Print methods
439
{
440             Iterator JavaDoc methodIt = cl.methodIterator();
441
442             if (methodIt.hasNext()) {
443                 if (cl.getMethodCount() != 0)
444                     out.println();
445
446                 while (methodIt.hasNext()) {
447                     SootMethod method = (SootMethod) methodIt.next();
448
449                     if (method.isPhantom())
450                         continue;
451
452                     if (!Modifier.isAbstract(method.getModifiers())
453                         && !Modifier.isNative(method.getModifiers())) {
454                         if (!method.hasActiveBody())
455                             throw new RuntimeException JavaDoc(
456                                 "method "
457                                     + method.getName()
458                                     + " has no active body!");
459                         else
460                             printTo(method.getActiveBody(), out);
461
462                         if (methodIt.hasNext())
463                             out.println();
464                     } else {
465             //if method is abstract then print the declaration
466
out.print(" ");
467                         out.print(method.getDavaDeclaration());
468                         out.println(";");
469
470                         if (methodIt.hasNext())
471                             out.println();
472                     }
473                 }
474             }
475         }
476
477
478
479
480     /*
481      * January 23rd, 2006
482      * In trying to handle the suepr class problem we need to introduce an inner class
483      * Instead of creating a data structure for it we are right now just going to print it in the form
484      * of a string
485      *
486      * It would be interesting to later have an internal inner class structure so that we could
487      * decompile inner classes into inner classes
488      */

489
490     if(G.v().SootClassNeedsDavaSuperHandlerClass.contains(cl)){
491         out.println("\n private static class DavaSuperHandler{");
492         out.println(" java.util.Vector myVector = new java.util.Vector();");
493
494         out.println("\n public Object get(int pos){");
495         out.println(" return myVector.elementAt(pos);");
496         out.println(" }");
497
498         out.println("\n public void store(Object obj){");
499         out.println(" myVector.add(obj);");
500         out.println(" }");
501         out.println(" }");
502     }
503
504
505         out.println("}");
506     }
507
508     
509     
510     
511     
512     
513     
514     public String JavaDoc getShortName(String JavaDoc name, IterableSet packagesUsed) {
515         // get the package name of the object if one exists
516
String JavaDoc packageName = null;
517         if (name.lastIndexOf('.') > 0) {// 0 doesnt make sense
518
packageName = name.substring(0, name.lastIndexOf('.'));
519         }
520
521         if (packageName != null && packagesUsed.contains(packageName)) {
522             // change superclassname to just the object type name
523
name = name.substring(name.lastIndexOf('.') + 1);
524         }
525
526         return name;
527     }
528     
529     /**
530      * Prints out the method corresponding to b Body, (declaration and body),
531      * in the textual format corresponding to the IR used to encode b body.
532      *
533      * @param out a PrintWriter instance to print to.
534      */

535     private void printTo(Body b, PrintWriter JavaDoc out) {
536         b.validate();
537
538         String JavaDoc decl = b.getMethod().getDavaDeclaration();
539
540         {
541             out.println(" " + decl);
542             for( Iterator JavaDoc tIt = b.getMethod().getTags().iterator(); tIt.hasNext(); ) {
543                 final Tag t = (Tag) tIt.next();
544                 if (Options.v().print_tags_in_output()){
545                     out.println(t);
546                 }
547             }
548             out.println(" {");
549
550
551         /*
552           The locals are now printed out from within the toString method of ASTMethodNode
553           Nomair A Naeem 10-MARCH-2005
554         */

555             //printLocalsInBody(b, out);
556
}
557
558         printStatementsInBody(b, out);
559
560         out.println(" }");
561
562     }
563
564 }
565
Popular Tags