KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > soot > RefType


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 import soot.*;
32
33 import soot.util.*;
34 import java.util.*;
35
36 /**
37  * A class that models Java's reference types. RefTypes are parametrized by a class name.
38  * Two RefType are equal iff they are parametrized by the same class name as a String.
39  */

40
41 public class RefType extends RefLikeType implements Comparable JavaDoc
42 {
43     public RefType( Singletons.Global g ) { className = ""; }
44     public static RefType v() { return G.v().soot_RefType(); }
45
46     /** the class name that parametrizes this RefType */
47     private final String JavaDoc className;
48     public String JavaDoc getClassName() { return className; }
49     private SootClass sootClass;
50     private AnySubType anySubType;
51
52     private RefType(String JavaDoc className)
53     {
54         if( className.startsWith("[") ) throw new RuntimeException JavaDoc("Attempt to create RefType whose name starts with [");
55         this.className = className;
56     }
57
58     /**
59      * Create a RefType for a class.
60      * @param className The name of the class used to parametrize the created RefType.
61      * @return a RefType for the given class name.
62      */

63     public static RefType v(String JavaDoc className)
64     {
65         RefType ret = Scene.v().getRefType( className );
66         if( ret == null ) {
67             ret = new RefType(className);
68             Scene.v().addRefType( ret );
69         }
70         return ret;
71     }
72
73     public int compareTo(Object JavaDoc o) throws ClassCastException JavaDoc
74     {
75         RefType t = (RefType)o;
76         return this.toString().compareTo(t.toString());
77     }
78         
79     /**
80      * Create a RefType for a class.
81      * @param c A SootClass for which to create a RefType.
82      * @return a RefType for the given SootClass..
83      */

84     public static RefType v(SootClass c)
85     {
86         return v(c.getName());
87     }
88     
89      /**
90       * Get the SootClass object corresponding to this RefType.
91       * @return the corresponding SootClass
92       */

93     public SootClass getSootClass()
94     {
95         if( sootClass == null ) {
96             //System.out.println( "wrning: "+this+" has no sootclass" );
97
sootClass = SootResolver.v().makeClassRef(className);
98         }
99         return sootClass;
100     }
101
102     public boolean hasSootClass() {
103         return sootClass != null;
104     }
105
106      /**
107       * Set the SootClass object corresponding to this RefType.
108       * @param sootClass The SootClass corresponding to this RefType.
109       */

110     public void setSootClass( SootClass sootClass )
111     {
112         this.sootClass = sootClass;
113     }
114
115     /**
116      * 2 RefTypes are considered equal if they are parametrized by the same class name String.
117      * @param t an object to test for equality.
118      * @ return true if t is a RefType parametrized by the same name as this.
119      */

120     public boolean equals(Object JavaDoc t)
121     {
122         return ((t instanceof RefType) && className.equals(((RefType) t).className));
123     }
124
125     public String JavaDoc toString()
126     {
127         return className;
128     }
129
130     public int hashCode()
131     {
132         return className.hashCode();
133     }
134
135     public void apply(Switch sw)
136     {
137         ((TypeSwitch) sw).caseRefType(this);
138     }
139
140
141     /** Returns the least common superclass of this type and other. */
142     public Type merge(Type other, Scene cm)
143     {
144         if(other.equals(UnknownType.v()) || this.equals(other))
145             return this;
146         
147         if(! (other instanceof RefType))
148             throw new RuntimeException JavaDoc("illegal type merge: "
149                                        + this + " and " + other);
150
151
152         {
153             // Return least common superclass
154

155             SootClass thisClass = cm.getSootClass(((RefType) this).className);
156             SootClass otherClass = cm.getSootClass(((RefType) other).className);
157             SootClass javalangObject = cm.getSootClass("java.lang.Object");
158
159             LinkedList thisHierarchy = new LinkedList();
160             LinkedList otherHierarchy = new LinkedList();
161
162             // Build thisHierarchy
163
{
164                 SootClass SootClass = thisClass;
165
166                 for(;;)
167                 {
168                     thisHierarchy.addFirst(SootClass);
169
170                     if(SootClass == javalangObject)
171                         break;
172
173                     SootClass = SootClass.getSuperclass();
174                 }
175             }
176
177             // Build otherHierarchy
178
{
179                 SootClass SootClass = otherClass;
180
181                 for(;;)
182                 {
183                     otherHierarchy.addFirst(SootClass);
184
185                     if(SootClass == javalangObject)
186                         break;
187
188                     SootClass = SootClass.getSuperclass();
189                 }
190             }
191
192             // Find least common superclass
193
{
194                 SootClass commonClass = null;
195
196                 while(!otherHierarchy.isEmpty() && !thisHierarchy.isEmpty() &&
197                     otherHierarchy.getFirst() == thisHierarchy.getFirst())
198                 {
199                     commonClass = (SootClass) otherHierarchy.removeFirst();
200                     thisHierarchy.removeFirst();
201                 }
202
203                 return RefType.v(commonClass.getName());
204             }
205         }
206         
207     }
208
209     public Type getArrayElementType() {
210     if( className.equals( "java.lang.Object" )
211         || className.equals( "java.io.Serializable" )
212         || className.equals( "java.lang.Cloneable" ) ) {
213         return RefType.v( "java.lang.Object" );
214     }
215     throw new RuntimeException JavaDoc( "Attempt to get array base type of a non-array" );
216
217     }
218
219     public AnySubType getAnySubType() { return anySubType; }
220     public void setAnySubType( AnySubType anySubType ) {
221         this.anySubType = anySubType;
222     }
223 }
224
Popular Tags