KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > soot > SootClass


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

25
26
27
28
29
30 package soot;
31
32 import soot.tagkit.*;
33 import soot.util.*;
34 import java.util.*;
35 import java.io.*;
36 import soot.baf.toolkits.base.*;
37 import soot.jimple.toolkits.base.*;
38 import soot.dava.*;
39 import soot.dava.toolkits.base.misc.*;
40 import soot.jimple.*;
41 import soot.options.*;
42
43 /*
44  * Incomplete and inefficient implementation.
45  *
46  * Implementation notes:
47  *
48  * 1. The getFieldOf() method is slow because it traverses the list of fields, comparing the names,
49  * one by one. If you establish a Dictionary of Name->Field, you will need to add a
50  * notifyOfNameChange() method, and register fields which belong to classes, because the hashtable
51  * will need to be updated. I will do this later. - kor 16-Sep-97
52  *
53  * 2. Note 1 is kept for historical (i.e. amusement) reasons. In fact, there is no longer a list of fields;
54  * these are kept in a Chain now. But that's ok; there is no longer a getFieldOf() method,
55  * either. There still is no efficient way to get a field by name, although one could establish
56  * a Chain of EquivalentValue-like objects and do an O(1) search on that. - plam 2-24-00
57  */

58
59 /**
60     Soot representation of a Java class. They are usually created by a Scene,
61     but can also be constructed manually through the given constructors.
62 */

