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 {
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 Hashtable method_table;
33 private ArrayList customattr_list;
34 private ArrayList event_list;
35 private ArrayList property_list;
36 private ArrayList typar_list;
37 private ArrayList override_list;
38 private ArrayList override_long_list;
39 private TypeDef outer;
41 private EventDef current_event;
42 private PropertyDef current_property;
47 private bool is_value_class;
48 private bool is_enum_class;
50 public TypeDef (PEAPI.TypeAttr attr, string name_space, string name,
51 IClassRef parent, ArrayList impl_list, Location location)
54 this.name_space = name_space;
57 this.impl_list = impl_list;
58 field_table = new Hashtable ();
59 method_table = new Hashtable ();
67 is_value_class = false;
68 is_value_class = false;
75 public string FullName {
76 get { return MakeFullName (); }
79 public TypeDef OuterType {
81 set { outer = value; }
84 public PEAPI.ClassDef PeapiType {
85 get { return classdef; }
88 public PEAPI.ClassDef ClassDef {
89 get { return classdef; }
92 public bool IsGenericType {
93 get { return (typar_list == null); }
96 public bool IsDefined {
97 get { return is_defined; }
100 public EventDef CurrentEvent {
101 get { return current_event; }
104 public PropertyDef CurrentProperty {
105 get { return current_property; }
109 public void AddOverride (MethodDef body, ITypeRef parent, string name)
111 if (override_list == null)
112 override_list = new ArrayList ();
113 override_list.Add (new DictionaryEntry (body,
114 new DictionaryEntry (parent, name)));
117 public void AddOverride (string sig, IMethodRef decl)
119 if (override_long_list == null)
120 override_long_list = new ArrayList ();
121 override_long_list.Add (new DictionaryEntry (sig,
125 public void MakeValueClass ()
127 is_value_class = true;
130 public void MakeEnumClass ()
132 is_enum_class = true;
135 public void SetSize (int size)
140 public void SetPack (int pack)
145 public void AddFieldDef (FieldDef fielddef)
147 field_table.Add (fielddef.Name, fielddef);
150 public void AddMethodDef (MethodDef methoddef)
152 method_table.Add (methoddef.Signature, methoddef);
155 public void BeginEventDef (EventDef event_def)
157 if (current_event != null)
158 throw new Exception ("An event definition was not closed.");
160 current_event = event_def;
163 public void EndEventDef ()
165 if (event_list == null)
166 event_list = new ArrayList ();
168 event_list.Add (current_event);
169 current_event = null;
172 public void BeginPropertyDef (PropertyDef property_def)
174 if (current_property != null)
175 throw new Exception ("A property definition was not closed.");
177 current_property = property_def;
180 public void EndPropertyDef ()
182 if (property_list == null)
183 property_list = new ArrayList ();
185 property_list.Add (current_property);
186 current_property = null;
189 public void AddCustomAttribute (CustomAttr customattr)
191 if (customattr_list == null)
192 customattr_list = new ArrayList ();
194 customattr_list.Add (customattr);
197 public void AddGenericParam (string id)
199 if (typar_list == null)
200 typar_list = new ArrayList ();
202 GenericInfo gi = new GenericInfo ();
208 public void AddGenericConstraint (int index, ITypeRef constraint)
210 GenericInfo gi = (GenericInfo) typar_list[index];
212 if (gi.ConstraintList == null)
213 gi.ConstraintList = new ArrayList ();
214 gi.ConstraintList.Add (constraint);
217 public void Define (CodeGen code_gen)
223 // Circular definition
224 throw new Exception ("Circular definition of class: " + FullName);
227 if (parent != null) {
229 parent.Resolve (code_gen);
230 is_intransit = false;
231 if (parent.PeapiClass == null) {
232 throw new Exception ("this type can not be a base type: "
236 if (!outer.IsDefined)
237 outer.Define (code_gen);
238 classdef = outer.PeapiType.AddNestedClass (attr,
239 name_space, name, parent.PeapiClass);
241 if (is_value_class) {
242 // Should probably confirm that the parent is System.ValueType
243 classdef = code_gen.PEFile.AddValueClass (attr,
246 classdef = code_gen.PEFile.AddClass (attr,
247 name_space, name, parent.PeapiClass);
252 if (!outer.IsDefined)
253 outer.Define (code_gen);
254 classdef = outer.PeapiType.AddNestedClass (attr,
257 if (is_value_class) {
258 classdef = code_gen.PEFile.AddValueClass (attr,
261 classdef = code_gen.PEFile.AddClass (attr,
265 if (FullName == "System.Object")
266 classdef.SpecialNoSuper ();
270 classdef.AddLayoutInfo (pack, size);
272 if (impl_list != null) {
273 foreach (IClassRef impl in impl_list) {
274 impl.Resolve (code_gen);
275 classdef.AddImplementedInterface (impl.PeapiClass);
279 if (typar_list != null) {
281 foreach (GenericInfo gi in typar_list) {
282 PEAPI.GenericParameter gp = classdef.AddGenericParameter (index++, gi.Id);
283 if (gi.ConstraintList != null) {
284 foreach (ITypeRef cnst in gi.ConstraintList) {
285 cnst.Resolve (code_gen);
286 gp.AddConstraint (cnst.PeapiType);
292 is_intransit = false;
295 code_gen.AddToDefineContentsList (this);
298 public void DefineContents (CodeGen code_gen)
300 foreach (FieldDef fielddef in field_table.Values) {
301 fielddef.Define (code_gen, classdef);
304 foreach (MethodDef methoddef in method_table.Values) {
305 methoddef.Define (code_gen, this);
308 if (event_list != null) {
309 foreach (EventDef eventdef in event_list) {
310 eventdef.Define (code_gen, classdef);
314 if (property_list != null) {
315 foreach (PropertyDef propdef in property_list) {
316 propdef.Define (code_gen, classdef);
321 if (customattr_list != null) {
322 foreach (CustomAttr customattr in customattr_list)
323 customattr.AddTo (code_gen, classdef);
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);
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);
353 public PEAPI.MethodDef ResolveMethod (string signature, CodeGen code_gen)
355 MethodDef methoddef = (MethodDef) method_table[signature];
357 if (methoddef == null) {
358 code_gen.Report.Error ("Unable to resolve method: " + signature);
359 Environment.Exit (1);
362 return methoddef.Resolve (code_gen, classdef);
365 public PEAPI.Method ResolveVarargMethod (string signature,
366 CodeGen code_gen, PEAPI.Type[] opt)
368 MethodDef methoddef = (MethodDef) method_table[signature];
370 if (methoddef == null) {
371 code_gen.Report.Error ("Unable to resolve method: " + signature);
372 Environment.Exit (1);
375 methoddef.Resolve (code_gen, classdef);
376 return methoddef.GetVarargSig (opt);
379 public PEAPI.Field ResolveField (string name, CodeGen code_gen)
381 FieldDef fielddef = (FieldDef) field_table[name];
383 return fielddef.Resolve (code_gen, classdef);
386 private string MakeFullName ()
388 if (name_space == null || name_space == String.Empty)
391 return name_space + "." + name;