KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > soot > PackManager


1 /* Soot - a J*va Optimization Framework
2  * Copyright (C) 2003, 2004 Ondrej 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;
21 import java.util.*;
22 import java.io.*;
23 import java.util.zip.*;
24 import soot.util.*;
25 import soot.util.queue.*;
26 import soot.jimple.*;
27 import soot.shimple.*;
28 import soot.grimp.*;
29 import soot.baf.*;
30 import soot.jimple.toolkits.invoke.*;
31 import soot.jimple.toolkits.base.*;
32 import soot.shimple.toolkits.scalar.*;
33 import soot.grimp.toolkits.base.*;
34 import soot.baf.toolkits.base.*;
35 import soot.jimple.toolkits.typing.*;
36 import soot.jimple.toolkits.scalar.*;
37 import soot.jimple.toolkits.scalar.pre.*;
38 import soot.jimple.toolkits.annotation.arraycheck.*;
39 import soot.jimple.toolkits.annotation.profiling.*;
40 import soot.jimple.toolkits.annotation.callgraph.*;
41 import soot.jimple.toolkits.annotation.parity.*;
42 import soot.jimple.toolkits.annotation.methods.*;
43 import soot.jimple.toolkits.annotation.fields.*;
44 import soot.jimple.toolkits.annotation.qualifiers.*;
45 import soot.jimple.toolkits.annotation.nullcheck.*;
46 import soot.jimple.toolkits.annotation.tags.*;
47 import soot.jimple.toolkits.annotation.defs.*;
48 import soot.jimple.toolkits.annotation.liveness.*;
49 import soot.jimple.toolkits.annotation.logic.*;
50 import soot.jimple.toolkits.annotation.purity.*; // [AM]
51
//import soot.javaToJimple.toolkits.*;
52
import soot.jimple.toolkits.annotation.*;
53 import soot.jimple.toolkits.pointer.*;
54 import soot.jimple.toolkits.callgraph.*;
55 import soot.tagkit.*;
56 import soot.options.Options;
57 import soot.toolkits.scalar.*;
58 import soot.jimple.spark.SparkTransformer;
59 import soot.jimple.paddle.PaddleHook;
60 import soot.jimple.toolkits.callgraph.CHATransformer;
61 import soot.jimple.spark.fieldrw.*;
62 import soot.dava.*;
63 import soot.dava.toolkits.base.AST.interProcedural.InterProceduralAnalyses;
64 import soot.dava.toolkits.base.misc.*;
65 import soot.xml.*;
66 import soot.toolkits.graph.interaction.*;
67
68 /** Manages the Packs containing the various phases and their options. */
69 public class PackManager {
70     public PackManager( Singletons.Global g ) { PhaseOptions.v().setPackManager(this); init(); }
71
72     public boolean onlyStandardPacks() { return onlyStandardPacks; }
73     private boolean onlyStandardPacks = false;
74     void notifyAddPack() {
75         onlyStandardPacks = false;
76     }
77
78     private void init()
79     {
80         Pack p;
81
82         // Jimple body creation
83
addPack(p = new JimpleBodyPack());
84         {
85             p.add(new Transform("jb.tt", soot.toolkits.exceptions.TrapTightener.v()));
86             p.add(new Transform("jb.ls", LocalSplitter.v()));
87             p.add(new Transform("jb.a", Aggregator.v()));
88             p.add(new Transform("jb.ule", UnusedLocalEliminator.v()));
89             p.add(new Transform("jb.tr", TypeAssigner.v()));
90             p.add(new Transform("jb.ulp", LocalPacker.v()));
91             p.add(new Transform("jb.lns", LocalNameStandardizer.v()));
92             p.add(new Transform("jb.cp", CopyPropagator.v()));
93             p.add(new Transform("jb.dae", DeadAssignmentEliminator.v()));
94             p.add(new Transform("jb.cp-ule", UnusedLocalEliminator.v()));
95             p.add(new Transform("jb.lp", LocalPacker.v()));
96             p.add(new Transform("jb.ne", NopEliminator.v()));
97             p.add(new Transform("jb.uce", UnreachableCodeEliminator.v()));
98         }
99
100         // Java to Jimple - Jimple body creation
101
addPack(p = new JavaToJimpleBodyPack());
102         {
103             p.add(new Transform("jj.ls", LocalSplitter.v()));
104             p.add(new Transform("jj.a", Aggregator.v()));
105             p.add(new Transform("jj.ule", UnusedLocalEliminator.v()));
106             p.add(new Transform("jj.ne", NopEliminator.v()));
107             p.add(new Transform("jj.tr", TypeAssigner.v()));
108             //p.add(new Transform("jj.ct", CondTransformer.v()));
109
p.add(new Transform("jj.ulp", LocalPacker.v()));
110             p.add(new Transform("jj.lns", LocalNameStandardizer.v()));
111             p.add(new Transform("jj.cp", CopyPropagator.v()));
112             p.add(new Transform("jj.dae", DeadAssignmentEliminator.v()));
113             p.add(new Transform("jj.cp-ule", UnusedLocalEliminator.v()));
114             p.add(new Transform("jj.lp", LocalPacker.v()));
115             p.add(new Transform("jj.uce", UnreachableCodeEliminator.v()));
116         
117         }
118         
119         // Call graph pack
120
addPack(p = new CallGraphPack("cg"));
121         {
122             p.add(new Transform("cg.cha", CHATransformer.v()));
123             p.add(new Transform("cg.spark", SparkTransformer.v()));
124             p.add(new Transform("cg.paddle", PaddleHook.v()));
125         }
126
127         // Whole-Shimple transformation pack
128
addPack(p = new ScenePack("wstp"));
129
130         // Whole-Shimple Optimization pack
131
addPack(p = new ScenePack("wsop"));
132
133         // Whole-Jimple transformation pack
134
addPack(p = new ScenePack("wjtp"));
135         {
136         }
137
138         // Whole-Jimple Optimization pack
139
addPack(p = new ScenePack("wjop"));
140         {
141             p.add(new Transform("wjop.smb", StaticMethodBinder.v()));
142             p.add(new Transform("wjop.si", StaticInliner.v()));
143         }
144
145         // Give another chance to do Whole-Jimple transformation
146
// The RectangularArrayFinder will be put into this package.
147
addPack(p = new ScenePack("wjap"));
148         {
149             p.add(new Transform("wjap.ra", RectangularArrayFinder.v()));
150             p.add(new Transform("wjap.umt", UnreachableMethodsTagger.v()));
151             p.add(new Transform("wjap.uft", UnreachableFieldsTagger.v()));
152             p.add(new Transform("wjap.tqt", TightestQualifiersTagger.v()));
153             p.add(new Transform("wjap.cgg", CallGraphGrapher.v()));
154             p.add(new Transform("wjap.purity", PurityAnalysis.v())); // [AM]
155
}
156
157         // Shimple pack
158
addPack(p = new BodyPack(Shimple.PHASE));
159         
160         // Shimple transformation pack
161
addPack(p = new BodyPack("stp"));
162             
163         // Shimple optimization pack
164
addPack(p = new BodyPack("sop"));
165         {
166             p.add(new Transform("sop.cpf", SConstantPropagatorAndFolder.v()));
167         }
168
169         // Jimple transformation pack
170
addPack(p = new BodyPack("jtp"));
171         
172         // Jimple optimization pack
173
addPack(p = new BodyPack("jop"));
174         {
175             p.add(new Transform("jop.cse", CommonSubexpressionEliminator.v()));
176             p.add(new Transform("jop.bcm", BusyCodeMotion.v()));
177             p.add(new Transform("jop.lcm", LazyCodeMotion.v()));
178             p.add(new Transform("jop.cp", CopyPropagator.v()));
179             p.add(new Transform("jop.cpf", ConstantPropagatorAndFolder.v()));
180             p.add(new Transform("jop.cbf", ConditionalBranchFolder.v()));
181             p.add(new Transform("jop.dae", DeadAssignmentEliminator.v()));
182             p.add(new Transform("jop.uce1", UnreachableCodeEliminator.v()));
183             p.add(new Transform("jop.ubf1", UnconditionalBranchFolder.v()));
184             p.add(new Transform("jop.uce2", UnreachableCodeEliminator.v()));
185             p.add(new Transform("jop.ubf2", UnconditionalBranchFolder.v()));
186             p.add(new Transform("jop.ule", UnusedLocalEliminator.v()));
187         }
188
189         // Jimple annotation pack
190
addPack(p = new BodyPack("jap"));
191         {
192             p.add(new Transform("jap.npc", NullPointerChecker.v()));
193             p.add(new Transform("jap.npcolorer", NullPointerColorer.v()));
194             p.add(new Transform("jap.abc", ArrayBoundsChecker.v()));
195             p.add(new Transform("jap.profiling", ProfilingGenerator.v()));
196             p.add(new Transform("jap.sea", SideEffectTagger.v()));
197             p.add(new Transform("jap.fieldrw", FieldTagger.v()));
198             p.add(new Transform("jap.cgtagger", CallGraphTagger.v()));
199             p.add(new Transform("jap.parity", ParityTagger.v()));
200             p.add(new Transform("jap.pat", ParameterAliasTagger.v()));
201             p.add(new Transform("jap.rdtagger", ReachingDefsTagger.v()));
202             p.add(new Transform("jap.lvtagger", LiveVarsTagger.v()));
203             p.add(new Transform("jap.che", CastCheckEliminatorDumper.v()));
204             p.add(new Transform("jap.umt", new UnreachableMethodTransformer()));
205             p.add(new Transform("jap.lit", LoopInvariantFinder.v()));
206             p.add(new Transform("jap.aet", AvailExprTagger.v()));
207             p.add(new Transform("jap.dmt", DominatorsTagger.v()));
208            
209         }
210
211         // CFG Viewer
212
/*addPack(p = new BodyPack("cfg"));
213         {
214             p.add(new Transform("cfg.output", CFGPrinter.v()));
215         }*/

216         
217         // Grimp body creation
218
addPack(p = new BodyPack("gb"));
219         {
220             p.add(new Transform("gb.a1", Aggregator.v()));
221             p.add(new Transform("gb.cf", ConstructorFolder.v()));
222             p.add(new Transform("gb.a2", Aggregator.v()));
223             p.add(new Transform("gb.ule", UnusedLocalEliminator.v()));
224         }
225
226         // Grimp optimization pack
227
addPack(p = new BodyPack("gop"));
228
229         // Baf body creation
230
addPack(p = new BodyPack("bb"));
231         {
232             p.add(new Transform("bb.lso", LoadStoreOptimizer.v()));
233             p.add(new Transform("bb.pho", PeepholeOptimizer.v()));
234             p.add(new Transform("bb.ule", UnusedLocalEliminator.v()));
235             p.add(new Transform("bb.lp", LocalPacker.v()));
236         }
237
238         // Baf optimization pack
239
addPack(p = new BodyPack("bop"));
240
241         // Code attribute tag aggregation pack
242
addPack(p = new BodyPack("tag"));
243         {
244             p.add(new Transform("tag.ln", LineNumberTagAggregator.v()));
245             p.add(new Transform("tag.an", ArrayNullTagAggregator.v()));
246             p.add(new Transform("tag.dep", DependenceTagAggregator.v()));
247             p.add(new Transform("tag.fieldrw", FieldTagAggregator.v()));
248         }
249
250         // Dummy Dava Phase
251
/*
252          * Nomair A. Naeem 13th Feb 2006
253          * Added so that Dava Options can be added as phase options rather
254          * than main soot options since they only make sense when decompiling
255          * The db phase options are added in soot_options.xml
256          */

257         addPack(p = new BodyPack("db"));
258         {
259             p.add(new Transform("db.transformations", null));
260             p.add(new Transform("db.renamer", null));
261             p.add(new Transform("db.deobfuscate", null));
262             p.add(new Transform("db.force-recompile", null));
263         }
264
265        
266         
267         onlyStandardPacks = true;
268     }
269
270     public static PackManager v() {
271         return G.v().soot_PackManager();
272     }
273
274     private Map packNameToPack = new HashMap();
275     private List packList = new LinkedList();
276
277     private void addPack( Pack p ) {
278         if( packNameToPack.containsKey( p.getPhaseName() ) )
279             throw new RuntimeException JavaDoc( "Duplicate pack "+p.getPhaseName() );
280         packNameToPack.put( p.getPhaseName(), p );
281         packList.add( p );
282     }
283
284     public boolean hasPack(String JavaDoc phaseName) {
285         return getPhase( phaseName ) != null;
286     }
287
288     public Pack getPack(String JavaDoc phaseName) {
289         Pack p = (Pack) packNameToPack.get(phaseName);
290         return p;
291     }
292
293     public boolean hasPhase(String JavaDoc phaseName) {
294         return getPhase(phaseName) != null;
295     }
296
297     public HasPhaseOptions getPhase(String JavaDoc phaseName) {
298         int index = phaseName.indexOf( "." );
299         if( index < 0 ) return getPack( phaseName );
300         String JavaDoc packName = phaseName.substring(0,index);
301         if( !hasPack( packName ) ) return null;
302         return getPack( packName ).get( phaseName );
303     }
304
305     public Transform getTransform(String JavaDoc phaseName) {
306         return (Transform) getPhase( phaseName );
307     }
308
309
310     public Collection allPacks() {
311         return Collections.unmodifiableList( packList );
312     }
313
314     public void runPacks() {
315         if (Options.v().src_prec() == Options.src_prec_class && Options.v().keep_line_number()){
316             LineNumberAdder lineNumAdder = LineNumberAdder.v();
317             lineNumAdder.internalTransform("", null);
318         }
319         
320         if (Options.v().whole_program() || Options.v().whole_shimple()) {
321             runWholeProgramPacks();
322         }
323         retrieveAllBodies();
324         preProcessDAVA();
325         if (Options.v().interactive_mode()){
326             if (InteractionHandler.v().getInteractionListener() == null){
327                 G.v().out.println("Cannot run in interactive mode. No listeners available. Continuing in regular mode.");
328                 Options.v().set_interactive_mode(false);
329             }
330             else {
331                 G.v().out.println("Running in interactive mode.");
332             }
333         }
334         
335         runBodyPacks();
336         handleInnerClasses();
337     }
338
339     public void runBodyPacks() {
340         runBodyPacks( reachableClasses() );
341     }
342
343     private ZipOutputStream jarFile = null;
344     public void writeOutput() {
345         if( Options.v().output_jar() ) {
346             String JavaDoc outFileName = SourceLocator.v().getOutputDir();
347             try {
348                 jarFile = new ZipOutputStream(new FileOutputStream(outFileName));
349             } catch( FileNotFoundException e ) {
350                 throw new CompilationDeathException("Cannot open output Jar file " + outFileName);
351             }
352         } else {
353             jarFile = null;
354         }
355         if(Options.v().verbose())
356             PhaseDumper.v().dumpBefore("output");
357             if( Options.v().output_format() == Options.output_format_dava ) {
358                 postProcessDAVA();
359             } else {
360                 writeOutput( reachableClasses() );
361             }
362             postProcessXML( reachableClasses() );
363             releaseBodies( reachableClasses() );
364         if(Options.v().verbose())
365             PhaseDumper.v().dumpAfter("output");
366     }
367
368     private void runWholeProgramPacks() {
369         if (Options.v().whole_shimple()) {
370             ShimpleTransformer.v().transform();
371             getPack("cg").apply();
372             getPack("wstp").apply();
373             getPack("wsop").apply();
374         } else {
375             getPack("cg").apply();
376             getPack("wjtp").apply();
377             getPack("wjop").apply();
378             getPack("wjap").apply();
379         }
380         PaddleHook.v().finishPhases();
381     }
382
383     /* preprocess classes for DAVA */
384     private void preProcessDAVA() {
385         if (Options.v().output_format() == Options.output_format_dava) {
386             ThrowFinder.v().find();
387             PackageNamer.v().fixNames();
388
389             G.v().out.println();
390         }
391     }
392
393     private void runBodyPacks( Iterator classes ) {
394         while( classes.hasNext() ) {
395             SootClass cl = (SootClass) classes.next();
396             runBodyPacks( cl );
397         }
398     }
399
400     private void handleInnerClasses(){
401        InnerClassTagAggregator agg = InnerClassTagAggregator.v();
402        agg.internalTransform("", null);
403     }
404
405     private void writeOutput( Iterator classes ) {
406         while( classes.hasNext() ) {
407             SootClass cl = (SootClass) classes.next();
408             writeClass( cl );
409         }
410         try {
411             if(jarFile != null) jarFile.close();
412         } catch( IOException e ) {
413             throw new CompilationDeathException( "Error closing output jar: "+e );
414         }
415     }
416
417     private void releaseBodies( Iterator classes ) {
418         while( classes.hasNext() ) {
419             SootClass cl = (SootClass) classes.next();
420             releaseBodies( cl );
421         }
422     }
423
424     private Iterator reachableClasses() {
425         if( false && (Options.v().whole_program() ||
426                       Options.v().whole_shimple())) {
427             QueueReader methods = Scene.v().getReachableMethods().listener();
428             HashSet reachableClasses = new HashSet();
429             
430             while(true) {
431                     SootMethod m = (SootMethod) methods.next();
432                     if(m == null) break;
433                     SootClass c = m.getDeclaringClass();
434                     if( !c.isApplicationClass() ) continue;
435                     reachableClasses.add( c );
436             }
437             return reachableClasses.iterator();
438         } else {
439             return Scene.v().getApplicationClasses().iterator();
440         }
441     }
442
443     /* post process for DAVA */
444     private void postProcessDAVA() {
445         G.v().out.println();
446
447         Chain appClasses = Scene.v().getApplicationClasses();
448
449         Map options = PhaseOptions.v().getPhaseOptions("db.transformations");
450         boolean transformations = PhaseOptions.getBoolean(options, "enabled");
451         /*
452          * apply analyses etc
453          */

454         Iterator classIt = appClasses.iterator();
455         while (classIt.hasNext()) {
456             SootClass s = (SootClass) classIt.next();
457             String JavaDoc fileName = SourceLocator.v().getFileNameFor(s, Options.v().output_format());
458             
459             /*
460              * Nomair A. Naeem 5-Jun-2005
461              * Added to remove the *final* bug in Dava (often seen in AspectJ programs)
462              */

463             DavaStaticBlockCleaner.v().staticBlockInlining(s);
464
465         
466             /*
467              * Nomair A. Naeem 1st March 2006
468              * Check if we want to apply transformations
469              * one reason we might not want to do this is when gathering old metrics data!!
470              */

471             if(transformations){
472                 //debug("analyzeAST","Advanced Analyses ALL DISABLED");
473

474                 G.v().out.println("Analyzing " + fileName + "... ");
475                     
476                 /*
477                  * Nomair A. Naeem 29th Jan 2006
478                  * Added hook into going through each decompiled method again
479                  * Need it for all the implemented AST analyses
480                  */

481                 Iterator methodIt = s.methodIterator();
482                 while (methodIt.hasNext()) {
483                     
484                     SootMethod m = (SootMethod) methodIt.next();
485                     //System.out.println("SootMethod:"+m.getName().toString());
486
DavaBody body = (DavaBody)m.getActiveBody();
487                     //System.out.println("body"+body.toString());
488
body.analyzeAST();
489                 }
490             } //if tansformations are enabled
491
} //going through all classes
492

493
494         
495         
496         /*
497          * Nomair A. Naeem March 6th, 2006
498          * Laying the seed for interprocedural analyses
499          *
500          * SHOULD BE INVOKED ONLY ONCE!!!
501          */

502         if(transformations){
503             InterProceduralAnalyses.applyInterProceduralAnalyses();
504         }
505                     
506         
507           
508             
509             
510         
511          /*
512           * Generate decompiled code
513           */

514         String JavaDoc pathForBuild=null;
515         ArrayList decompiledClasses = new ArrayList();
516         classIt = appClasses.iterator();
517         while (classIt.hasNext()) {
518             SootClass s = (SootClass) classIt.next();
519             
520             OutputStream streamOut = null;
521             PrintWriter writerOut = null;
522             String JavaDoc fileName = SourceLocator.v().getFileNameFor(s, Options.v().output_format());
523             decompiledClasses.add(fileName.substring(fileName.lastIndexOf('/')+1));
524             if(pathForBuild == null){
525                 pathForBuild =fileName.substring(0,fileName.lastIndexOf('/')+1);
526                 //System.out.println(pathForBuild);
527
}
528             if( Options.v().gzip() )
529                 fileName = fileName+".gz";
530
531             try {
532                 if( jarFile != null ) {
533                     ZipEntry entry = new ZipEntry(soot.util.StringTools.replaceAll(fileName,"\\","/"));
534                     jarFile.putNextEntry(entry);
535                     streamOut = jarFile;
536                 } else {
537                     streamOut = new FileOutputStream(fileName);
538                 }
539                 if( Options.v().gzip() )
540                     streamOut = new GZIPOutputStream(streamOut);
541                 writerOut =
542                     new PrintWriter(new OutputStreamWriter(streamOut));
543             } catch (IOException e) {
544                 throw new CompilationDeathException("Cannot output file " + fileName);
545             }
546
547             
548
549             G.v().out.print("Generating " + fileName + "... ");
550  
551             G.v().out.flush();
552
553             DavaPrinter.v().printTo(s, writerOut);
554
555             G.v().out.println();
556             G.v().out.flush();
557
558             {
559                 try {
560                     writerOut.flush();
561                     if(jarFile == null) streamOut.close();
562                 } catch (IOException e) {
563                     throw new CompilationDeathException("Cannot close output file " + fileName);
564                 }
565             }
566         } //going through all classes
567
G.v().out.println();
568
569         
570         /*
571          * Create the build.xml for Dava
572          */

573         {
574             //path for build is probably ending in sootoutput/dava/src
575
//definetly remove the src
576
if(pathForBuild.endsWith("src/"))
577                 pathForBuild=pathForBuild.substring(0,pathForBuild.length()-4);
578             
579             String JavaDoc fileName = pathForBuild +"build.xml";
580         
581             try{
582                 OutputStream streamOut = new FileOutputStream(fileName);
583                 PrintWriter writerOut = new PrintWriter(new OutputStreamWriter(streamOut));
584                 DavaBuildFile.generate(writerOut,decompiledClasses);
585                 writerOut.flush();
586                 streamOut.close();
587             } catch (IOException e) {
588                 throw new CompilationDeathException("Cannot output file " + fileName);
589             }
590         }
591
592         
593         
594     }
595
596     private void runBodyPacks(SootClass c) {
597         final int format = Options.v().output_format();
598         if (format == Options.output_format_dava) {
599             G.v().out.print("Decompiling ");
600
601          //January 13th, 2006 SootMethodAddedByDava is set to false for SuperFirstStmtHandler
602
G.v().SootMethodAddedByDava=false;
603         } else {
604             G.v().out.print("Transforming ");
605         }
606         G.v().out.println(c.getName() + "... ");
607
608         boolean produceBaf = false, produceGrimp = false, produceDava = false,
609             produceJimple = true, produceShimple = false;
610
611         switch (format) {
612             case Options.output_format_none :
613             case Options.output_format_xml :
614             case Options.output_format_jimple :
615             case Options.output_format_jimp :
616                 break;
617             case Options.output_format_shimp:
618             case Options.output_format_shimple:
619                 produceShimple = true;
620                 // FLIP produceJimple
621
produceJimple = false;
622                 break;
623             case Options.output_format_dava :
624                 produceDava = true;
625                 // FALL THROUGH
626
case Options.output_format_grimp :
627             case Options.output_format_grimple :
628                 produceGrimp = true;
629                 break;
630             case Options.output_format_baf :
631             case Options.output_format_b :
632                 produceBaf = true;
633                 break;
634             case Options.output_format_jasmin :
635             case Options.output_format_class :
636                 produceGrimp = Options.v().via_grimp();
637                 produceBaf = !produceGrimp;
638                 break;
639             default :
640                 throw new RuntimeException JavaDoc();
641         }
642
643         soot.xml.TagCollector tc = new soot.xml.TagCollector();
644         
645         boolean wholeShimple = Options.v().whole_shimple();
646         if( Options.v().via_shimple() ) produceShimple = true;
647
648         Iterator methodIt = c.methodIterator();
649         while (methodIt.hasNext()) {
650             SootMethod m = (SootMethod) methodIt.next();
651
652             if (!m.isConcrete()) continue;
653
654             if (produceShimple || wholeShimple) {
655                 ShimpleBody sBody = null;
656
657                 // whole shimple or not?
658
{
659                     Body body = m.retrieveActiveBody();
660
661                     if(body instanceof ShimpleBody){
662                         sBody = (ShimpleBody) body;
663                         if(!sBody.isSSA())
664                             sBody.rebuild();
665                     }
666                     else{
667                         sBody = Shimple.v().newBody(body);
668                     }
669                 }
670                 
671                 m.setActiveBody(sBody);
672                 PackManager.v().getPack("stp").apply(sBody);
673                 PackManager.v().getPack("sop").apply(sBody);
674
675                 if( produceJimple || (wholeShimple && !produceShimple) )
676                     m.setActiveBody(sBody.toJimpleBody());
677             }
678
679             if (produceJimple) {
680                 JimpleBody body =(JimpleBody) m.retrieveActiveBody();
681                 PackManager.v().getPack("jtp").apply(body);
682                 if( Options.v().validate() ) {
683                     body.validate();
684                 }
685                 PackManager.v().getPack("jop").apply(body);
686                 PackManager.v().getPack("jap").apply(body);
687                 if (Options.v().xml_attributes() && Options.v().output_format() != Options.output_format_jimple) {
688                     //System.out.println("collecting body tags");
689
tc.collectBodyTags(body);
690                 }
691             }
692             
693             //PackManager.v().getPack("cfg").apply(m.retrieveActiveBody());
694

695             if (produceGrimp) {
696                 m.setActiveBody(Grimp.v().newBody(m.getActiveBody(), "gb"));
697                 PackManager.v().getPack("gop").apply(m.getActiveBody());
698             } else if (produceBaf) {
699                 m.setActiveBody(Baf.v().newBody
700                                 ((JimpleBody) m.getActiveBody()));
701                 PackManager.v().getPack("bop").apply(m.getActiveBody());
702                 PackManager.v().getPack("tag").apply(m.getActiveBody());
703             }
704         }
705             
706         if (Options.v().xml_attributes() && Options.v().output_format() != Options.output_format_jimple) {
707             processXMLForClass(c, tc);
708             //System.out.println("processed xml for class");
709
}
710
711         if (produceDava) {
712             methodIt = c.methodIterator();
713             while (methodIt.hasNext()) {
714                 SootMethod m = (SootMethod) methodIt.next();
715                 if (!m.isConcrete())
716                     continue;
717                 //all the work done in decompilation is done in DavaBody which is invoked from within newBody
718
m.setActiveBody(Dava.v().newBody(m.getActiveBody()));
719             }
720
721             /*
722              * January 13th, 2006
723              * SuperFirstStmtHandler might have set SootMethodAddedByDava if it needs to create a new
724              * method.
725              */

726             //could use G to add new method...................
727
if(G.v().SootMethodAddedByDava){
728                 //System.out.println("PACKMANAGER SAYS:----------------Have to add the new method(s)");
729
ArrayList sootMethodsAdded = G.v().SootMethodsAdded;
730                 Iterator it = sootMethodsAdded.iterator();
731                 while(it.hasNext()){
732                     c.addMethod((SootMethod)it.next());
733                 }
734                 G.v().SootMethodsAdded = new ArrayList();
735                 G.v().SootMethodAddedByDava=false;
736             }
737
738         }//end if produceDava
739
}
740
741     private void writeClass(SootClass c) {
742         final int format = Options.v().output_format();
743         if( format == Options.output_format_none ) return;
744         if( format == Options.output_format_dava ) return;
745
746         OutputStream streamOut = null;
747         PrintWriter writerOut = null;
748         boolean noOutputFile = false;
749
750         String JavaDoc fileName = SourceLocator.v().getFileNameFor(c, format);
751         if( Options.v().gzip() ) fileName = fileName+".gz";
752
753         try {
754             if( jarFile != null ) {
755                 ZipEntry entry = new ZipEntry(fileName);
756                 jarFile.putNextEntry(entry);
757                 streamOut = jarFile;
758             } else {
759                 new File(fileName).getParentFile().mkdirs();
760                 streamOut = new FileOutputStream(fileName);
761             }
762             if( Options.v().gzip() ) {
763                 streamOut = new GZIPOutputStream(streamOut);
764             }
765             if(format == Options.output_format_class) {
766                 streamOut = new JasminOutputStream(streamOut);
767             }
768             writerOut = new PrintWriter(new OutputStreamWriter(streamOut));
769             G.v().out.println( "Writing to "+fileName );
770         } catch (IOException e) {
771             throw new CompilationDeathException("Cannot output file " + fileName);
772         }
773
774         if (Options.v().xml_attributes()) {
775             Printer.v().setOption(Printer.ADD_JIMPLE_LN);
776         }
777         switch (format) {
778             case Options.output_format_class :
779             case Options.output_format_jasmin :
780                 if (c.containsBafBody())
781                     new soot.baf.JasminClass(c).print(writerOut);
782                 else
783                     new soot.jimple.JasminClass(c).print(writerOut);
784                 break;
785             case Options.output_format_jimp :
786             case Options.output_format_shimp :
787             case Options.output_format_b :
788             case Options.output_format_grimp :
789                 Printer.v().setOption(Printer.USE_ABBREVIATIONS);
790                 Printer.v().printTo(c, writerOut);
791                 break;
792             case Options.output_format_baf :
793             case Options.output_format_jimple :
794             case Options.output_format_shimple :
795             case Options.output_format_grimple :
796                 writerOut =
797                     new PrintWriter(
798                         new EscapedWriter(new OutputStreamWriter(streamOut)));
799                 Printer.v().printTo(c, writerOut);
800                 break;
801             case Options.output_format_xml :
802                 writerOut =
803                     new PrintWriter(
804                         new EscapedWriter(new OutputStreamWriter(streamOut)));
805                 XMLPrinter.v().printJimpleStyleTo(c, writerOut);
806                 break;
807             default :
808                 throw new RuntimeException JavaDoc();
809         }
810
811         try {
812             writerOut.flush();
813             streamOut.close();
814         } catch (IOException e) {
815             throw new CompilationDeathException("Cannot close output file " + fileName);
816         }
817     }
818
819     private void postProcessXML( Iterator classes ) {
820         if (!Options.v().xml_attributes()) return;
821         if (Options.v().output_format() != Options.output_format_jimple) return;
822         while( classes.hasNext() ) {
823             SootClass c = (SootClass) classes.next();
824             processXMLForClass(c);
825         }
826     }
827
828     private void processXMLForClass(SootClass c, TagCollector tc){
829         final int format = Options.v().output_format();
830         String JavaDoc fileName = SourceLocator.v().getFileNameFor(c, format);
831         XMLAttributesPrinter xap = new XMLAttributesPrinter(fileName,
832                SourceLocator.v().getOutputDir());
833         xap.printAttrs(c, tc);
834     }
835     
836     private void processXMLForClass(SootClass c){
837         final int format = Options.v().output_format();
838         String JavaDoc fileName = SourceLocator.v().getFileNameFor(c, format);
839         XMLAttributesPrinter xap = new XMLAttributesPrinter(fileName,
840                SourceLocator.v().getOutputDir());
841         xap.printAttrs(c);
842     }
843
844     private void releaseBodies( SootClass cl ) {
845         Iterator methodIt = cl.methodIterator();
846         while (methodIt.hasNext()) {
847             SootMethod m = (SootMethod) methodIt.next();
848
849             if (m.hasActiveBody())
850                 m.releaseActiveBody();
851         }
852     }
853
854     private void retrieveAllBodies() {
855         Iterator clIt = reachableClasses();
856         while( clIt.hasNext() ) {
857             SootClass cl = (SootClass) clIt.next();
858             Iterator methodIt = cl.methodIterator();
859             while (methodIt.hasNext()) {
860                 SootMethod m = (SootMethod) methodIt.next();
861
862                 if( m.isConcrete() ) {
863                     m.retrieveActiveBody();
864                 }
865             }
866         }
867     }
868 }
869
Popular Tags