63 public class SootClass extends AbstractHost implements Numberable
64 {
65     protected String JavaDoc name, shortName, fixedShortName, packageName, fixedPackageName;
66     protected int modifiers;
67     protected Chain fields = new HashChain();
68     protected SmallNumberedMap subSigToMethods = new SmallNumberedMap( Scene.v().getSubSigNumberer() );
69     // methodList is just for keeping the methods in a consistent order. It
70
// needs to be kept consistent with subSigToMethods.
71
protected List methodList = new ArrayList();
72     protected Chain interfaces = new HashChain();
73
74     protected boolean isInScene;
75     protected SootClass superClass;
76     protected SootClass outerClass;
77
78     protected boolean isPhantom;
79     
80     
81     /**
82         Constructs an empty SootClass with the given name and modifiers.
83     */

84
85     public SootClass(String JavaDoc name, int modifiers)
86     {
87         if( name.charAt(0) == '[' ) throw new RuntimeException JavaDoc( "Attempt to make a class whose name starts with [" );
88     setName( name);
89         this.modifiers = modifiers;
90         refType = RefType.v(name);
91         refType.setSootClass(this);
92         if(Options.v().debug_resolver()) G.v().out.println("created "+name+" with modifiers "+modifiers);
93         setResolvingLevel(BODIES);
94     }
95
96     /**
97         Constructs an empty SootClass with the given name and no modifiers.
98     */

99
100     public SootClass(String JavaDoc name)
101     {
102     this( name, 0);
103     }
104
105     public final static int DANGLING = 0;
106     public final static int HIERARCHY = 1;
107     public final static int SIGNATURES = 2;
108     public final static int BODIES = 3;
109     private int resolvingLevel = DANGLING;
110
111     private String JavaDoc levelToString( int level ) {
112         switch(level) {
113             case DANGLING: return "DANGLING";
114             case HIERARCHY: return "HIERARCHY";
115             case SIGNATURES: return "SIGNATURES";
116             case BODIES: return "BODIES";
117             default: throw new RuntimeException JavaDoc("unknown resolving level");
118         }
119     }
120     public void checkLevel( int level ) {
121         if( !Scene.v().doneResolving() ) return;
122         if( resolvingLevel < level ) {
123             /*
124             try {
125             */

126                 throw new RuntimeException JavaDoc(
127                     "This operation requires resolving level "+
128                     levelToString(level)+" but "+name+
129                     " is at resolving level "+levelToString(resolvingLevel) );
130                 /*
131             } catch( RuntimeException e ) {
132                 System.out.println("RESOLVING ERROR: "+e.toString());
133                 e.printStackTrace();
134             }
135             */

136         }
137     }
138
139     public int resolvingLevel() { return resolvingLevel; }
140     public void setResolvingLevel( int newLevel ) {
141         resolvingLevel = newLevel;
142     }
143
144     public boolean isInScene()
145     {
146         return isInScene;
147     }
148
149     /** Tells this class if it is being managed by a Scene. */
150     public void setInScene(boolean isInScene)
151     {
152         this.isInScene = isInScene;
153     }
154
155     /**
156         Returns the number of fields in this class.
157     */

158
159     public int getFieldCount()
160     {
161         checkLevel(SIGNATURES);
162         return fields.size();
163     }
164
165     /**
166      * Returns a backed Chain of fields.
167      */

168
169     public Chain getFields()
170     {
171         checkLevel(SIGNATURES);
172         return fields;
173     }
174
175     /*
176     public void setFields(Field[] fields)
177     {
178         this.fields = new ArraySet(fields);
179     }
180     */

181
182     /**
183         Adds the given field to this class.
184     */

185
186     public void addField(SootField f)
187     {
188         checkLevel(SIGNATURES);
189         if(f.isDeclared())
190             throw new RuntimeException JavaDoc("already declared: "+f.getName());
191
192     if(declaresField(f.getName()))
193             throw new RuntimeException JavaDoc("Field already exists : "+f.getName());
194  
195         fields.add(f);
196         f.isDeclared = true;
197         f.declaringClass = this;
198         
199     }
200
201     /**
202         Removes the given field from this class.
203     */

204
205     public void removeField(SootField f)
206     {
207         checkLevel(SIGNATURES);
208         if(!f.isDeclared() || f.getDeclaringClass() != this)
209             throw new RuntimeException JavaDoc("did not declare: "+f.getName());
210
211         fields.remove(f);
212         f.isDeclared = false;
213     }
214
215     /**
216         Returns the field of this class with the given name and type.
217     */

218
219     public SootField getField( String JavaDoc name, Type type ) {
220         checkLevel(SIGNATURES);
221         for( Iterator fieldIt = this.getFields().iterator(); fieldIt.hasNext(); ) {
222             final SootField field = (SootField) fieldIt.next();
223             if(field.name.equals(name) && field.type.equals(type))
224                 return field;
225         }
226         throw new RuntimeException JavaDoc("No field " + name + " in class " + getName());
227     }
228     
229     /**
230         Returns the field of this class with the given name. Throws a RuntimeException if there
231         are more than one.
232     */

233
234     public SootField getFieldByName(String JavaDoc name)
235     {
236         checkLevel(SIGNATURES);
237         boolean found = false;
238         SootField foundField = null;
239
240         Iterator fieldIt = getFields().iterator();
241
242         while(fieldIt.hasNext())
243         {
244             SootField field = (SootField) fieldIt.next();
245
246             if(field.name.equals(name))
247             {
248                 if(found)
249                     throw new RuntimeException JavaDoc("ambiguous field: "+name);
250                 else {
251                     found = true;
252                     foundField = field;
253                 }
254             }
255         }
256
257         if(found)
258             return foundField;
259         else
260             throw new RuntimeException JavaDoc("No field " + name + " in class " + getName());
261     }
262
263     
264     /*
265         Returns the field of this class with the given subsignature.
266     */

267
268     public SootField getField(String JavaDoc subsignature)
269     {
270         checkLevel(SIGNATURES);
271         for( Iterator fieldIt = this.getFields().iterator(); fieldIt.hasNext(); ) {
272             final SootField field = (SootField) fieldIt.next();
273             if( field.getSubSignature().equals( subsignature ) ) return field;
274         }
275
276         throw new RuntimeException JavaDoc("No field " + subsignature + " in class " + getName());
277     }
278
279     
280     /**
281         Does this class declare a field with the given subsignature?
282     */

283
284     public boolean declaresField(String JavaDoc subsignature)
285     {
286         checkLevel(SIGNATURES);
287         for( Iterator fieldIt = this.getFields().iterator(); fieldIt.hasNext(); ) {
288             final SootField field = (SootField) fieldIt.next();
289             if( field.getSubSignature().equals( subsignature ) ) return true;
290         }
291         return false;
292     }
293
294     
295     /*
296         Returns the method of this class with the given subsignature.
297     */

298
299     public SootMethod getMethod(NumberedString subsignature)
300     {
301         checkLevel(SIGNATURES);
302         SootMethod ret = (SootMethod) subSigToMethods.get( subsignature );
303         if(ret == null)
304             throw new RuntimeException JavaDoc("No method " + subsignature + " in class " + getName());
305         else
306             return ret;
307     }
308
309     /**
310         Does this class declare a method with the given subsignature?
311     */

312
313     public boolean declaresMethod(NumberedString subsignature)
314     {
315         checkLevel(SIGNATURES);
316         SootMethod ret = (SootMethod) subSigToMethods.get( subsignature );
317         return ret != null;
318     }
319     
320     
321     /*
322         Returns the method of this class with the given subsignature.
323     */

324
325     public SootMethod getMethod(String JavaDoc subsignature)
326     {
327         checkLevel(SIGNATURES);
328         return getMethod( Scene.v().getSubSigNumberer().findOrAdd( subsignature ) );
329     }
330
331     /**
332         Does this class declare a method with the given subsignature?
333     */

334
335     public boolean declaresMethod(String JavaDoc subsignature)
336     {
337         checkLevel(SIGNATURES);
338         return declaresMethod( Scene.v().getSubSigNumberer().findOrAdd( subsignature ) );
339     }
340     
341     
342     /**
343         Does this class declare a field with the given name?
344     */

345
346     public boolean declaresFieldByName(String JavaDoc name)
347     {
348         checkLevel(SIGNATURES);
349         Iterator fieldIt = getFields().iterator();
350
351         while(fieldIt.hasNext())
352         {
353             SootField field = (SootField) fieldIt.next();
354
355             if(field.name.equals(name))
356                 return true;
357         }
358
359         return false;
360     }
361
362     
363     /**
364         Does this class declare a field with the given name and type.
365     */

366
367     public boolean declaresField(String JavaDoc name, Type type)
368     {
369         checkLevel(SIGNATURES);
370         Iterator fieldIt = getFields().iterator();
371
372         while(fieldIt.hasNext())
373         {
374             SootField field = (SootField) fieldIt.next();
375
376             if(field.name.equals(name) &&
377                 field.type.equals(type))
378                 return true;
379         }
380
381         return false;
382     }
383
384     /**
385         Returns the number of methods in this class.
386     */

387
388     public int getMethodCount()
389     {
390         checkLevel(SIGNATURES);
391         return subSigToMethods.nonNullSize();
392     }
393
394     /**
395      * Returns an iterator over the methods in this class.
396      */

397
398     public Iterator methodIterator()
399     {
400         checkLevel(SIGNATURES);
401         return methodList.iterator();
402     }
403
404     public List getMethods() {
405         checkLevel(SIGNATURES);
406         ArrayList ret = new ArrayList();
407         for( Iterator it = methodIterator(); it.hasNext(); )
408             ret.add( it.next() );
409         return ret;
410     }
411
412     public SootMethod getMethod( String JavaDoc name, List parameterTypes,
413             Type returnType )
414     {
415         checkLevel(SIGNATURES);
416         for( Iterator methodIt = methodIterator(); methodIt.hasNext(); ) {
417             final SootMethod method = (SootMethod) methodIt.next();
418             if(method.getName().equals(name) &&
419                 parameterTypes.equals(method.getParameterTypes()) &&
420                 returnType.equals(method.getReturnType()))
421             {
422                 return method;
423             }
424         }
425         throw new RuntimeException JavaDoc(
426                 "Class "+getName()+" doesn't have method "+
427             name + "(" + parameterTypes + ")" + " : " + returnType );
428     }
429     /**
430         Attempts to retrieve the method with the given name, parameters and return type.
431     */

432
433     /**
434         Attempts to retrieve the method with the given name and parameters. This method
435         may throw an AmbiguousMethodException if there is more than one method with the
436         given name and parameter.
437     */

438
439     public SootMethod getMethod(String JavaDoc name, List parameterTypes)
440     {
441         checkLevel(SIGNATURES);
442         boolean found = false;
443         SootMethod foundMethod = null;
444         
445         Iterator methodIt = methodIterator();
446
447         while(methodIt.hasNext())
448         {
449             SootMethod method = (SootMethod) methodIt.next();
450
451             if(method.getName().equals(name) &&
452                 parameterTypes.equals(method.getParameterTypes()))
453             {
454                 if(found)
455                     throw new RuntimeException JavaDoc("ambiguous method");
456                 else {
457                     found = true;
458                     foundMethod = method;
459                 }
460             }
461         }
462
463         if(found)
464             return foundMethod;
465         else
466             throw new RuntimeException JavaDoc("couldn't find method "+name+"("+parameterTypes+") in "+this);
467     }
468
469     
470      /**
471         Attempts to retrieve the method with the given name. This method
472         may throw an AmbiguousMethodException if there are more than one method with the
473         given name.
474     */

475
476     public SootMethod getMethodByName(String JavaDoc name)
477     {
478         checkLevel(SIGNATURES);
479         boolean found = false;
480         SootMethod foundMethod = null;
481         
482         Iterator methodIt = methodIterator();
483
484         while(methodIt.hasNext())
485         {
486             SootMethod method = (SootMethod) methodIt.next();
487
488             if(method.getName().equals(name))
489             {
490                 if(found)
491                     throw new RuntimeException JavaDoc("ambiguous method");
492                 else {
493                     found = true;
494                     foundMethod = method;
495                 }
496             }
497         }
498         if(found)
499             return foundMethod;
500         else
501             throw new RuntimeException JavaDoc("couldn't find method "+name+"(*) in "+this);
502     }
503
504     /**
505         Does this class declare a method with the given name and parameter types?
506     */

507
508     public boolean declaresMethod(String JavaDoc name, List parameterTypes)
509     {
510         checkLevel(SIGNATURES);
511         Iterator methodIt = methodIterator();
512
513         while(methodIt.hasNext())
514         {
515             SootMethod method = (SootMethod) methodIt.next();
516
517             if(method.getName().equals(name) &&
518                 method.getParameterTypes().equals(parameterTypes))
519                 return true;
520         }
521         
522         return false;
523     }
524
525     /**
526         Does this class declare a method with the given name, parameter types, and return type?
527     */

528
529     public boolean declaresMethod(String JavaDoc name, List parameterTypes, Type returnType)
530     {
531         checkLevel(SIGNATURES);
532         Iterator methodIt = methodIterator();
533
534         while(methodIt.hasNext())
535         {
536             SootMethod method = (SootMethod) methodIt.next();
537
538             if(method.getName().equals(name) &&
539                 method.getParameterTypes().equals(parameterTypes) &&
540                 method.getReturnType().equals(returnType))
541                 
542                 return true;
543         }
544         
545         return false;
546     }
547
548     /**
549         Does this class declare a method with the given name?
550     */

551
552     public boolean declaresMethodByName(String JavaDoc name)
553     {
554         checkLevel(SIGNATURES);
555         Iterator methodIt = methodIterator();
556
557         while(methodIt.hasNext())
558         {
559             SootMethod method = (SootMethod) methodIt.next();
560
561             if(method.getName().equals(name))
562                 return true;
563         }
564         
565         return false;
566     }
567
568     /*
569     public void setMethods(Method[] method)
570     {
571         methods = new ArraySet(method);
572     }
573     */

574
575     /**
576         Adds the given method to this class.
577     */

578
579     public void addMethod(SootMethod m)
580     {
581         checkLevel(SIGNATURES);
582         if(m.isDeclared())
583             throw new RuntimeException JavaDoc("already declared: "+m.getName());
584
585         /*
586         if(declaresMethod(m.getName(), m.getParameterTypes()))
587             throw new RuntimeException("duplicate signature for: " + m.getName());
588         */

589         
590         if(subSigToMethods.get(m.getNumberedSubSignature()) != null ) {
591             throw new RuntimeException JavaDoc(
592                     "Attempting to add method "+m.getSubSignature()+" to class "+this+", but the class already has a method with that signature.");
593         }
594         subSigToMethods.put(m.getNumberedSubSignature(),m);
595         methodList.add(m);
596         m.isDeclared = true;
597         m.declaringClass = this;
598         
599     }
600
601     /**
602         Removes the given method from this class.
603     */

604
605     public void removeMethod(SootMethod m)
606     {
607         checkLevel(SIGNATURES);
608         if(!m.isDeclared() || m.getDeclaringClass() != this)
609             throw new RuntimeException JavaDoc("incorrect declarer for remove: "+m.getName());
610
611         if(subSigToMethods.get(m.getNumberedSubSignature()) == null) {
612             throw new RuntimeException JavaDoc(
613                     "Attempt to remove method "+m.getSubSignature()+" which is not in class "+this);
614         }
615         subSigToMethods.put(m.getNumberedSubSignature(),null);
616         methodList.remove(m);
617         m.isDeclared = false;
618     }
619
620     /**
621         Returns the modifiers of this class.
622     */

623
624     public int getModifiers()
625     {
626         return modifiers;
627     }
628
629     /**
630         Sets the modifiers for this class.
631     */

632
633     public void setModifiers(int modifiers)
634     {
635         this.modifiers = modifiers;
636     }
637
638     /**
639         Returns the number of interfaces being directly implemented by this class. Note that direct
640         implementation corresponds to an "implements" keyword in the Java class file and that this class may
641         still be implementing additional interfaces in the usual sense by being a subclass of a class
642         which directly implements some interfaces.
643     */

644
645     public int getInterfaceCount()
646     {
647         checkLevel(HIERARCHY);
648         return interfaces.size();
649     }
650
651     /**
652      * Returns a backed Chain of the interfaces that are directly implemented by this class. (see getInterfaceCount())
653      */

654
655     public Chain getInterfaces()
656     {
657         checkLevel(HIERARCHY);
658         return interfaces;
659     }
660
661     /**
662         Does this class directly implement the given interface? (see getInterfaceCount())
663     */

664
665     public boolean implementsInterface(String JavaDoc name)
666     {
667         checkLevel(HIERARCHY);
668         Iterator interfaceIt = getInterfaces().iterator();
669
670         while(interfaceIt.hasNext())
671         {
672             SootClass SootClass = (SootClass) interfaceIt.next();
673
674             if(SootClass.getName().equals(name))
675                 return true;
676         }
677
678         return false;
679     }
680
681     /**
682         Add the given class to the list of interfaces which are directly implemented by this class.
683     */

684
685     public void addInterface(SootClass interfaceClass)
686     {
687         checkLevel(HIERARCHY);
688         if(implementsInterface(interfaceClass.getName()))
689             throw new RuntimeException JavaDoc("duplicate interface: "+interfaceClass.getName());
690         interfaces.add(interfaceClass);
691     }
692
693     /**
694         Removes the given class from the list of interfaces which are direclty implemented by this class.
695     */

696
697     public void removeInterface(SootClass interfaceClass)
698     {
699         checkLevel(HIERARCHY);
700         if(!implementsInterface(interfaceClass.getName()))
701             throw new RuntimeException JavaDoc("no such interface: "+interfaceClass.getName());
702
703         interfaces.remove(interfaceClass);
704     }
705
706     /**
707     WARNING: interfaces are subclasses of the java.lang.Object class!
708         Does this class have a superclass? False implies that this is
709         the java.lang.Object class. Note that interfaces are
710         subclasses of the java.lang.Object class. */

711
712     
713     public boolean hasSuperclass()
714     {
715         checkLevel(HIERARCHY);
716         return superClass != null;
717     }
718
719     /**
720     WARNING: interfaces are subclasses of the java.lang.Object class!
721         Returns the superclass of this class. (see hasSuperclass())
722     */

723
724     public SootClass getSuperclass()
725     {
726         checkLevel(HIERARCHY);
727         if(superClass == null)
728             throw new RuntimeException JavaDoc("no superclass for "+getName());
729         else
730             return superClass;
731     }
732
733     /**
734         Sets the superclass of this class. Note that passing a null will cause the class to have no superclass.
735     */

736
737     public void setSuperclass(SootClass c)
738     {
739         checkLevel(HIERARCHY);
740         superClass = c;
741     }
742
743     public boolean hasOuterClass(){
744         checkLevel(HIERARCHY);
745         return outerClass != null;
746     }
747
748     public SootClass getOuterClass(){
749         checkLevel(HIERARCHY);
750         if (outerClass == null)
751             throw new RuntimeException JavaDoc("no outer class");
752         else
753             return outerClass;
754     }
755
756     public void setOuterClass(SootClass c){
757         checkLevel(HIERARCHY);
758         outerClass = c;
759     }
760     
761     /**
762         Returns the name of this class.
763     */

764
765     public String JavaDoc getName()
766     {
767         return name;
768     }
769
770     public String JavaDoc getJavaStyleName()
771     {
772     if (PackageNamer.v().has_FixedNames()) {
773         if (fixedShortName == null)
774         fixedShortName = PackageNamer.v().get_FixedClassName( name);
775
776         if (PackageNamer.v().use_ShortName( getJavaPackageName(), fixedShortName) == false)
777         return getJavaPackageName() + "." + fixedShortName;
778
779         return fixedShortName;
780     }
781
782     return shortName;
783     }
784
785     public String JavaDoc getShortJavaStyleName()
786     {
787     if (PackageNamer.v().has_FixedNames()) {
788         if (fixedShortName == null)
789         fixedShortName = PackageNamer.v().get_FixedClassName( name);
790
791         return fixedShortName;
792     }
793
794     return shortName;
795     }
796
797     public String JavaDoc getShortName() {
798         return shortName;
799     }
800
801     /**
802         Returns the package name of this class.
803     */

804
805     public String JavaDoc getPackageName()
806     {
807     return packageName;
808     }
809
810     public String JavaDoc getJavaPackageName()
811     {
812     if (PackageNamer.v().has_FixedNames()) {
813         if (fixedPackageName == null)
814         fixedPackageName = PackageNamer.v().get_FixedPackageName( packageName);
815         
816         return fixedPackageName;
817     }
818
819     return packageName;
820     }
821
822     /**
823         Sets the name of this class.
824     */

825
826     private void setName(String JavaDoc name)
827     {
828         this.name = name;
829     
830     shortName = name;
831     packageName = "";
832
833     int index = name.lastIndexOf( '.');
834     if (index > 0) {
835         shortName = name.substring( index + 1);
836         packageName = name.substring( 0, index);
837     }
838
839     fixedShortName = null;
840     fixedPackageName = null;
841     }
842
843     /** Convenience method; returns true if this class is an interface. */
844     public boolean isInterface()
845     {
846         checkLevel(HIERARCHY);
847         return Modifier.isInterface(this.getModifiers());
848     }
849
850     /** Returns true if this class is not an interface and not abstract. */
851     public boolean isConcrete() {
852         return !isInterface() && !isAbstract();
853     }
854
855     /** Convenience method; returns true if this class is public. */
856     public boolean isPublic()
857     {
858         return Modifier.isPublic(this.getModifiers());
859     }
860
861     /** Returns true if some method in this class has an active Baf body. */
862     public boolean containsBafBody()
863     {
864         Iterator methodIt = methodIterator();
865         
866         while(methodIt.hasNext())
867         {
868             SootMethod m = (SootMethod) methodIt.next();
869             
870             if(m.hasActiveBody() &&
871                 m.getActiveBody() instanceof soot.baf.BafBody)
872             {
873                 return true;
874             }
875         }
876         
877         return false;
878     }
879     
880     private RefType refType;
881     void setRefType( RefType refType ) { this.refType = refType; }
882     public boolean hasRefType() { return refType != null; }
883     
884     /** Returns the RefType corresponding to this class. */
885     public RefType getType()
886     {
887         return refType;
888     }
889
890     /** Returns the name of this class. */
891     public String JavaDoc toString()
892     {
893         return getName();
894     }
895
896     /* Renames private fields and methods with numeric names. */
897     public void renameFieldsAndMethods(boolean privateOnly)
898     {
899         checkLevel(SIGNATURES);
900         // Rename fields. Ignore collisions for now.
901
{
902             Iterator fieldIt = this.getFields().iterator();
903             int fieldCount = 0;
904
905             if(fieldIt.hasNext())
906             {
907                 while(fieldIt.hasNext())
908                   {
909                       SootField f = (SootField)fieldIt.next();
910                       if (!privateOnly || Modifier.isPrivate(f.getModifiers()))
911                         {
912                           String JavaDoc newFieldName = "__field"+(fieldCount++);
913                           f.setName(newFieldName);
914                         }
915                   }
916             }
917         }
918
919         // Rename methods. Again, ignore collisions for now.
920
{
921             Iterator methodIt = this.methodIterator();
922             int methodCount = 0;
923
924             if(methodIt.hasNext())
925             {
926                 while(methodIt.hasNext())
927                   {
928                       SootMethod m = (SootMethod)methodIt.next();
929                       if (!privateOnly || Modifier.isPrivate(m.getModifiers()))
930                         {
931                           String JavaDoc newMethodName = "__method"+(methodCount++);
932                           m.setName(newMethodName);
933                         }
934                   }
935             }
936         }
937     }
938
939     /** Convenience method returning true if this class is an application class.
940      *
941      * @see Scene#getApplicationClasses() */

942     public boolean isApplicationClass()
943     {
944         return Scene.v().getApplicationClasses().contains(this);
945     }
946
947     /** Makes this class an application class. */
948     public void setApplicationClass()
949     {
950         Chain c = Scene.v().getContainingChain(this);
951         if (c != null)
952             c.remove(this);
953         Scene.v().getApplicationClasses().add(this);
954
955         isPhantom = false;
956     }
957
958     /** Convenience method returning true if this class is a library class.
959      *
960      * @see Scene#getLibraryClasses() */

961     public boolean isLibraryClass()
962     {
963         return Scene.v().getLibraryClasses().contains(this);
964     }
965
966     /** Makes this class a library class. */
967     public void setLibraryClass()
968     {
969         Chain c = Scene.v().getContainingChain(this);
970         if (c != null)
971             c.remove(this);
972         Scene.v().getLibraryClasses().add(this);
973
974         isPhantom = false;
975     }
976
977     /** Convenience method returning true if this class is a phantom class.
978      *
979      * @see Scene#getPhantomClasses() */

980     public boolean isPhantomClass()
981     {
982         return Scene.v().getPhantomClasses().contains(this);
983     }
984
985     /** Makes this class a phantom class. */
986     public void setPhantomClass()
987     {
988         Chain c = Scene.v().getContainingChain(this);
989         if (c != null)
990             c.remove(this);
991         Scene.v().getPhantomClasses().add(this);
992         isPhantom = true;
993     }
994     
995     /** Convenience method returning true if this class is phantom. */
996     public boolean isPhantom()
997     {
998         return isPhantom;
999     }
1000    
1001    /** Marks this class as phantom, without notifying the Scene. */
1002    public void setPhantom(boolean value)
1003    {
1004        if (value == false)
1005            if (isPhantom)
1006                throw new RuntimeException JavaDoc("don't know how to de-phantomize this class");
1007            else
1008                return;
1009        
1010        setPhantomClass();
1011    }
1012    /**
1013     * Convenience method returning true if this class is private.
1014     */

1015    public boolean isPrivate()
1016    {
1017        return Modifier.isPrivate(this.getModifiers());
1018    }
1019
1020    /**
1021     * Convenience method returning true if this class is protected.
1022     */

1023    public boolean isProtected()
1024    {
1025        return Modifier.isProtected(this.getModifiers());
1026    }
1027
1028    /**
1029     * Convenience method returning true if this class is abstract.
1030     */

1031    public boolean isAbstract()
1032    {
1033        return Modifier.isAbstract(this.getModifiers());
1034    }
1035
1036    public final int getNumber() { return number; }
1037    public final void setNumber( int number ) { this.number = number; }
1038
1039    private int number = 0;
1040}
1041
1042
Popular Tags