* DataDef.cs: Make name public so data names can be looked up
[mono.git] / mcs / ilasm / codegen / TypeDef.cs
1 //
2 // Mono.ILASM.TypeDef
3 //
4 // Author(s):
5 //  Jackson Harper (Jackson@LatitudeGeo.com)
6 //
7 // (C) 2003 Jackson Harper, All rights reserved
8 //
9
10
11 using System;
12 using System.Collections;
13
14 namespace Mono.ILASM {
15
16         public class TypeDef {
17
18                 private PEAPI.TypeAttr attr;
19                 private string name_space;
20                 private string name;
21                 private bool is_defined;
22                 private bool is_intransit;
23                 private IClassRef parent;
24                 private ArrayList impl_list;
25                 private PEAPI.ClassDef classdef;
26                 private Hashtable field_table;
27                 private Hashtable method_table;
28                 private ArrayList data_list;
29                 private ArrayList customattr_list;
30                 private ArrayList event_list;
31                 private ArrayList property_list;
32                 private ArrayList typar_list;
33                 private ArrayList override_list;
34                 private ArrayList override_long_list;
35                 private Hashtable constraint_table;
36                 private TypeDef outer;
37
38                 private EventDef current_event;
39                 private PropertyDef current_property;
40
41                 private int size;
42                 private int pack;
43
44                 private bool is_value_class;
45                 private bool is_enum_class;
46
47                 public TypeDef (PEAPI.TypeAttr attr, string name_space, string name,
48                                 IClassRef parent, ArrayList impl_list, Location location)
49                 {
50                         this.attr = attr;
51                         this.name_space = name_space;
52                         this.name = name;
53                         this.parent = parent;
54                         this.impl_list = impl_list;
55                         field_table = new Hashtable ();
56                         method_table = new Hashtable ();
57                         data_list = new ArrayList ();
58
59                         size = -1;
60                         pack = -1;
61
62                         is_defined = false;
63                         is_intransit = false;
64
65                         is_value_class = false;
66                         is_value_class = false;
67                 }
68
69                 public string Name {
70                         get { return name; }
71                 }
72
73                 public string FullName {
74                         get { return MakeFullName (); }
75                 }
76
77                 public TypeDef OuterType {
78                         get { return outer; }
79                         set { outer = value; }
80                 }
81
82                 public PEAPI.ClassDef PeapiType {
83                         get { return classdef; }
84                 }
85
86                 public PEAPI.ClassDef ClassDef {
87                         get { return classdef; }
88                 }
89
90                 public bool IsGenericType {
91                         get { return (typar_list == null); }
92                 }
93
94                 public bool IsDefined {
95                         get { return is_defined; }
96                 }
97
98                 public EventDef CurrentEvent {
99                         get { return current_event; }
100                 }
101
102                 public PropertyDef CurrentProperty {
103                         get { return current_property; }
104                 }
105
106
107                 public void AddOverride (MethodDef body, ITypeRef parent, string name)
108                 {
109                         if (override_list == null)
110                                 override_list = new ArrayList ();
111                         override_list.Add (new DictionaryEntry (body,
112                                            new DictionaryEntry (parent, name)));
113                 }
114
115                 public void AddOverride (string sig, IMethodRef decl)
116                 {
117                         if (override_long_list == null)
118                                 override_long_list = new ArrayList ();
119                         override_long_list.Add (new DictionaryEntry (sig,
120                                                                 decl));
121                 }
122
123                 public void MakeValueClass ()
124                 {
125                         is_value_class = true;
126                 }
127
128                 public void MakeEnumClass ()
129                 {
130                         is_enum_class = true;
131                 }
132
133                 public void SetSize (int size)
134                 {
135                         this.size = size;
136                 }
137
138                 public void SetPack (int pack)
139                 {
140                         this.pack = pack;
141                 }
142
143                 public void AddFieldDef (FieldDef fielddef)
144                 {
145                         field_table.Add (fielddef.Name, fielddef);
146                 }
147
148                 public void AddDataDef (DataDef datadef)
149                 {
150                         data_list.Add (datadef);
151                 }
152
153                 public DataDef GetDataDef (string name)
154                 {
155                         foreach (DataDef def in data_list) {
156                                 if (def.Name == name)
157                                         return def;
158                         }
159                         return null;
160                 }
161
162                 public void AddMethodDef (MethodDef methoddef)
163                 {
164                         method_table.Add (methoddef.Signature, methoddef);
165                 }
166
167                 public void BeginEventDef (EventDef event_def)
168                 {
169                         if (current_event != null)
170                                 throw new Exception ("An event definition was not closed.");
171
172                         current_event = event_def;
173                 }
174
175                 public void EndEventDef ()
176                 {
177                         if (event_list == null)
178                                 event_list = new ArrayList ();
179
180                         event_list.Add (current_event);
181                         current_event = null;
182                 }
183
184                 public void BeginPropertyDef (PropertyDef property_def)
185                 {
186                         if (current_property != null)
187                                 throw new Exception ("A property definition was not closed.");
188
189                         current_property = property_def;
190                 }
191
192                 public void EndPropertyDef ()
193                 {
194                         if (property_list == null)
195                                 property_list = new ArrayList ();
196
197                         property_list.Add (current_property);
198                         current_property = null;
199                 }
200
201                 public void AddCustomAttribute (CustomAttr customattr)
202                 {
203                         if (customattr_list == null)
204                                 customattr_list = new ArrayList ();
205
206                         customattr_list.Add (customattr);
207                 }
208
209                 public void AddGenericParam (string id)
210                 {
211                         if (typar_list == null)
212                                 typar_list = new ArrayList ();
213
214                         typar_list.Add (id);
215                 }
216
217                 public void AddGenericConstraint (int index, ITypeRef constraint)
218                 {
219                         if (constraint_table == null)
220                                 constraint_table = new Hashtable ();
221
222                         constraint_table.Add (index, constraint);
223                 }
224
225                 public void Define (CodeGen code_gen)
226                 {
227                         if (is_defined)
228                                 return;
229
230                         if (is_intransit) {
231                                 // Circular definition
232                                 throw new Exception ("Circular definition of class: " + FullName);
233                         }
234
235                         if (parent != null) {
236                                 is_intransit = true;
237                                 parent.Resolve (code_gen);
238                                 is_intransit = false;
239                                 if (parent.PeapiClass == null) {
240                                         throw new Exception ("this type can not be a base type: "
241                                                         + parent);
242                                 }
243                                 if (outer != null) {
244                                         if (!outer.IsDefined)
245                                                 outer.Define (code_gen);
246                                         classdef = outer.PeapiType.AddNestedClass (attr,
247                                                         name_space, name, parent.PeapiClass);
248                                 } else {
249                                         if (is_value_class) {
250                                                 // Should probably confirm that the parent is System.ValueType
251                                                 classdef = code_gen.PEFile.AddValueClass (attr,
252                                                         name_space, name);
253                                         } else {
254                                                 classdef = code_gen.PEFile.AddClass (attr,
255                                                         name_space, name, parent.PeapiClass);
256                                         }
257                                 }
258                         } else {
259                                 if (outer != null) {
260                                         if (!outer.IsDefined)
261                                                 outer.Define (code_gen);
262                                         classdef = outer.PeapiType.AddNestedClass (attr,
263                                                 name_space, name);
264                                 } else {
265                                         if (is_value_class) {
266                                                 classdef = code_gen.PEFile.AddValueClass (attr,
267                                                         name_space, name);
268                                         } else {
269                                                 classdef = code_gen.PEFile.AddClass (attr,
270                                                         name_space, name);
271                                         }
272                                 }
273                                 classdef.SpecialNoSuper ();
274                         }
275
276                         if (size != -1)
277                                 classdef.AddLayoutInfo (pack, size);
278
279                         if (typar_list != null) {
280                                 short index = 0;
281                                 foreach (string id in typar_list) {
282                                         if (constraint_table != null && constraint_table.Contains ((int) index)) {
283                                                 ITypeRef constraint = (ITypeRef) constraint_table[(int) index];
284                                                 constraint.Resolve (code_gen);
285                                                 classdef.AddGenericParameter (index++, id, constraint.PeapiType);
286                                         } else {
287                                                 classdef.AddGenericParameter (index++, id);
288                                         }
289                                 }
290                         }
291
292                         is_intransit = false;
293                         is_defined = true;
294
295                         code_gen.AddToDefineContentsList (this);
296                 }
297
298                 public void DefineContents (CodeGen code_gen)
299                 {
300                         foreach (FieldDef fielddef in field_table.Values) {
301                                 fielddef.Define (code_gen, classdef);
302                         }
303
304                         foreach (MethodDef methoddef in method_table.Values) {
305                                 methoddef.Define (code_gen, classdef);
306                         }
307
308                         if (event_list != null) {
309                                 foreach (EventDef eventdef in event_list) {
310                                         eventdef.Define (code_gen, classdef);
311                                 }
312                         }
313
314                         if (property_list != null) {
315                                 foreach (PropertyDef propdef in property_list) {
316                                         propdef.Define (code_gen, classdef);
317                                 }
318
319                         }
320
321                         if (customattr_list != null) {
322                                 foreach (CustomAttr customattr in customattr_list)
323                                         customattr.AddTo (code_gen, classdef);
324                         }
325
326                         if (override_list != null) {
327                                 foreach (DictionaryEntry entry in override_list) {
328                                         MethodDef body = (MethodDef) entry.Key;
329                                         DictionaryEntry decl = (DictionaryEntry) entry.Value;
330                                         ITypeRef parent_type = (ITypeRef) decl.Key;
331                                         parent_type.Resolve (code_gen);
332                                         string over_name = (string) decl.Value;
333                                         IMethodRef over_meth = parent_type.GetMethodRef (body.RetType,
334                                                         body.CallConv, over_name, body.ParamTypeList ());
335                                         over_meth.Resolve (code_gen);
336                                         classdef.AddMethodOverride (over_meth.PeapiMethod,
337                                                         body.PeapiMethodDef);
338                                 }
339                         }
340
341                         if (override_long_list != null) {
342                                 foreach (DictionaryEntry entry in override_long_list) {
343                                         string sig = (string) entry.Key;
344                                         IMethodRef decl = (IMethodRef) entry.Value;
345                                         MethodDef body = (MethodDef) method_table[sig];
346                                         decl.Resolve (code_gen);
347                                         classdef.AddMethodOverride (decl.PeapiMethod,
348                                                         body.PeapiMethodDef);
349                                 }
350                         }
351                 }
352
353                 public PEAPI.MethodDef ResolveMethod (string signature, CodeGen code_gen)
354                 {
355                         MethodDef methoddef = (MethodDef) method_table[signature];
356
357                         return methoddef.Resolve (code_gen, classdef);
358                 }
359
360                 public PEAPI.Method ResolveVarargMethod (string signature,
361                                 CodeGen code_gen, PEAPI.Type[] opt)
362                 {
363                         MethodDef methoddef = (MethodDef) method_table[signature];
364                         methoddef.Resolve (code_gen, classdef);
365
366                         return methoddef.GetVarargSig (opt);
367                 }
368
369                 public PEAPI.Field ResolveField (string name, CodeGen code_gen)
370                 {
371                         FieldDef fielddef = (FieldDef) field_table[name];
372
373                         return fielddef.Resolve (code_gen, classdef);
374                 }
375
376                 private string MakeFullName ()
377                 {
378                         if (name_space == null || name_space == String.Empty)
379                                 return name;
380
381                         return name_space + "." + name;
382                 }
383         }
384
385 }
386