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, IDeclSecurityTarget {
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 declsecurity_list;
36 private ArrayList event_list;
37 private ArrayList property_list;
38 private ArrayList typar_list;
39 private ArrayList override_list;
40 private ArrayList override_long_list;
41 private TypeDef outer;
43 private EventDef current_event;
44 private PropertyDef current_property;
49 private bool is_value_class;
50 private bool is_enum_class;
52 public TypeDef (PEAPI.TypeAttr attr, string name_space, string name,
53 IClassRef parent, ArrayList impl_list, Location location)
56 this.name_space = name_space;
59 this.impl_list = impl_list;
61 field_table = new Hashtable ();
62 field_list = new ArrayList ();
64 method_table = new Hashtable ();
72 is_value_class = false;
73 is_enum_class = false;
80 public string FullName {
81 get { return MakeFullName (); }
84 public TypeDef OuterType {
86 set { outer = value; }
89 public PEAPI.ClassDef PeapiType {
90 get { return classdef; }
93 public PEAPI.ClassDef ClassDef {
94 get { return classdef; }
97 public bool IsGenericType {
98 get { return (typar_list == null); }
101 public bool IsDefined {
102 get { return is_defined; }
105 public EventDef CurrentEvent {
106 get { return current_event; }
109 public PropertyDef CurrentProperty {
110 get { return current_property; }
113 public bool IsInterface {
114 get { return (attr & PEAPI.TypeAttr.Interface) != 0; }
117 public void AddOverride (MethodDef body, ITypeRef parent, string name)
119 if (override_list == null)
120 override_list = new ArrayList ();
121 override_list.Add (new DictionaryEntry (body,
122 new DictionaryEntry (parent, name)));
125 public void AddOverride (string sig, IMethodRef decl)
127 if (override_long_list == null)
128 override_long_list = new ArrayList ();
129 override_long_list.Add (new DictionaryEntry (sig,
133 public void MakeValueClass ()
135 is_value_class = true;
138 public void MakeEnumClass ()
140 is_enum_class = true;
143 public void SetSize (int size)
148 public void SetPack (int pack)
153 public void AddFieldDef (FieldDef fielddef)
155 if (IsInterface && !fielddef.IsStatic) {
156 Console.WriteLine ("warning -- Non-static field in interface, set to such");
157 fielddef.Attributes |= PEAPI.FieldAttr.Static;
160 field_table.Add (fielddef.Name, fielddef);
161 field_list.Add (fielddef);
164 public void AddMethodDef (MethodDef methoddef)
166 if (IsInterface && !(methoddef.IsVirtual || methoddef.IsAbstract)) {
167 Console.WriteLine ("warning -- Non-virtual, non-abstract instance method in interface, set to such");
168 methoddef.Attributes |= PEAPI.MethAttr.Abstract | PEAPI.MethAttr.Virtual;
171 method_table.Add (methoddef.Signature, methoddef);
174 public void BeginEventDef (EventDef event_def)
176 if (current_event != null)
177 throw new Exception ("An event definition was not closed.");
179 current_event = event_def;
182 public void EndEventDef ()
184 if (event_list == null)
185 event_list = new ArrayList ();
187 event_list.Add (current_event);
188 current_event = null;
191 public void BeginPropertyDef (PropertyDef property_def)
193 if (current_property != null)
194 throw new Exception ("A property definition was not closed.");
196 current_property = property_def;
199 public void EndPropertyDef ()
201 if (property_list == null)
202 property_list = new ArrayList ();
204 property_list.Add (current_property);
205 current_property = null;
208 public void AddCustomAttribute (CustomAttr customattr)
210 if (customattr_list == null)
211 customattr_list = new ArrayList ();
213 customattr_list.Add (customattr);
216 public void AddDeclSecurity (DeclSecurity declsecurity)
218 if (declsecurity_list == null)
219 declsecurity_list = new ArrayList ();
221 declsecurity_list.Add (declsecurity);
224 public void AddGenericParam (string id)
226 if (typar_list == null)
227 typar_list = new ArrayList ();
229 GenericInfo gi = new GenericInfo ();
235 public void AddGenericConstraint (int index, ITypeRef constraint)
237 GenericInfo gi = (GenericInfo) typar_list[index];
239 if (gi.ConstraintList == null)
240 gi.ConstraintList = new ArrayList ();
241 gi.ConstraintList.Add (constraint);
244 public void Define (CodeGen code_gen)
250 // Circular definition
251 throw new Exception ("Circular definition of class: " + FullName);
254 if (parent != null) {
256 parent.Resolve (code_gen);
257 is_intransit = false;
258 if (parent.PeapiClass == null) {
259 throw new Exception ("this type can not be a base type: "
263 if (parent.PeapiClass.nameSpace != null &&
264 parent.PeapiClass.nameSpace.CompareTo ("System") == 0) {
266 if (parent.PeapiClass.name.CompareTo ("ValueType") == 0)
267 is_value_class = true;
269 if (parent.PeapiClass.name.CompareTo ("Enum") == 0 )
270 is_enum_class = true;
274 if (!outer.IsDefined)
275 outer.Define (code_gen);
276 classdef = outer.PeapiType.AddNestedClass (attr,
277 name_space, name, parent.PeapiClass);
279 if (is_value_class || is_enum_class) {
280 // Should probably confirm that the parent is System.ValueType
281 classdef = code_gen.PEFile.AddValueClass (attr,
282 name_space, name, is_value_class ? PEAPI.ValueClass.ValueType : PEAPI.ValueClass.Enum);
284 classdef = code_gen.PEFile.AddClass (attr,
285 name_space, name, parent.PeapiClass);
290 if (!outer.IsDefined)
291 outer.Define (code_gen);
292 classdef = outer.PeapiType.AddNestedClass (attr,
295 if (is_value_class || is_enum_class) {
296 classdef = code_gen.PEFile.AddValueClass (attr,
297 name_space, name, is_value_class ? PEAPI.ValueClass.ValueType : PEAPI.ValueClass.Enum);
299 classdef = code_gen.PEFile.AddClass (attr,
303 if (FullName == "System.Object")
304 classdef.SpecialNoSuper ();
307 if (size != -1 || pack != -1)
308 classdef.AddLayoutInfo ( (pack == -1) ? 1 : pack, (size == -1) ? 0 : size);
310 if (impl_list != null) {
311 foreach (IClassRef impl in impl_list) {
312 impl.Resolve (code_gen);
313 classdef.AddImplementedInterface (impl.PeapiClass);
317 if (typar_list != null) {
319 foreach (GenericInfo gi in typar_list) {
320 PEAPI.GenericParameter gp = classdef.AddGenericParameter (index++, gi.Id);
321 if (gi.ConstraintList != null) {
322 foreach (ITypeRef cnst in gi.ConstraintList) {
323 cnst.Resolve (code_gen);
324 gp.AddConstraint (cnst.PeapiType);
330 is_intransit = false;
333 code_gen.AddToDefineContentsList (this);
336 public void DefineContents (CodeGen code_gen)
338 ArrayList fielddef_list = new ArrayList ();
339 foreach (FieldDef fielddef in field_list) {
340 fielddef.Define (code_gen, classdef);
341 fielddef_list.Add (fielddef.PeapiFieldDef);
344 classdef.SetFieldOrder (fielddef_list);
346 foreach (MethodDef methoddef in method_table.Values) {
347 methoddef.Define (code_gen, this);
350 if (event_list != null) {
351 foreach (EventDef eventdef in event_list) {
352 eventdef.Define (code_gen, classdef);
356 if (property_list != null) {
357 foreach (PropertyDef propdef in property_list) {
358 propdef.Define (code_gen, classdef);
363 if (customattr_list != null) {
364 foreach (CustomAttr customattr in customattr_list) {
365 customattr.AddTo (code_gen, classdef);
366 if (customattr.IsSuppressUnmanaged (code_gen))
367 classdef.AddAttribute (PEAPI.TypeAttr.HasSecurity);
371 /// Add declarative security to this method
372 if (declsecurity_list != null) {
373 foreach (DeclSecurity declsecurity in declsecurity_list)
374 declsecurity.AddTo (code_gen, classdef);
376 classdef.AddAttribute (PEAPI.TypeAttr.HasSecurity);
379 if (override_list != null) {
380 foreach (DictionaryEntry entry in override_list) {
381 MethodDef body = (MethodDef) entry.Key;
382 DictionaryEntry decl = (DictionaryEntry) entry.Value;
383 ITypeRef parent_type = (ITypeRef) decl.Key;
384 parent_type.Resolve (code_gen);
385 string over_name = (string) decl.Value;
386 IMethodRef over_meth = parent_type.GetMethodRef (body.RetType,
387 body.CallConv, over_name, body.ParamTypeList ());
388 over_meth.Resolve (code_gen);
389 classdef.AddMethodOverride (over_meth.PeapiMethod,
390 body.PeapiMethodDef);
394 if (override_long_list != null) {
395 foreach (DictionaryEntry entry in override_long_list) {
396 string sig = (string) entry.Key;
397 IMethodRef decl = (IMethodRef) entry.Value;
398 MethodDef body = (MethodDef) method_table[sig];
399 decl.Resolve (code_gen);
400 classdef.AddMethodOverride (decl.PeapiMethod,
401 body.PeapiMethodDef);
406 public PEAPI.MethodDef ResolveMethod (string signature, CodeGen code_gen)
408 MethodDef methoddef = (MethodDef) method_table[signature];
410 if (methoddef == null) {
411 code_gen.Report.Error ("Unable to resolve method: " + signature);
412 Environment.Exit (1);
415 return methoddef.Resolve (code_gen, classdef);
418 public PEAPI.Method ResolveVarargMethod (string signature,
419 CodeGen code_gen, PEAPI.Type[] opt)
421 MethodDef methoddef = (MethodDef) method_table[signature];
423 if (methoddef == null) {
424 code_gen.Report.Error ("Unable to resolve method: " + signature);
425 Environment.Exit (1);
428 methoddef.Resolve (code_gen, classdef);
429 return methoddef.GetVarargSig (opt);
432 public PEAPI.Field ResolveField (string name, CodeGen code_gen)
434 FieldDef fielddef = (FieldDef) field_table[name];
436 return fielddef.Resolve (code_gen, classdef);
439 private string MakeFullName ()
441 if (name_space == null || name_space == String.Empty)
444 return name_space + "." + name;