KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > soot > jimple > toolkits > typing > ClassHierarchy


1 /* Soot - a J*va Optimization Framework
2  * Copyright (C) 1997-2000 Etienne Gagnon. All rights reserved.
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 package soot.jimple.toolkits.typing;
28
29 import soot.*;
30 import soot.jimple.*;
31 import soot.util.*;
32 import java.util.*;
33
34 /**
35  * This class encapsulates the typing class hierarchy, as well as non-reference types.
36  *
37  * <P> This class is primarily used by the TypeResolver class, to optimize its computation.
38  **/

39 class ClassHierarchy
40 {
41   /** Map: Scene -> ClassHierarchy **/
42   
43   public final TypeNode OBJECT;
44   public final TypeNode CLONEABLE;
45   public final TypeNode SERIALIZABLE;
46   public final TypeNode NULL;
47   public final TypeNode INT;
48   //public final TypeNode UNKNOWN;
49
//public final TypeNode ERROR;
50

51   /** The class manager **/
52   private final Scene scene;
53   
54   /** All type node instances **/
55   private final List typeNodeList = new ArrayList();
56   
57   /** Map: Type -> TypeNode **/
58   private final HashMap typeNodeMap = new HashMap();
59   
60   /** Used to transform boolean, byte, short and char to int **/
61   private final ToInt transform = new ToInt();
62   
63   /** Used to create TypeNode instances **/
64   private final ConstructorChooser make = new ConstructorChooser();
65   
66   private ClassHierarchy(Scene scene)
67   {
68     if(scene == null)
69       {
70     throw new InternalTypingException();
71       }
72
73     this.scene = scene;
74     G.v().ClassHierarchy_classHierarchyMap.put(scene, this);
75
76     NULL = typeNode(NullType.v());
77     OBJECT = typeNode(RefType.v("java.lang.Object"));
78
79     // hack for J2ME library which does not have Cloneable and Serializable
80
// reported by Stephen Chen
81
if (!G.v().isJ2ME) {
82       CLONEABLE = typeNode(RefType.v("java.lang.Cloneable"));
83       SERIALIZABLE = typeNode(RefType.v("java.io.Serializable"));
84     } else {
85       CLONEABLE = null;
86       SERIALIZABLE = null;
87     }
88
89     INT = typeNode(IntType.v());
90   }
91
92   /** Get the class hierarchy for the given scene. **/
93   public static ClassHierarchy classHierarchy(Scene scene)
94   {
95     if(scene == null)
96       {
97     throw new InternalTypingException();
98       }
99     
100     ClassHierarchy classHierarchy =
101       (ClassHierarchy) G.v().ClassHierarchy_classHierarchyMap.get(scene);
102
103     if(classHierarchy == null)
104       {
105     classHierarchy = new ClassHierarchy(scene);
106       }
107     
108     return classHierarchy;
109   }
110
111   /** Get the type node for the given type. **/
112   public TypeNode typeNode(Type type)
113   {
114     if(type == null)
115       {
116     throw new InternalTypingException();
117       }
118     
119     type = transform.toInt(type);
120     TypeNode typeNode = (TypeNode) typeNodeMap.get(type);
121
122     if(typeNode == null)
123       {
124     int id = typeNodeList.size();
125     typeNodeList.add(null);
126
127     typeNode = make.typeNode(id, type, this);
128
129     typeNodeList.set(id, typeNode);
130     typeNodeMap.put(type, typeNode);
131       }
132
133     return typeNode;
134   }
135
136   /** Returns a string representation of this object **/
137   public String JavaDoc toString ()
138   {
139     StringBuffer JavaDoc s = new StringBuffer JavaDoc();
140     boolean colon = false;
141
142     s.append("ClassHierarchy:{");
143     for(Iterator i = typeNodeList.iterator(); i.hasNext();)
144       {
145     if(colon)
146       {
147         s.append(",");
148       }
149     else
150       {
151         colon = true;
152       }
153
154     s.append(i.next());
155       }
156     s.append("}");
157
158     return s.toString();
159   }
160
161   /**
162    * Transforms boolean, byte, short and char into int.
163    **/

164   private static class ToInt extends TypeSwitch
165   {
166     private Type result;
167     private final Type intType = IntType.v();
168
169     private ToInt()
170     {
171     }
172
173     /** Transform boolean, byte, short and char into int. **/
174     Type toInt(Type type)
175     {
176       type.apply(this);
177       return result;
178     }
179
180     public void caseBooleanType(BooleanType type)
181     {
182       result = intType;
183     }
184
185     public void caseByteType(ByteType type)
186     {
187       result = intType;
188     }
189
190     public void caseShortType(ShortType type)
191     {
192       result = intType;
193     }
194
195     public void caseCharType(CharType type)
196     {
197       result = intType;
198     }
199
200     public void defaultCase(Type type)
201     {
202       result = type;
203     }
204   }
205
206   /**
207    * Creates new TypeNode instances usign the appropriate constructor.
208    **/

209   private static class ConstructorChooser extends TypeSwitch
210   {
211     private int id;
212     private ClassHierarchy hierarchy;
213
214     private TypeNode result;
215     
216     ConstructorChooser()
217     {
218     }
219     
220     /** Create a new TypeNode instance for the type parameter. **/
221     TypeNode typeNode(int id, Type type, ClassHierarchy hierarchy)
222     {
223       if(type == null || hierarchy == null)
224     {
225       throw new InternalTypingException();
226     }
227       
228       this.id = id;
229       this.hierarchy = hierarchy;
230       
231       type.apply(this);
232       
233       return result;
234     }
235
236     public void caseRefType(RefType type)
237     {
238       result = new TypeNode(id, type, hierarchy);
239     }
240
241     public void caseArrayType(ArrayType type)
242     {
243       result = new TypeNode(id, type, hierarchy);
244     }
245
246     public void defaultCase(Type type)
247     {
248       result = new TypeNode(id, type, hierarchy);
249     }
250   }
251 }
252
Popular Tags