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 private PEAPI.TypeAttr attr;
19 private string name_space;
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;
38 private EventDef current_event;
39 private PropertyDef current_property;
44 private bool is_value_class;
45 private bool is_enum_class;
47 public TypeDef (PEAPI.TypeAttr attr, string name_space, string name,
48 IClassRef parent, ArrayList impl_list, Location location)
51 this.name_space = name_space;
54 this.impl_list = impl_list;
55 field_table = new Hashtable ();
56 method_table = new Hashtable ();
57 data_list = new ArrayList ();
65 is_value_class = false;
66 is_value_class = false;
73 public string FullName {
74 get { return MakeFullName (); }
77 public TypeDef OuterType {
79 set { outer = value; }
82 public PEAPI.ClassDef PeapiType {
83 get { return classdef; }
86 public PEAPI.ClassDef ClassDef {
87 get { return classdef; }
90 public bool IsGenericType {
91 get { return (typar_list == null); }
94 public bool IsDefined {
95 get { return is_defined; }
98 public EventDef CurrentEvent {
99 get { return current_event; }
102 public PropertyDef CurrentProperty {
103 get { return current_property; }
107 public void AddOverride (MethodDef body, ITypeRef parent, string name)
109 if (override_list == null)
110 override_list = new ArrayList ();
111 override_list.Add (new DictionaryEntry (body,
112 new DictionaryEntry (parent, name)));
115 public void AddOverride (string sig, IMethodRef decl)
117 if (override_long_list == null)
118 override_long_list = new ArrayList ();
119 override_long_list.Add (new DictionaryEntry (sig,
123 public void MakeValueClass ()
125 is_value_class = true;
128 public void MakeEnumClass ()
130 is_enum_class = true;
133 public void SetSize (int size)
138 public void SetPack (int pack)
143 public void AddFieldDef (FieldDef fielddef)
145 field_table.Add (fielddef.Name, fielddef);
148 public void AddDataDef (DataDef datadef)
150 data_list.Add (datadef);
153 public DataDef GetDataDef (string name)
155 foreach (DataDef def in data_list) {
156 if (def.Name == name)
162 public void AddMethodDef (MethodDef methoddef)
164 method_table.Add (methoddef.Signature, methoddef);
167 public void BeginEventDef (EventDef event_def)
169 if (current_event != null)
170 throw new Exception ("An event definition was not closed.");
172 current_event = event_def;
175 public void EndEventDef ()
177 if (event_list == null)
178 event_list = new ArrayList ();
180 event_list.Add (current_event);
181 current_event = null;
184 public void BeginPropertyDef (PropertyDef property_def)
186 if (current_property != null)
187 throw new Exception ("A property definition was not closed.");
189 current_property = property_def;
192 public void EndPropertyDef ()
194 if (property_list == null)
195 property_list = new ArrayList ();
197 property_list.Add (current_property);
198 current_property = null;
201 public void AddCustomAttribute (CustomAttr customattr)
203 if (customattr_list == null)
204 customattr_list = new ArrayList ();
206 customattr_list.Add (customattr);
209 public void AddGenericParam (string id)
211 if (typar_list == null)
212 typar_list = new ArrayList ();
217 public void AddGenericConstraint (int index, ITypeRef constraint)
219 if (constraint_table == null)
220 constraint_table = new Hashtable ();
222 constraint_table.Add (index, constraint);
225 public void Define (CodeGen code_gen)
231 // Circular definition
232 throw new Exception ("Circular definition of class: " + FullName);
235 if (parent != null) {
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: "
244 if (!outer.IsDefined)
245 outer.Define (code_gen);
246 classdef = outer.PeapiType.AddNestedClass (attr,
247 name_space, name, parent.PeapiClass);
249 if (is_value_class) {
250 // Should probably confirm that the parent is System.ValueType
251 classdef = code_gen.PEFile.AddValueClass (attr,
254 classdef = code_gen.PEFile.AddClass (attr,
255 name_space, name, parent.PeapiClass);
260 if (!outer.IsDefined)
261 outer.Define (code_gen);
262 classdef = outer.PeapiType.AddNestedClass (attr,
265 if (is_value_class) {
266 classdef = code_gen.PEFile.AddValueClass (attr,
269 classdef = code_gen.PEFile.AddClass (attr,
273 classdef.SpecialNoSuper ();
277 classdef.AddLayoutInfo (pack, size);
279 if (typar_list != null) {
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);
287 classdef.AddGenericParameter (index++, id);
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, classdef);
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 return methoddef.Resolve (code_gen, classdef);
360 public PEAPI.Method ResolveVarargMethod (string signature,
361 CodeGen code_gen, PEAPI.Type[] opt)
363 MethodDef methoddef = (MethodDef) method_table[signature];
364 methoddef.Resolve (code_gen, classdef);
366 return methoddef.GetVarargSig (opt);
369 public PEAPI.Field ResolveField (string name, CodeGen code_gen)
371 FieldDef fielddef = (FieldDef) field_table[name];
373 return fielddef.Resolve (code_gen, classdef);
376 private string MakeFullName ()
378 if (name_space == null || name_space == String.Empty)
381 return name_space + "." + name;