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 data_list;
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;
59 field_table = new Hashtable ();
60 method_table = new Hashtable ();
61 data_list = new ArrayList ();
69 is_value_class = false;
70 is_value_class = false;
77 public string FullName {
78 get { return MakeFullName (); }
81 public TypeDef OuterType {
83 set { outer = value; }
86 public PEAPI.ClassDef PeapiType {
87 get { return classdef; }
90 public PEAPI.ClassDef ClassDef {
91 get { return classdef; }
94 public bool IsGenericType {
95 get { return (typar_list == null); }
98 public bool IsDefined {
99 get { return is_defined; }
102 public EventDef CurrentEvent {
103 get { return current_event; }
106 public PropertyDef CurrentProperty {
107 get { return current_property; }
111 public void AddOverride (MethodDef body, ITypeRef parent, string name)
113 if (override_list == null)
114 override_list = new ArrayList ();
115 override_list.Add (new DictionaryEntry (body,
116 new DictionaryEntry (parent, name)));
119 public void AddOverride (string sig, IMethodRef decl)
121 if (override_long_list == null)
122 override_long_list = new ArrayList ();
123 override_long_list.Add (new DictionaryEntry (sig,
127 public void MakeValueClass ()
129 is_value_class = true;
132 public void MakeEnumClass ()
134 is_enum_class = true;
137 public void SetSize (int size)
142 public void SetPack (int pack)
147 public void AddFieldDef (FieldDef fielddef)
149 field_table.Add (fielddef.Name, fielddef);
152 public void AddDataDef (DataDef datadef)
154 data_list.Add (datadef);
157 public DataDef GetDataDef (string name)
159 foreach (DataDef def in data_list) {
160 if (def.Name == name)
166 public void AddMethodDef (MethodDef methoddef)
168 method_table.Add (methoddef.Signature, methoddef);
171 public void BeginEventDef (EventDef event_def)
173 if (current_event != null)
174 throw new Exception ("An event definition was not closed.");
176 current_event = event_def;
179 public void EndEventDef ()
181 if (event_list == null)
182 event_list = new ArrayList ();
184 event_list.Add (current_event);
185 current_event = null;
188 public void BeginPropertyDef (PropertyDef property_def)
190 if (current_property != null)
191 throw new Exception ("A property definition was not closed.");
193 current_property = property_def;
196 public void EndPropertyDef ()
198 if (property_list == null)
199 property_list = new ArrayList ();
201 property_list.Add (current_property);
202 current_property = null;
205 public void AddCustomAttribute (CustomAttr customattr)
207 if (customattr_list == null)
208 customattr_list = new ArrayList ();
210 customattr_list.Add (customattr);
213 public void AddGenericParam (string id)
215 if (typar_list == null)
216 typar_list = new ArrayList ();
218 GenericInfo gi = new GenericInfo ();
224 public void AddGenericConstraint (int index, ITypeRef constraint)
226 GenericInfo gi = (GenericInfo) typar_list[index];
228 if (gi.ConstraintList == null)
229 gi.ConstraintList = new ArrayList ();
230 gi.ConstraintList.Add (constraint);
233 public void Define (CodeGen code_gen)
239 // Circular definition
240 throw new Exception ("Circular definition of class: " + FullName);
243 if (parent != null) {
245 parent.Resolve (code_gen);
246 is_intransit = false;
247 if (parent.PeapiClass == null) {
248 throw new Exception ("this type can not be a base type: "
252 if (!outer.IsDefined)
253 outer.Define (code_gen);
254 classdef = outer.PeapiType.AddNestedClass (attr,
255 name_space, name, parent.PeapiClass);
257 if (is_value_class) {
258 // Should probably confirm that the parent is System.ValueType
259 classdef = code_gen.PEFile.AddValueClass (attr,
262 classdef = code_gen.PEFile.AddClass (attr,
263 name_space, name, parent.PeapiClass);
268 if (!outer.IsDefined)
269 outer.Define (code_gen);
270 classdef = outer.PeapiType.AddNestedClass (attr,
273 if (is_value_class) {
274 classdef = code_gen.PEFile.AddValueClass (attr,
277 classdef = code_gen.PEFile.AddClass (attr,
281 if (FullName == "System.Object")
282 classdef.SpecialNoSuper ();
286 classdef.AddLayoutInfo (pack, size);
288 if (typar_list != null) {
290 foreach (GenericInfo gi in typar_list) {
291 PEAPI.GenericParameter gp = classdef.AddGenericParameter (index++, gi.Id);
292 if (gi.ConstraintList != null) {
293 foreach (ITypeRef cnst in gi.ConstraintList) {
294 cnst.Resolve (code_gen);
295 gp.AddConstraint (cnst.PeapiType);
301 is_intransit = false;
304 code_gen.AddToDefineContentsList (this);
307 public void DefineContents (CodeGen code_gen)
309 foreach (FieldDef fielddef in field_table.Values) {
310 fielddef.Define (code_gen, classdef);
313 foreach (MethodDef methoddef in method_table.Values) {
314 methoddef.Define (code_gen, classdef);
317 if (event_list != null) {
318 foreach (EventDef eventdef in event_list) {
319 eventdef.Define (code_gen, classdef);
323 if (property_list != null) {
324 foreach (PropertyDef propdef in property_list) {
325 propdef.Define (code_gen, classdef);
330 if (customattr_list != null) {
331 foreach (CustomAttr customattr in customattr_list)
332 customattr.AddTo (code_gen, classdef);
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);
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);
362 public PEAPI.MethodDef ResolveMethod (string signature, CodeGen code_gen)
364 MethodDef methoddef = (MethodDef) method_table[signature];
366 return methoddef.Resolve (code_gen, classdef);
369 public PEAPI.Method ResolveVarargMethod (string signature,
370 CodeGen code_gen, PEAPI.Type[] opt)
372 MethodDef methoddef = (MethodDef) method_table[signature];
373 methoddef.Resolve (code_gen, classdef);
375 return methoddef.GetVarargSig (opt);
378 public PEAPI.Field ResolveField (string name, CodeGen code_gen)
380 FieldDef fielddef = (FieldDef) field_table[name];
382 return fielddef.Resolve (code_gen, classdef);
385 private string MakeFullName ()
387 if (name_space == null || name_space == String.Empty)
390 return name_space + "." + name;