fix for ssJava: realized that annotation should not be a part of hash code.
[IRC.git] / Robust / src / IR / TypeDescriptor.java
1 package IR;
2
3 import java.util.HashSet;
4 import java.util.Set;
5 import java.util.Vector;
6
7 /**
8  * Descriptor
9  *
10  * represents a symbol in the language (var name, function name, etc).
11  */
12
13 public class TypeDescriptor extends Descriptor {
14   public static final int BYTE=1;
15   public static final int SHORT=2;
16   public static final int INT=3;
17   public static final int LONG=4;
18   public static final int CHAR=5;
19   public static final int BOOLEAN=6;
20   public static final int FLOAT=7;
21   public static final int DOUBLE=8;
22   public static final int VOID=9;
23   public static final int NULL=10;
24   public static final int TAG=11;
25   public static final int CLASS=12;
26   public static final int OFFSET=13;
27
28
29   int arraycount;
30   private int type;
31   ClassDescriptor class_desc;
32   boolean isClassNameRef = false;
33   
34   private Vector<AnnotationDescriptor> annotationSet;
35
36   public boolean equals(Object o) {
37     if (o instanceof TypeDescriptor) {
38       TypeDescriptor t=(TypeDescriptor)o;
39       if (t.type!=type)
40         return false;
41       if ((type==CLASS)&&(!t.getSymbol().equals(getSymbol())))
42         return false;
43       if (t.arraycount!=arraycount)
44         return false;
45       if (t.isClassNameRef != this.isClassNameRef)
46         return false;
47       return true;
48     }
49     return false;
50   }
51
52   public boolean isString() {
53     if (type!=CLASS)
54       return false;
55     if (arraycount>0)
56       return false;
57     if (!getSymbol().equals(TypeUtil.StringClass))
58       return false;
59     return true;
60   }
61   
62   public boolean isClassNameRef() {
63     return this.isClassNameRef;
64   }
65   
66   public void setClassNameRef() {
67     this.isClassNameRef = true;
68   }
69
70   public int hashCode() {
71     int hashcode=type^arraycount;
72     if (type==CLASS)
73       hashcode^=getSymbol().hashCode();
74     return hashcode;
75   }
76
77   public boolean iswrapper() {
78     if (arraycount!=0||!isClass())
79       return false;
80     return (name.equals("bytewrapper")||
81             name.equals("booleanwrapper")||
82             name.equals("shortwrapper")||
83             name.equals("intwrapper")||
84             name.equals("longwrapper")||
85             name.equals("charwrapper")||
86             name.equals("floatwrapper")||
87             name.equals("doublewrapper")||
88             name.equals("Objectwrapper"));
89   }
90
91   public TypeDescriptor makeArray(State state) {
92     TypeDescriptor td=new TypeDescriptor(getSymbol());
93     td.arraycount=arraycount+1;
94     td.type=type;
95     td.class_desc=class_desc;
96     state.addArrayType(td);
97     return td;
98   }
99
100   public boolean isArray() {
101     return (arraycount>0);
102   }
103
104   public int getArrayCount() {
105     return arraycount;
106   }
107
108   /* Only use this method if you really know what you are doing.  It
109    * doesn't have the effect you might expect. */
110
111   public void setArrayCount(int a) {
112     arraycount=a;
113   }
114
115   public TypeDescriptor dereference() {
116     TypeDescriptor td=new TypeDescriptor(getSymbol());
117     if (arraycount==0)
118       throw new Error();
119     td.arraycount=arraycount-1;
120     td.type=type;
121     td.class_desc=class_desc;
122     return td;
123   }
124
125   public String getSafeSymbol() {
126     if (isArray())
127       return IR.Flat.BuildCode.arraytype;
128     else if (isClass()) {
129       return class_desc.getSafeSymbol();
130     } else if (isByte())
131       return "char";
132     else if (isChar())
133       return "short";
134     else if (isShort())
135       return "short";
136     else if (isEnum())
137       return "int";
138     else if (isInt())
139       return "int";
140     else if (isBoolean())     //Booleans are ints in C
141       return "int";
142     else if (isLong())
143       return "long long";
144     else if (isVoid())
145       return "void";
146     else if (isDouble())
147       return "double";
148     else if (isFloat())
149       return "float";
150     else if (isOffset())
151       return "short";
152     else 
153       throw new Error("Error Type: "+type);
154   }
155
156   public String getRepairSymbol() {
157     if (isArray())
158       return IR.Flat.BuildCode.arraytype;
159     else if (isClass()) {
160       return class_desc.getSymbol();
161     } else if (isByte())
162       return "byte";
163     else if (isChar())
164       return "short";
165     else if (isShort())
166       return "short";
167     else if (isEnum())
168       return "int";
169     else if (isInt())
170       return "int";
171     else if (isBoolean())     //Booleans are ints in C
172       return "int";
173     else if (isLong())
174       return "long long";
175     else if (isVoid())
176       return "void";
177     else if (isDouble())
178       return "double";
179     else if (isFloat())
180       return "float";
181     else throw new Error("Error Type: "+type);
182   }
183
184   public String getSafeDescriptor() {
185     //Can't safely use [ in C
186     if (isArray())
187       return "_AR_"+this.dereference().getSafeDescriptor();
188     else if (isClass()||isEnum())
189       return class_desc.getSafeDescriptor();
190     else if (isByte())
191       return "B";
192     else if (isChar())
193       return "C";
194     else if (isShort())
195       return "S";
196     else if (isBoolean())
197       return "Z";
198     else if (isInt())
199       return "I";
200     else if (isLong())
201       return "J";
202     else if (isDouble())
203       return "D";
204     else if (isFloat())
205       return "F";
206     else if (isTag())
207       return "T";
208     else throw new Error(toString());
209   }
210
211   public boolean isNumber() {
212     return (isIntegerType()||isFloat()||isDouble());
213   }
214
215   public boolean isByte() {
216     return type==BYTE;
217   }
218   public boolean isNull() {
219     return type==NULL;
220   }
221   public boolean isShort() {
222     return type==SHORT;
223   }
224   public boolean isInt() {
225     return type==INT;
226   }
227   public boolean isLong() {
228     return type==LONG;
229   }
230   public boolean isChar() {
231     return type==CHAR;
232   }
233   public boolean isBoolean() {
234     return type==BOOLEAN;
235   }
236   public boolean isFloat() {
237     return type==FLOAT;
238   }
239   public boolean isDouble() {
240     return type==DOUBLE;
241   }
242   public boolean isVoid() {
243     return type==VOID;
244   }
245
246   public boolean isOffset() {
247     return type==OFFSET;
248   }
249
250   public boolean isPtr() {
251     return (isClass()||isNull()||isTag()||isArray());
252   }
253
254   public boolean isIntegerType() {
255     return (isInt()||isLong()||isShort()||isChar()||isByte()||isEnum());
256   }
257
258   public void setClassDescriptor(ClassDescriptor cd) {
259     class_desc=cd;
260   }
261
262   public boolean isPrimitive() {
263     return (((type>=BYTE)&&(type<=DOUBLE)) || isEnum());
264   }
265
266   public boolean isEnum() {
267     if(this.type != CLASS) {
268       return false;
269     } else if(this.class_desc != null){
270       return this.class_desc.isEnum();
271     }
272     return false;
273   }
274   
275   public boolean isClass() {
276     return (type==CLASS && !isEnum());
277   }
278
279   public boolean isTag() {
280     return type==TAG;
281   }
282
283   public boolean isImmutable() {
284     return isPrimitive() || isString();
285   }
286
287   public TypeDescriptor(NameDescriptor name) {
288     super(name.toString());
289     this.type=CLASS;
290     this.class_desc=null;
291     this.arraycount=0;
292     this.isClassNameRef =false;
293     this.annotationSet=new Vector<AnnotationDescriptor>();
294   }
295
296   public TypeDescriptor(String st) {
297     super(st);
298     this.type=CLASS;
299     this.class_desc=null;
300     this.arraycount=0;
301     this.isClassNameRef =false;
302     this.annotationSet=new Vector<AnnotationDescriptor>();
303   }
304
305   public ClassDescriptor getClassDesc() {
306     return class_desc;
307   }
308
309   public TypeDescriptor(ClassDescriptor cd) {
310     super(cd.getSymbol());
311     this.type=CLASS;
312     this.class_desc=cd;
313     this.arraycount=0;
314     this.isClassNameRef =false;
315     this.annotationSet=new Vector<AnnotationDescriptor>();
316   }
317
318   public TypeDescriptor(int t) {
319     super(decodeInt(t));
320     this.type=t;
321     this.arraycount=0;
322     this.isClassNameRef =false;
323     this.annotationSet=new Vector<AnnotationDescriptor>();
324   }
325
326   public String toString() {
327     if (type==CLASS) {
328       return name;
329     } else
330       return decodeInt(type);
331   }
332
333   public String toPrettyString() {
334     String str=name;
335     if (type!=CLASS) {
336       str=decodeInt(type);
337     }
338     for(int i=0; i<arraycount; i++)
339       str+="[]";
340     return str;    
341   }
342
343   private static String decodeInt(int type) {
344     if (type==BYTE)
345       return "byte";
346     else if (type==BOOLEAN)
347       return "boolean";
348     else if (type==SHORT)
349       return "short";
350     else if (type==INT)
351       return "int";
352     else if (type==LONG)
353       return "long";
354     else if (type==CHAR)
355       return "char";
356     else if (type==FLOAT)
357       return "float";
358     else if (type==DOUBLE)
359       return "double";
360     else if (type==VOID)
361       return "void";
362     else if (type==NULL)
363       return "NULL";
364     else if (type==TAG)
365       return TypeUtil.TagClass;
366     else if (type==OFFSET)
367       return "offset";
368     else throw new Error();
369   }
370   
371   public void addAnnotationMarker(AnnotationDescriptor an){
372     annotationSet.add(an);
373   }
374   
375   public Vector<AnnotationDescriptor> getAnnotationMarkers(){
376     return annotationSet;
377   }
378   
379 }