5 // Jackson Harper (Jackson@LatitudeGeo.com)
7 // (C) 2003 Jackson Harper, All rights reserved
12 using System.Collections;
14 namespace Mono.ILASM {
16 public class TypeDef : ICustomAttrTarget {
18 protected class GenericInfo {
20 public ArrayList ConstraintList;
23 private PEAPI.TypeAttr attr;
24 private string name_space;
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;
42 private EventDef current_event;
43 private PropertyDef current_property;
48 private bool is_value_class;
49 private bool is_enum_class;
51 public TypeDef (PEAPI.TypeAttr attr, string name_space, string name,
52 IClassRef parent, ArrayList impl_list, Location location)
55 this.name_space = name_space;
58 this.impl_list = impl_list;
60 field_table = new Hashtable ();
61 field_list = new ArrayList ();
63 method_table = new Hashtable ();
71 is_value_class = false;
72 is_enum_class = false;
79 public string FullName {
80 get { return MakeFullName (); }
83 public TypeDef OuterType {
85 set { outer = value; }
88 public PEAPI.ClassDef PeapiType {
89 get { return classdef; }
92 public PEAPI.ClassDef ClassDef {
93 get { return classdef; }
96 public bool IsGenericType {
97 get { return (typar_list == null); }
100 public bool IsDefined {
101 get { return is_defined; }
104 public EventDef CurrentEvent {
105 get { return current_event; }
108 public PropertyDef CurrentProperty {
109 get { return current_property; }
112 public bool IsInterface {
113 get { return (attr & PEAPI.TypeAttr.Interface) != 0; }
116 public void AddOverride (MethodDef body, ITypeRef parent, string name)
118 if (override_list == null)
119 override_list = new ArrayList ();
120 override_list.Add (new DictionaryEntry (body,
121 new DictionaryEntry (parent, name)));
124 public void AddOverride (string sig, IMethodRef decl)
126 if (override_long_list == null)
127 override_long_list = new ArrayList ();
128 override_long_list.Add (new DictionaryEntry (sig,
132 public void MakeValueClass ()
134 is_value_class = true;
137 public void MakeEnumClass ()
139 is_enum_class = true;
142 public void SetSize (int size)
147 public void SetPack (int pack)
152 public void AddFieldDef (FieldDef fielddef)
154 if (IsInterface && !fielddef.IsStatic) {
155 Console.WriteLine ("warning -- Non-static field in interface, set to such");
156 fielddef.Attributes |= PEAPI.FieldAttr.Static;
159 field_table.Add (fielddef.Name, fielddef);
160 field_list.Add (fielddef);
163 public void AddMethodDef (MethodDef methoddef)
165 if (IsInterface && !(methoddef.IsVirtual || methoddef.IsAbstract)) {
166 Console.WriteLine ("warning -- Non-virtual, non-abstract instance method in interface, set to such");
167 methoddef.Attributes |= PEAPI.MethAttr.Abstract | PEAPI.MethAttr.Virtual;
170 method_table.Add (methoddef.Signature, methoddef);
173 public void BeginEventDef (EventDef event_def)
175 if (current_event != null)
176 throw new Exception ("An event definition was not closed.");
178 current_event = event_def;
181 public void EndEventDef ()
183 if (event_list == null)
184 event_list = new ArrayList ();
186 event_list.Add (current_event);
187 current_event = null;
190 public void BeginPropertyDef (PropertyDef property_def)
192 if (current_property != null)
193 throw new Exception ("A property definition was not closed.");
195 current_property = property_def;
198 public void EndPropertyDef ()
200 if (property_list == null)
201 property_list = new ArrayList ();
203 property_list.Add (current_property);
204 current_property = null;
207 public void AddCustomAttribute (CustomAttr customattr)
209 if (customattr_list == null)
210 customattr_list = new ArrayList ();
212 customattr_list.Add (customattr);
215 public void AddGenericParam (string id)
217 if (typar_list == null)
218 typar_list = new ArrayList ();
220 GenericInfo gi = new GenericInfo ();
226 public void AddGenericConstraint (int index, ITypeRef constraint)
228 GenericInfo gi = (GenericInfo) typar_list[index];
230 if (gi.ConstraintList == null)
231 gi.ConstraintList = new ArrayList ();
232 gi.ConstraintList.Add (constraint);
235 public void Define (CodeGen code_gen)
241 // Circular definition
242 throw new Exception ("Circular definition of class: " + FullName);
245 if (parent != null) {
247 parent.Resolve (code_gen);
248 is_intransit = false;
249 if (parent.PeapiClass == null) {
250 throw new Exception ("this type can not be a base type: "
254 if (parent.PeapiClass.nameSpace != null &&
255 parent.PeapiClass.nameSpace.CompareTo ("System") == 0) {
257 if (parent.PeapiClass.name.CompareTo ("ValueType") == 0)
258 is_value_class = true;
260 if (parent.PeapiClass.name.CompareTo ("Enum") == 0 )
261 is_enum_class = true;
265 if (!outer.IsDefined)
266 outer.Define (code_gen);
267 classdef = outer.PeapiType.AddNestedClass (attr,
268 name_space, name, parent.PeapiClass);
270 if (is_value_class || is_enum_class) {
271 // Should probably confirm that the parent is System.ValueType
272 classdef = code_gen.PEFile.AddValueClass (attr,
273 name_space, name, is_value_class ? PEAPI.ValueClass.ValueType : PEAPI.ValueClass.Enum);
275 classdef = code_gen.PEFile.AddClass (attr,
276 name_space, name, parent.PeapiClass);
281 if (!outer.IsDefined)
282 outer.Define (code_gen);
283 classdef = outer.PeapiType.AddNestedClass (attr,
286 if (is_value_class || is_enum_class) {
287 classdef = code_gen.PEFile.AddValueClass (attr,
288 name_space, name, is_value_class ? PEAPI.ValueClass.ValueType : PEAPI.ValueClass.Enum);
290 classdef = code_gen.PEFile.AddClass (attr,
294 if (FullName == "System.Object")
295 classdef.SpecialNoSuper ();
299 classdef.AddLayoutInfo (pack, size);
301 if (impl_list != null) {
302 foreach (IClassRef impl in impl_list) {
303 impl.Resolve (code_gen);
304 classdef.AddImplementedInterface (impl.PeapiClass);
308 if (typar_list != null) {
310 foreach (GenericInfo gi in typar_list) {
311 PEAPI.GenericParameter gp = classdef.AddGenericParameter (index++, gi.Id);
312 if (gi.ConstraintList != null) {
313 foreach (ITypeRef cnst in gi.ConstraintList) {
314 cnst.Resolve (code_gen);
315 gp.AddConstraint (cnst.PeapiType);
321 is_intransit = false;
324 code_gen.AddToDefineContentsList (this);
327 public void DefineContents (CodeGen code_gen)
329 ArrayList fielddef_list = new ArrayList ();
330 foreach (FieldDef fielddef in field_list) {
331 fielddef.Define (code_gen, classdef);
332 fielddef_list.Add (fielddef.PeapiFieldDef);
335 classdef.SetFieldOrder (fielddef_list);
337 foreach (MethodDef methoddef in method_table.Values) {
338 methoddef.Define (code_gen, this);
341 if (event_list != null) {
342 foreach (EventDef eventdef in event_list) {
343 eventdef.Define (code_gen, classdef);
347 if (property_list != null) {
348 foreach (PropertyDef propdef in property_list) {
349 propdef.Define (code_gen, classdef);
354 if (customattr_list != null) {
355 foreach (CustomAttr customattr in customattr_list)
356 customattr.AddTo (code_gen, classdef);
359 if (override_list != null) {
360 foreach (DictionaryEntry entry in override_list) {
361 MethodDef body = (MethodDef) entry.Key;
362 DictionaryEntry decl = (DictionaryEntry) entry.Value;
363 ITypeRef parent_type = (ITypeRef) decl.Key;
364 parent_type.Resolve (code_gen);
365 string over_name = (string) decl.Value;
366 IMethodRef over_meth = parent_type.GetMethodRef (body.RetType,
367 body.CallConv, over_name, body.ParamTypeList ());
368 over_meth.Resolve (code_gen);
369 classdef.AddMethodOverride (over_meth.PeapiMethod,
370 body.PeapiMethodDef);
374 if (override_long_list != null) {
375 foreach (DictionaryEntry entry in override_long_list) {
376 string sig = (string) entry.Key;
377 IMethodRef decl = (IMethodRef) entry.Value;
378 MethodDef body = (MethodDef) method_table[sig];
379 decl.Resolve (code_gen);
380 classdef.AddMethodOverride (decl.PeapiMethod,
381 body.PeapiMethodDef);
386 public PEAPI.MethodDef ResolveMethod (string signature, CodeGen code_gen)
388 MethodDef methoddef = (MethodDef) method_table[signature];
390 if (methoddef == null) {
391 code_gen.Report.Error ("Unable to resolve method: " + signature);
392 Environment.Exit (1);
395 return methoddef.Resolve (code_gen, classdef);
398 public PEAPI.Method ResolveVarargMethod (string signature,
399 CodeGen code_gen, PEAPI.Type[] opt)
401 MethodDef methoddef = (MethodDef) method_table[signature];
403 if (methoddef == null) {
404 code_gen.Report.Error ("Unable to resolve method: " + signature);
405 Environment.Exit (1);
408 methoddef.Resolve (code_gen, classdef);
409 return methoddef.GetVarargSig (opt);
412 public PEAPI.Field ResolveField (string name, CodeGen code_gen)
414 FieldDef fielddef = (FieldDef) field_table[name];
416 return fielddef.Resolve (code_gen, classdef);
419 private string MakeFullName ()
421 if (name_space == null || name_space == String.Empty)
424 return name_space + "." + name;