KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > soot > Scene


1 /* Soot - a J*va Optimization Framework
2  * Copyright (C) 1997-1999 Raja Vallee-Rai
3  * Copyright (C) 2004 Ondrej Lhotak
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 /*
22  * Modified by the Sable Research Group and others 1997-1999.
23  * See the 'credits' file distributed with Soot for the complete list of
24  * contributors. (Soot is distributed at http://www.sable.mcgill.ca/soot)
25  */

26
27
28 package soot;
29 import soot.*;
30 import soot.options.*;
31
32
33 import soot.util.*;
34 import java.util.*;
35 import java.io.*;
36 import soot.jimple.toolkits.invoke.*;
37 import soot.jimple.toolkits.callgraph.*;
38 import soot.jimple.toolkits.pointer.*;
39 import soot.toolkits.exceptions.ThrowAnalysis;
40 import soot.toolkits.exceptions.PedanticThrowAnalysis;
41 import soot.toolkits.exceptions.UnitThrowAnalysis;
42
43 /** Manages the SootClasses of the application being analyzed. */
44 public class Scene //extends AbstractHost
45
{
46     public Scene ( Singletons.Global g )
47     {
48         setReservedNames();
49         
50         // load soot.class.path system property, if defined
51
String JavaDoc scp = System.getProperty("soot.class.path");
52
53         if (scp != null)
54             setSootClassPath(scp);
55
56         kindNumberer.add( Kind.INVALID );
57         kindNumberer.add( Kind.STATIC );
58         kindNumberer.add( Kind.VIRTUAL );
59         kindNumberer.add( Kind.INTERFACE );
60         kindNumberer.add( Kind.SPECIAL );
61         kindNumberer.add( Kind.CLINIT );
62         kindNumberer.add( Kind.THREAD );
63         kindNumberer.add( Kind.FINALIZE );
64         kindNumberer.add( Kind.INVOKE_FINALIZE );
65         kindNumberer.add( Kind.PRIVILEGED );
66         kindNumberer.add( Kind.NEWINSTANCE );
67
68     addSootBasicClasses();
69     }
70     public static Scene v() { return G.v().soot_Scene (); }
71
72     Chain classes = new HashChain();
73     Chain applicationClasses = new HashChain();
74     Chain libraryClasses = new HashChain();
75     Chain phantomClasses = new HashChain();
76     
77     private Map nameToClass = new HashMap();
78
79     ArrayNumberer kindNumberer = new ArrayNumberer();
80     ArrayNumberer typeNumberer = new ArrayNumberer();
81     ArrayNumberer methodNumberer = new ArrayNumberer();
82     Numberer unitNumberer = new MapNumberer();
83     Numberer contextNumberer = null;
84     ArrayNumberer fieldNumberer = new ArrayNumberer();
85     ArrayNumberer classNumberer = new ArrayNumberer();
86     StringNumberer subSigNumberer = new StringNumberer();
87     ArrayNumberer localNumberer = new ArrayNumberer();
88
89     private Hierarchy activeHierarchy;
90     private FastHierarchy activeFastHierarchy;
91     private CallGraph activeCallGraph;
92     private ReachableMethods reachableMethods;
93     private PointsToAnalysis activePointsToAnalysis;
94     private SideEffectAnalysis activeSideEffectAnalysis;
95     private List entryPoints;
96
97     boolean allowsPhantomRefs = false;
98
99     // temporary for testing cfgs in plugin
100

101     public ArrayList cfgList = new ArrayList();
102     
103     SootClass mainClass;
104     String JavaDoc sootClassPath = null;
105
106     // Two default values for constructing ExceptionalUnitGraphs:
107
private ThrowAnalysis defaultThrowAnalysis = null;
108     private boolean alwaysAddEdgesFromExceptingUnits = false;
109     
110     public void setMainClass(SootClass m)
111     {
112         mainClass = m;
113     }
114     
115     Set reservedNames = new HashSet();
116     
117     /**
118         Returns a set of tokens which are reserved. Any field, class, method, or local variable with such a name will be quoted.
119      */

120      
121     public Set getReservedNames()
122     {
123         return reservedNames;
124     }
125     
126     /**
127         If this name is in the set of reserved names, then return a quoted version of it. Else pass it through.
128      */

129     
130     public String JavaDoc quotedNameOf(String JavaDoc s)
131     {
132         if(reservedNames.contains(s))
133             return "\'" + s + "\'";
134         else
135             return s;
136     }
137     
138     public SootClass getMainClass()
139     {
140         if(mainClass == null)
141             throw new RuntimeException JavaDoc("There is no main class set!");
142             
143         return mainClass;
144     }
145     
146     
147     public void setSootClassPath(String JavaDoc p)
148     {
149         sootClassPath = p;
150         SourceLocator.v().invalidateClassPath();
151     }
152     
153     public String JavaDoc getSootClassPath()
154     {
155         if( sootClassPath == null ) {
156             String JavaDoc optionscp = Options.v().soot_classpath();
157             if( optionscp.length() > 0 )
158                 sootClassPath = optionscp;
159         }
160         if( sootClassPath == null ) {
161             sootClassPath = System.getProperty("java.class.path")+File.pathSeparator+
162                 System.getProperty("java.home")+File.separator+
163                 "lib"+File.separator+"rt.jar";
164         }
165         return sootClassPath;
166     }
167
168
169     private int stateCount;
170     public int getState() { return this.stateCount; }
171     private void modifyHierarchy() {
172         stateCount++;
173         activeFastHierarchy = null;
174         activeSideEffectAnalysis = null;
175         activePointsToAnalysis = null;
176     }
177
178     public void addClass(SootClass c)
179     {
180         if(c.isInScene())
181             throw new RuntimeException JavaDoc("already managed: "+c.getName());
182
183         if(containsClass(c.getName()))
184             throw new RuntimeException JavaDoc("duplicate class: "+c.getName());
185
186         classes.add(c);
187         c.setLibraryClass();
188
189         nameToClass.put(c.getName(), c.getType());
190         c.getType().setSootClass(c);
191         c.setInScene(true);
192         modifyHierarchy();
193     }
194
195     public void removeClass(SootClass c)
196     {
197         if(!c.isInScene())
198             throw new RuntimeException JavaDoc();
199
200         classes.remove(c);
201         c.getType().setSootClass(null);
202         c.setInScene(false);
203         modifyHierarchy();
204     }
205
206     public boolean containsClass(String JavaDoc className)
207     {
208         RefType type = (RefType) nameToClass.get(className);
209         if( type == null ) return false;
210         if( !type.hasSootClass() ) return false;
211         SootClass c = type.getSootClass();
212         return c.isInScene();
213     }
214
215     public String JavaDoc signatureToClass(String JavaDoc sig) {
216         if( sig.charAt(0) != '<' ) throw new RuntimeException JavaDoc("oops "+sig);
217         if( sig.charAt(sig.length()-1) != '>' ) throw new RuntimeException JavaDoc("oops "+sig);
218         int index = sig.indexOf( ":" );
219         if( index < 0 ) throw new RuntimeException JavaDoc("oops "+sig);
220         return sig.substring(1,index);
221     }
222
223     public String JavaDoc signatureToSubsignature(String JavaDoc sig) {
224         if( sig.charAt(0) != '<' ) throw new RuntimeException JavaDoc("oops "+sig);
225         if( sig.charAt(sig.length()-1) != '>' ) throw new RuntimeException JavaDoc("oops "+sig);
226         int index = sig.indexOf( ":" );
227         if( index < 0 ) throw new RuntimeException JavaDoc("oops "+sig);
228         return sig.substring(index+2,sig.length()-1);
229     }
230
231     private SootField grabField(String JavaDoc fieldSignature)
232     {
233         String JavaDoc cname = signatureToClass( fieldSignature );
234         String JavaDoc fname = signatureToSubsignature( fieldSignature );
235         if( !containsClass(cname) ) return null;
236         SootClass c = getSootClass(cname);
237         if( !c.declaresField( fname ) ) return null;
238         return c.getField( fname );
239     }
240
241     public boolean containsField(String JavaDoc fieldSignature)
242     {
243         return grabField(fieldSignature) != null;
244     }
245     
246     private SootMethod grabMethod(String JavaDoc methodSignature)
247     {
248         String JavaDoc cname = signatureToClass( methodSignature );
249         String JavaDoc mname = signatureToSubsignature( methodSignature );
250         if( !containsClass(cname) ) return null;
251         SootClass c = getSootClass(cname);
252         if( !c.declaresMethod( mname ) ) return null;
253         return c.getMethod( mname );
254     }
255
256     public boolean containsMethod(String JavaDoc methodSignature)
257     {
258         return grabMethod(methodSignature) != null;
259     }
260
261     public SootField getField(String JavaDoc fieldSignature)
262     {
263         SootField f = grabField( fieldSignature );
264         if (f != null)
265             return f;
266
267         throw new RuntimeException JavaDoc("tried to get nonexistent field "+fieldSignature);
268     }
269
270     public SootMethod getMethod(String JavaDoc methodSignature)
271     {
272         SootMethod m = grabMethod( methodSignature );
273         if (m != null)
274             return m;
275         throw new RuntimeException JavaDoc("tried to get nonexistent method "+methodSignature);
276     }
277
278     /**
279      * Attempts to load the given class and all of the required support classes.
280      * Returns the original class if it was loaded, or null otherwise.
281      */

282      
283     public SootClass tryLoadClass(String JavaDoc className, int desiredLevel)
284     {
285         /*
286         if(Options.v().time())
287             Main.v().resolveTimer.start();
288         */

289         
290         Scene.v().setPhantomRefs(true);
291         //SootResolver resolver = new SootResolver();
292
if( !getPhantomRefs()
293         && SourceLocator.v().getClassSource(className) == null ) {
294             Scene.v().setPhantomRefs(false);
295             return null;
296         }
297         SootResolver resolver = SootResolver.v();
298         SootClass toReturn = resolver.resolveClass(className, desiredLevel);
299         Scene.v().setPhantomRefs(false);
300
301         return toReturn;
302         
303         /*
304         if(Options.v().time())
305             Main.v().resolveTimer.end(); */

306     }
307     
308     /**
309      * Loads the given class and all of the required support classes. Returns the first class.
310      */

311      
312     public SootClass loadClassAndSupport(String JavaDoc className)
313     {
314         SootClass ret = loadClass(className, SootClass.SIGNATURES);
315         if( !ret.isPhantom() ) ret = loadClass(className, SootClass.BODIES);
316         return ret;
317     }
318
319     public SootClass loadClass(String JavaDoc className, int desiredLevel)
320     {
321         /*
322         if(Options.v().time())
323             Main.v().resolveTimer.start();
324         */

325         
326         Scene.v().setPhantomRefs(true);
327         //SootResolver resolver = new SootResolver();
328
SootResolver resolver = SootResolver.v();
329         SootClass toReturn = resolver.resolveClass(className, desiredLevel);
330         Scene.v().setPhantomRefs(false);
331
332         return toReturn;
333         
334         /*
335         if(Options.v().time())
336             Main.v().resolveTimer.end(); */

337     }
338     
339     /**
340      * Returns the RefType with the given className.
341      */

342     public RefType getRefType(String JavaDoc className)
343     {
344         return (RefType) nameToClass.get(className);
345     }
346
347     /**
348      * Returns the RefType with the given className.
349      */

350     public void addRefType(RefType type)
351     {
352         nameToClass.put(type.getClassName(), type);
353     }
354
355     /**
356      * Returns the SootClass with the given className.
357      */

358
359     public SootClass getSootClass(String JavaDoc className)
360     {
361         RefType type = (RefType) nameToClass.get(className);
362         SootClass toReturn = null;
363         if( type != null ) toReturn = type.getSootClass();
364         
365         if(toReturn != null) {
366         return toReturn;
367     } else if(Scene.v().allowsPhantomRefs()) {
368         SootClass c = new SootClass(className);
369         c.setPhantom(true);
370         addClass(c);
371         return c;
372     }
373     else {
374         throw new RuntimeException JavaDoc( System.getProperty("line.separator") + "Aborting: can't find classfile " + className );
375     }
376     }
377
378     /**
379      * Returns an backed chain of the classes in this manager.
380      */

381      
382     public Chain getClasses()
383     {
384         return classes;
385     }
386
387     /* The four following chains are mutually disjoint. */
388
389     /**
390      * Returns a chain of the application classes in this scene.
391      * These classes are the ones which can be freely analysed & modified.
392      */

393     public Chain getApplicationClasses()
394     {
395         return applicationClasses;
396     }
397
398     /**
399      * Returns a chain of the library classes in this scene.
400      * These classes can be analysed but not modified.
401      */

402     public Chain getLibraryClasses()
403     {
404         return libraryClasses;
405     }
406
407     /**
408      * Returns a chain of the phantom classes in this scene.
409      * These classes are referred to by other classes, but cannot be loaded.
410      */

411     public Chain getPhantomClasses()
412     {
413         return phantomClasses;
414     }
415
416     Chain getContainingChain(SootClass c)
417     {
418         if (c.isApplicationClass())
419             return getApplicationClasses();
420         else if (c.isLibraryClass())
421             return getLibraryClasses();
422         else if (c.isPhantomClass())
423             return getPhantomClasses();
424
425         return null;
426     }
427
428     /****************************************************************************/
429     /**
430         Retrieves the active side-effect analysis
431      */

432
433     public SideEffectAnalysis getSideEffectAnalysis()
434     {
435         if(!hasSideEffectAnalysis()) {
436         setSideEffectAnalysis( new SideEffectAnalysis(
437             getPointsToAnalysis(),
438             getCallGraph() ) );
439     }
440             
441         return activeSideEffectAnalysis;
442     }
443     
444     /**
445         Sets the active side-effect analysis
446      */

447      
448     public void setSideEffectAnalysis(SideEffectAnalysis sea)
449     {
450         activeSideEffectAnalysis = sea;
451     }
452
453     public boolean hasSideEffectAnalysis()
454     {
455         return activeSideEffectAnalysis != null;
456     }
457     
458     public void releaseSideEffectAnalysis()
459     {
460         activeSideEffectAnalysis = null;
461     }
462
463     /****************************************************************************/
464     /**
465         Retrieves the active pointer analysis
466      */

467
468     public PointsToAnalysis getPointsToAnalysis()
469     {
470         if(!hasPointsToAnalysis()) {
471         return DumbPointerAnalysis.v();
472     }
473             
474         return activePointsToAnalysis;
475     }
476     
477     /**
478         Sets the active pointer analysis
479      */

480      
481     public void setPointsToAnalysis(PointsToAnalysis pa)
482     {
483         activePointsToAnalysis = pa;
484     }
485
486     public boolean hasPointsToAnalysis()
487     {
488         return activePointsToAnalysis != null;
489     }
490     
491     public void releasePointsToAnalysis()
492     {
493         activePointsToAnalysis = null;
494     }
495
496     /****************************************************************************/
497     /** Makes a new fast hierarchy is none is active, and returns the active
498      * fast hierarchy. */

499     public FastHierarchy getOrMakeFastHierarchy() {
500     if(!hasFastHierarchy() ) {
501         setFastHierarchy( new FastHierarchy() );
502     }
503     return getFastHierarchy();
504     }
505     /**
506         Retrieves the active fast hierarchy
507      */

508
509     public FastHierarchy getFastHierarchy()
510     {
511         if(!hasFastHierarchy())
512             throw new RuntimeException JavaDoc("no active FastHierarchy present for scene");
513             
514         return activeFastHierarchy;
515     }
516     
517     /**
518         Sets the active hierarchy
519      */

520      
521     public void setFastHierarchy(FastHierarchy hierarchy)
522     {
523         activeFastHierarchy = hierarchy;
524     }
525
526     public boolean hasFastHierarchy()
527     {
528         return activeFastHierarchy != null;
529     }
530     
531     public void releaseFastHierarchy()
532     {
533         activeFastHierarchy = null;
534     }
535
536     /****************************************************************************/
537     /**
538         Retrieves the active hierarchy
539      */

540
541     public Hierarchy getActiveHierarchy()
542     {
543         if(!hasActiveHierarchy())
544             //throw new RuntimeException("no active Hierarchy present for scene");
545
setActiveHierarchy( new Hierarchy() );
546             
547         return activeHierarchy;
548     }
549     
550     /**
551         Sets the active hierarchy
552      */

553      
554     public void setActiveHierarchy(Hierarchy hierarchy)
555     {
556         activeHierarchy = hierarchy;
557     }
558
559     public boolean hasActiveHierarchy()
560     {
561         return activeHierarchy != null;
562     }
563     
564     public void releaseActiveHierarchy()
565     {
566         activeHierarchy = null;
567     }
568
569     /** Get the set of entry points that are used to build the call graph. */
570     public List getEntryPoints() {
571         if( entryPoints == null ) {
572             entryPoints = EntryPoints.v().all();
573         }
574         return entryPoints;
575     }
576
577     /** Change the set of entry point methods used to build the call graph. */
578     public void setEntryPoints( List entryPoints ) {
579         this.entryPoints = entryPoints;
580     }
581
582     private ContextSensitiveCallGraph cscg;
583     public ContextSensitiveCallGraph getContextSensitiveCallGraph() {
584         if(cscg == null) throw new RuntimeException JavaDoc("No context-sensitive call graph present in Scene. You can bulid one with Paddle.");
585         return cscg;
586     }
587
588     public void setContextSensitiveCallGraph(ContextSensitiveCallGraph cscg) {
589         this.cscg = cscg;
590     }
591
592     public CallGraph getCallGraph()
593     {
594         if(!hasCallGraph()) {
595             throw new RuntimeException JavaDoc( "No call graph present in Scene. Maybe you want Whole Program mode (-w)." );
596         }
597             
598         return activeCallGraph;
599     }
600     
601     public void setCallGraph(CallGraph cg)
602     {
603         reachableMethods = null;
604         activeCallGraph = cg;
605     }
606
607     public boolean hasCallGraph()
608     {
609         return activeCallGraph != null;
610     }
611     
612     public void releaseCallGraph()
613     {
614         activeCallGraph = null;
615         reachableMethods = null;
616     }
617     public ReachableMethods getReachableMethods() {
618         if( reachableMethods == null ) {
619             reachableMethods = new ReachableMethods(
620                     getCallGraph(), getEntryPoints() );
621         }
622         reachableMethods.update();
623         return reachableMethods;
624     }
625     public void setReachableMethods( ReachableMethods rm ) {
626         reachableMethods = rm;
627     }
628     public boolean hasReachableMethods() {
629         return reachableMethods != null;
630     }
631     public void releaseReachableMethods() {
632         reachableMethods = null;
633     }
634    
635     public boolean getPhantomRefs()
636     {
637         if( !Options.v().allow_phantom_refs() ) return false;
638         return allowsPhantomRefs;
639     }
640
641     public void setPhantomRefs(boolean value)
642     {
643         allowsPhantomRefs = value;
644     }
645     
646     public boolean allowsPhantomRefs()
647     {
648         return getPhantomRefs();
649     }
650     public Numberer kindNumberer() { return kindNumberer; }
651     public ArrayNumberer getTypeNumberer() { return typeNumberer; }
652     public ArrayNumberer getMethodNumberer() { return methodNumberer; }
653     public Numberer getContextNumberer() { return contextNumberer; }
654     public Numberer getUnitNumberer() { return unitNumberer; }
655     public ArrayNumberer getFieldNumberer() { return fieldNumberer; }
656     public ArrayNumberer getClassNumberer() { return classNumberer; }
657     public StringNumberer getSubSigNumberer() { return subSigNumberer; }
658     public ArrayNumberer getLocalNumberer() { return localNumberer; }
659
660     public void setContextNumberer( Numberer n ) {
661         if( contextNumberer != null )
662             throw new RuntimeException JavaDoc(
663                     "Attempt to set context numberer when it is already set." );
664         contextNumberer = n;
665     }
666
667     /**
668      * Returns the {@link ThrowAnalysis} to be used by default when
669      * constructing CFGs which include exceptional control flow.
670      *
671      * @return the default {@link ThrowAnalysis}
672      */

673     public ThrowAnalysis getDefaultThrowAnalysis()
674     {
675     if( defaultThrowAnalysis == null ) {
676         int optionsThrowAnalysis = Options.v().throw_analysis();
677         switch (optionsThrowAnalysis) {
678         case Options.throw_analysis_pedantic:
679         defaultThrowAnalysis = PedanticThrowAnalysis.v();
680         break;
681         case Options.throw_analysis_unit:
682         defaultThrowAnalysis = UnitThrowAnalysis.v();
683         break;
684         default:
685         throw new IllegalStateException JavaDoc("Options.v().throw_analysi() == " +
686                         Options.v().throw_analysis());
687         }
688     }
689     return defaultThrowAnalysis;
690     }
691
692     /**
693      * Sets the {@link ThrowAnalysis} to be used by default when
694      * constructing CFGs which include exceptional control flow.
695      *
696      * @param the default {@link ThrowAnalysis}.
697      */

698     public void setDefaultThrowAnalysis(ThrowAnalysis ta)
699     {
700     defaultThrowAnalysis = ta;
701     }
702
703     private void setReservedNames()
704     {
705         Set rn = getReservedNames();
706         rn.add("newarray");
707         rn.add("newmultiarray");
708         rn.add("nop");
709         rn.add("ret");
710         rn.add("specialinvoke");
711         rn.add("staticinvoke");
712         rn.add("tableswitch");
713         rn.add("virtualinvoke");
714         rn.add("null_type");
715         rn.add("unknown");
716         rn.add("cmp");
717         rn.add("cmpg");
718         rn.add("cmpl");
719         rn.add("entermonitor");
720         rn.add("exitmonitor");
721         rn.add("interfaceinvoke");
722         rn.add("lengthof");
723         rn.add("lookupswitch");
724         rn.add("neg");
725         rn.add("if");
726         rn.add("abstract");
727         rn.add("boolean");
728         rn.add("break");
729         rn.add("byte");
730         rn.add("case");
731         rn.add("catch");
732         rn.add("char");
733         rn.add("class");
734         rn.add("final");
735         rn.add("native");
736         rn.add("public");
737         rn.add("protected");
738         rn.add("private");
739         rn.add("static");
740         rn.add("synchronized");
741         rn.add("transient");
742         rn.add("volatile");
743     rn.add("interface");
744         rn.add("void");
745         rn.add("short");
746         rn.add("int");
747         rn.add("long");
748         rn.add("float");
749         rn.add("double");
750         rn.add("extends");
751         rn.add("implements");
752         rn.add("breakpoint");
753         rn.add("default");
754         rn.add("goto");
755         rn.add("instanceof");
756         rn.add("new");
757         rn.add("return");
758         rn.add("throw");
759         rn.add("throws");
760         rn.add("null");
761         rn.add("from");
762     rn.add("to");
763     }
764
765     private Set[]/*<String>*/ basicclasses=new Set[4];
766
767     private void addSootBasicClasses() {
768         basicclasses[SootClass.HIERARCHY] = new HashSet();
769         basicclasses[SootClass.SIGNATURES] = new HashSet();
770         basicclasses[SootClass.BODIES] = new HashSet();
771
772     addBasicClass("java.lang.Object");
773     addBasicClass("java.lang.Class", SootClass.SIGNATURES);
774
775     addBasicClass("java.lang.Void", SootClass.SIGNATURES);
776     addBasicClass("java.lang.Boolean", SootClass.SIGNATURES);
777     addBasicClass("java.lang.Byte", SootClass.SIGNATURES);
778     addBasicClass("java.lang.Character", SootClass.SIGNATURES);
779     addBasicClass("java.lang.Short", SootClass.SIGNATURES);
780     addBasicClass("java.lang.Integer", SootClass.SIGNATURES);
781     addBasicClass("java.lang.Long", SootClass.SIGNATURES);
782     addBasicClass("java.lang.Float", SootClass.SIGNATURES);
783     addBasicClass("java.lang.Double", SootClass.SIGNATURES);
784
785     addBasicClass("java.lang.String");
786     addBasicClass("java.lang.StringBuffer", SootClass.SIGNATURES);
787
788     addBasicClass("java.lang.Error");
789     addBasicClass("java.lang.AssertionError", SootClass.SIGNATURES);
790     addBasicClass("java.lang.Throwable", SootClass.SIGNATURES);
791     addBasicClass("java.lang.NoClassDefFoundError", SootClass.SIGNATURES);
792     addBasicClass("java.lang.ExceptionInInitializerError");
793     addBasicClass("java.lang.RuntimeException");
794     addBasicClass("java.lang.ClassNotFoundException");
795     addBasicClass("java.lang.ArithmeticException");
796     addBasicClass("java.lang.ArrayStoreException");
797     addBasicClass("java.lang.ClassCastException");
798     addBasicClass("java.lang.IllegalMonitorStateException");
799     addBasicClass("java.lang.IndexOutOfBoundsException");
800     addBasicClass("java.lang.ArrayIndexOutOfBoundsException");
801     addBasicClass("java.lang.NegativeArraySizeException");
802     addBasicClass("java.lang.NullPointerException");
803     addBasicClass("java.lang.InstantiationError");
804     addBasicClass("java.lang.InternalError");
805     addBasicClass("java.lang.OutOfMemoryError");
806     addBasicClass("java.lang.StackOverflowError");
807     addBasicClass("java.lang.UnknownError");
808     addBasicClass("java.lang.ThreadDeath");
809     addBasicClass("java.lang.ClassCircularityError");
810     addBasicClass("java.lang.ClassFormatError");
811     addBasicClass("java.lang.IllegalAccessError");
812     addBasicClass("java.lang.IncompatibleClassChangeError");
813     addBasicClass("java.lang.LinkageError");
814     addBasicClass("java.lang.VerifyError");
815     addBasicClass("java.lang.NoSuchFieldError");
816     addBasicClass("java.lang.AbstractMethodError");
817     addBasicClass("java.lang.NoSuchMethodError");
818     addBasicClass("java.lang.UnsatisfiedLinkError");
819
820     addBasicClass("java.lang.Thread");
821     addBasicClass("java.lang.Runnable");
822     addBasicClass("java.lang.Cloneable");
823
824     addBasicClass("java.io.Serializable");
825
826     addBasicClass("java.lang.ref.Finalizer");
827     }
828
829     public void addBasicClass(String JavaDoc name) {
830     addBasicClass(name,SootClass.HIERARCHY);
831     }
832     
833     public void addBasicClass(String JavaDoc name,int level) {
834     basicclasses[level].add(name);
835     }
836
837     /** Load just the set of basic classes soot needs, ignoring those
838      * specified on the command-line. You don't need to use both this and
839      * loadNecessaryClasses, though it will only waste time.
840      */

841     public void loadBasicClasses() {
842     Iterator it;
843
844     for(int i=SootClass.BODIES;i>=SootClass.HIERARCHY;i--) {
845         it = basicclasses[i].iterator();
846         while(it.hasNext()) {
847         String JavaDoc name=(String JavaDoc) it.next();
848         tryLoadClass(name,i);
849         }
850     }
851     }
852
853     private List dynamicClasses;
854     public Collection dynamicClasses() {
855         return dynamicClasses;
856     }
857
858     private void loadNecessaryClass(String JavaDoc name) {
859         SootClass c;
860
861         c = Scene.v().loadClassAndSupport(name);
862
863         if (mainClass == null) {
864             mainClass = c;
865             Scene.v().setMainClass(c);
866         }
867         c.setApplicationClass();
868     }
869     /** Load the set of classes that soot needs, including those specified on the
870      * command-line. This is the standard way of initialising the list of
871      * classes soot should use.
872      */

873     public void loadNecessaryClasses() {
874     loadBasicClasses();
875
876         Iterator it = Options.v().classes().iterator();
877
878         while (it.hasNext()) {
879             String JavaDoc name = (String JavaDoc) it.next();
880             loadNecessaryClass(name);
881         }
882
883         loadDynamicClasses();
884
885         for( Iterator pathIt = Options.v().process_dir().iterator(); pathIt.hasNext(); ) {
886
887             final String JavaDoc path = (String JavaDoc) pathIt.next();
888             for( Iterator clIt = SourceLocator.v().getClassesUnder(path).iterator(); clIt.hasNext(); ) {
889                 final String JavaDoc cl = (String JavaDoc) clIt.next();
890                 Scene.v().loadClassAndSupport(cl).setApplicationClass();
891             }
892         }
893
894         prepareClasses();
895         setMainClassFromOptions();
896         setDoneResolving();
897     }
898
899     public void loadDynamicClasses() {
900         dynamicClasses = new ArrayList();
901         HashSet dynClasses = new HashSet();
902         dynClasses.addAll(Options.v().dynamic_class());
903
904         for( Iterator pathIt = Options.v().dynamic_dir().iterator(); pathIt.hasNext(); ) {
905
906             final String JavaDoc path = (String JavaDoc) pathIt.next();
907             dynClasses.addAll(SourceLocator.v().getClassesUnder(path));
908         }
909
910         for( Iterator pkgIt = Options.v().dynamic_package().iterator(); pkgIt.hasNext(); ) {
911
912             final String JavaDoc pkg = (String JavaDoc) pkgIt.next();
913             dynClasses.addAll(SourceLocator.v().classesInDynamicPackage(pkg));
914         }
915
916         for( Iterator classNameIt = dynClasses.iterator(); classNameIt.hasNext(); ) {
917
918             final String JavaDoc className = (String JavaDoc) classNameIt.next();
919             dynamicClasses.add( Scene.v().loadClassAndSupport(className) );
920         }
921     }
922
923
924     /* Generate classes to process, adding or removing package marked by
925      * command line options.
926      */

927     private void prepareClasses() {
928
929         LinkedList excludedPackages = new LinkedList();
930         if (Options.v().exclude() != null)
931             excludedPackages.addAll(Options.v().exclude());
932
933         if( !Options.v().include_all() ) {
934             excludedPackages.add("java.");
935             excludedPackages.add("sun.");
936             excludedPackages.add("javax.");
937             excludedPackages.add("com.sun.");
938             excludedPackages.add("com.ibm.");
939             excludedPackages.add("org.xml.");
940             excludedPackages.add("org.w3c.");
941             excludedPackages.add("org.apache.");
942         }
943
944         // Remove/add all classes from packageInclusionMask as per -i option
945
Set processedClasses = new HashSet();
946         while(true) {
947             Set unprocessedClasses = new HashSet(Scene.v().getClasses());
948             unprocessedClasses.removeAll(processedClasses);
949             if( unprocessedClasses.isEmpty() ) break;
950             processedClasses.addAll(unprocessedClasses);
951             for( Iterator sIt = unprocessedClasses.iterator(); sIt.hasNext(); ) {
952                 final SootClass s = (SootClass) sIt.next();
953                 if( s.isPhantom() ) continue;
954                 if(Options.v().app()) {
955                     s.setApplicationClass();
956                 }
957                 if (Options.v().classes().contains(s.getName())) {
958                     s.setApplicationClass();
959                     continue;
960                 }
961                 for( Iterator pkgIt = excludedPackages.iterator(); pkgIt.hasNext(); ) {
962                     final String JavaDoc pkg = (String JavaDoc) pkgIt.next();
963                     if (s.isApplicationClass()
964                     && s.getPackageName().startsWith(pkg)) {
965                             s.setLibraryClass();
966                     }
967                 }
968                 for( Iterator pkgIt = Options.v().include().iterator(); pkgIt.hasNext(); ) {
969                     final String JavaDoc pkg = (String JavaDoc) pkgIt.next();
970                     if (s.getPackageName().startsWith(pkg))
971                         s.setApplicationClass();
972                 }
973                 if(s.isApplicationClass()) {
974                     // make sure we have the support
975
Scene.v().loadClassAndSupport(s.getName());
976                 }
977             }
978         }
979     }
980
981     ArrayList pkgList;
982
983     public void setPkgList(ArrayList list){
984         pkgList = list;
985     }
986
987     public ArrayList getPkgList(){
988         return pkgList;
989     }
990
991
992     /** Create an unresolved reference to a method. */
993     public SootMethodRef makeMethodRef(
994             SootClass declaringClass,
995             String JavaDoc name,
996             List/*Type*/ parameterTypes,
997             Type returnType,
998             boolean isStatic ) {
999         return new AbstractSootMethodRef(declaringClass, name, parameterTypes,
1000                returnType, isStatic);
1001    }
1002
1003    /** Create an unresolved reference to a constructor. */
1004    public SootMethodRef makeConstructorRef(
1005            SootClass declaringClass,
1006            List/*Type*/ parameterTypes) {
1007        return makeMethodRef(declaringClass, SootMethod.constructorName,
1008                                         parameterTypes, VoidType.v(), false );
1009    }
1010
1011
1012    /** Create an unresolved reference to a field. */
1013    public SootFieldRef makeFieldRef(
1014            SootClass declaringClass,
1015            String JavaDoc name,
1016            Type type,
1017            boolean isStatic) {
1018        return new AbstractSootFieldRef(declaringClass, name, type, isStatic);
1019    }
1020    /** Returns the list of SootClasses that have been resolved at least to
1021     * the level specified. */

1022    public List/*SootClass*/ getClasses(int desiredLevel) {
1023        List ret = new ArrayList();
1024        for( Iterator clIt = getClasses().iterator(); clIt.hasNext(); ) {
1025            final SootClass cl = (SootClass) clIt.next();
1026            if( cl.resolvingLevel() >= desiredLevel ) ret.add(cl);
1027        }
1028        return ret;
1029    }
1030    private boolean doneResolving = false;
1031    public boolean doneResolving() { return doneResolving; }
1032    public void setDoneResolving() { doneResolving = true; }
1033    public void setMainClassFromOptions() {
1034        if( Options.v().main_class() != null
1035                && Options.v().main_class().length() > 0 ) {
1036            setMainClass(getSootClass(Options.v().main_class()));
1037        }
1038    }
1039}
1040
1041
Popular Tags