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