5 // Jackson Harper (Jackson@LatitudeGeo.com)
7 // (C) 2003 Jackson Harper, All rights reserved
12 using System.Collections;
13 using System.Security;
15 namespace Mono.ILASM {
17 public class TypeDef : ICustomAttrTarget, IDeclSecurityTarget {
19 protected class GenericInfo {
21 public ArrayList ConstraintList;
24 private PEAPI.TypeAttr attr;
25 private string name_space;
27 private bool is_defined;
28 private bool is_intransit;
29 private IClassRef parent;
30 private ArrayList impl_list;
31 private PEAPI.ClassDef classdef;
32 private Hashtable field_table;
33 private ArrayList field_list;
34 private Hashtable method_table;
35 private ArrayList customattr_list;
36 private DeclSecurity decl_sec;
37 private ArrayList event_list;
38 private ArrayList property_list;
39 private ArrayList typar_list;
40 private ArrayList override_list;
41 private ArrayList override_long_list;
42 private TypeDef outer;
44 private EventDef current_event;
45 private PropertyDef current_property;
50 private bool is_value_class;
51 private bool is_enum_class;
53 public TypeDef (PEAPI.TypeAttr attr, string name_space, string name,
54 IClassRef parent, ArrayList impl_list, Location location)
57 this.name_space = name_space;
60 this.impl_list = impl_list;
62 field_table = new Hashtable ();
63 field_list = new ArrayList ();
65 method_table = new Hashtable ();
73 is_value_class = false;
74 is_enum_class = false;
81 public string FullName {
82 get { return MakeFullName (); }
85 public TypeDef OuterType {
87 set { outer = value; }
90 public PEAPI.ClassDef PeapiType {
91 get { return classdef; }
94 public PEAPI.ClassDef ClassDef {
95 get { return classdef; }
98 public bool IsGenericType {
99 get { return (typar_list == null); }
102 public bool IsDefined {
103 get { return is_defined; }
106 public EventDef CurrentEvent {
107 get { return current_event; }
110 public PropertyDef CurrentProperty {
111 get { return current_property; }
114 public bool IsInterface {
115 get { return (attr & PEAPI.TypeAttr.Interface) != 0; }
118 public void AddOverride (MethodDef body, ITypeRef parent, string name)
120 if (override_list == null)
121 override_list = new ArrayList ();
122 override_list.Add (new DictionaryEntry (body,
123 new DictionaryEntry (parent, name)));
126 public void AddOverride (string sig, IMethodRef decl)
128 if (override_long_list == null)
129 override_long_list = new ArrayList ();
130 override_long_list.Add (new DictionaryEntry (sig,
134 public void MakeValueClass ()
136 is_value_class = true;
139 public void MakeEnumClass ()
141 is_enum_class = true;
144 public void SetSize (int size)
149 public void SetPack (int pack)
154 public void AddFieldDef (FieldDef fielddef)
156 if (IsInterface && !fielddef.IsStatic) {
157 Console.WriteLine ("warning -- Non-static field in interface, set to such");
158 fielddef.Attributes |= PEAPI.FieldAttr.Static;
161 field_table.Add (fielddef.Name, fielddef);
162 field_list.Add (fielddef);
165 public void AddMethodDef (MethodDef methoddef)
167 if (IsInterface && !(methoddef.IsVirtual || methoddef.IsAbstract)) {
168 Console.WriteLine ("warning -- Non-virtual, non-abstract instance method in interface, set to such");
169 methoddef.Attributes |= PEAPI.MethAttr.Abstract | PEAPI.MethAttr.Virtual;
172 method_table.Add (methoddef.Signature, methoddef);
175 public void BeginEventDef (EventDef event_def)
177 if (current_event != null)
178 throw new Exception ("An event definition was not closed.");
180 current_event = event_def;
183 public void EndEventDef ()
185 if (event_list == null)
186 event_list = new ArrayList ();
188 event_list.Add (current_event);
189 current_event = null;
192 public void BeginPropertyDef (PropertyDef property_def)
194 if (current_property != null)
195 throw new Exception ("A property definition was not closed.");
197 current_property = property_def;
200 public void EndPropertyDef ()
202 if (property_list == null)
203 property_list = new ArrayList ();
205 property_list.Add (current_property);
206 current_property = null;
209 public void AddCustomAttribute (CustomAttr customattr)
211 if (customattr_list == null)
212 customattr_list = new ArrayList ();
214 customattr_list.Add (customattr);
217 public void AddPermissionSet (PEAPI.SecurityAction sec_action, PermissionSet ps)
219 if (decl_sec == null)
220 decl_sec = new DeclSecurity ();
222 decl_sec.AddPermissionSet (sec_action, ps);
225 public void AddPermission (PEAPI.SecurityAction sec_action, IPermission iper)
227 if (decl_sec == null)
228 decl_sec = new DeclSecurity ();
230 decl_sec.AddPermission (sec_action, iper);
233 public void AddGenericParam (string id)
235 if (typar_list == null)
236 typar_list = new ArrayList ();
238 GenericInfo gi = new GenericInfo ();
244 public void AddGenericConstraint (int index, ITypeRef constraint)
246 GenericInfo gi = (GenericInfo) typar_list[index];
248 if (gi.ConstraintList == null)
249 gi.ConstraintList = new ArrayList ();
250 gi.ConstraintList.Add (constraint);
253 public void Define (CodeGen code_gen)
259 // Circular definition
260 throw new Exception ("Circular definition of class: " + FullName);
263 if (parent != null) {
265 parent.Resolve (code_gen);
266 is_intransit = false;
267 if (parent.PeapiClass == null) {
268 throw new Exception ("this type can not be a base type: "
272 if (parent.PeapiClass.nameSpace != null &&
273 parent.PeapiClass.nameSpace.CompareTo ("System") == 0) {
275 if (parent.PeapiClass.name.CompareTo ("ValueType") == 0)
276 is_value_class = true;
278 if (parent.PeapiClass.name.CompareTo ("Enum") == 0 )
279 is_enum_class = true;
283 if (!outer.IsDefined)
284 outer.Define (code_gen);
285 classdef = outer.PeapiType.AddNestedClass (attr,
286 name_space, name, parent.PeapiClass);
288 if (is_value_class || is_enum_class) {
289 // Should probably confirm that the parent is System.ValueType
290 classdef = code_gen.PEFile.AddValueClass (attr,
291 name_space, name, is_value_class ? PEAPI.ValueClass.ValueType : PEAPI.ValueClass.Enum);
293 classdef = code_gen.PEFile.AddClass (attr,
294 name_space, name, parent.PeapiClass);
299 if (!outer.IsDefined)
300 outer.Define (code_gen);
301 classdef = outer.PeapiType.AddNestedClass (attr,
304 if (is_value_class || is_enum_class) {
305 classdef = code_gen.PEFile.AddValueClass (attr,
306 name_space, name, is_value_class ? PEAPI.ValueClass.ValueType : PEAPI.ValueClass.Enum);
308 classdef = code_gen.PEFile.AddClass (attr,
312 if (FullName == "System.Object")
313 classdef.SpecialNoSuper ();
316 if (size != -1 || pack != -1)
317 classdef.AddLayoutInfo ( (pack == -1) ? 1 : pack, (size == -1) ? 0 : size);
319 if (impl_list != null) {
320 foreach (IClassRef impl in impl_list) {
321 impl.Resolve (code_gen);
322 classdef.AddImplementedInterface (impl.PeapiClass);
326 if (typar_list != null) {
328 foreach (GenericInfo gi in typar_list) {
329 PEAPI.GenericParameter gp = classdef.AddGenericParameter (index++, gi.Id);
330 if (gi.ConstraintList != null) {
331 foreach (ITypeRef cnst in gi.ConstraintList) {
332 cnst.Resolve (code_gen);
333 gp.AddConstraint (cnst.PeapiType);
339 is_intransit = false;
342 code_gen.AddToDefineContentsList (this);
345 public void DefineContents (CodeGen code_gen)
347 ArrayList fielddef_list = new ArrayList ();
348 foreach (FieldDef fielddef in field_list) {
349 fielddef.Define (code_gen, classdef);
350 fielddef_list.Add (fielddef.PeapiFieldDef);
353 classdef.SetFieldOrder (fielddef_list);
355 foreach (MethodDef methoddef in method_table.Values) {
356 methoddef.Define (code_gen, this);
359 if (event_list != null) {
360 foreach (EventDef eventdef in event_list) {
361 eventdef.Define (code_gen, classdef);
365 if (property_list != null) {
366 foreach (PropertyDef propdef in property_list) {
367 propdef.Define (code_gen, classdef);
372 if (customattr_list != null) {
373 foreach (CustomAttr customattr in customattr_list) {
374 customattr.AddTo (code_gen, classdef);
375 if (customattr.IsSuppressUnmanaged (code_gen))
376 classdef.AddAttribute (PEAPI.TypeAttr.HasSecurity);
380 /// Add declarative security to this class
381 if (decl_sec != null) {
382 decl_sec.AddTo (code_gen, classdef);
383 classdef.AddAttribute (PEAPI.TypeAttr.HasSecurity);
386 if (override_list != null) {
387 foreach (DictionaryEntry entry in override_list) {
388 MethodDef body = (MethodDef) entry.Key;
389 DictionaryEntry decl = (DictionaryEntry) entry.Value;
390 ITypeRef parent_type = (ITypeRef) decl.Key;
391 parent_type.Resolve (code_gen);
392 string over_name = (string) decl.Value;
393 IMethodRef over_meth = parent_type.GetMethodRef (body.RetType,
394 body.CallConv, over_name, body.ParamTypeList ());
395 over_meth.Resolve (code_gen);
396 classdef.AddMethodOverride (over_meth.PeapiMethod,
397 body.PeapiMethodDef);
401 if (override_long_list != null) {
402 foreach (DictionaryEntry entry in override_long_list) {
403 string sig = (string) entry.Key;
404 IMethodRef decl = (IMethodRef) entry.Value;
405 MethodDef body = (MethodDef) method_table[sig];
406 decl.Resolve (code_gen);
407 classdef.AddMethodOverride (decl.PeapiMethod,
408 body.PeapiMethodDef);
413 public PEAPI.MethodDef ResolveMethod (string signature, CodeGen code_gen)
415 MethodDef methoddef = (MethodDef) method_table[signature];
417 if (methoddef == null) {
418 code_gen.Report.Error ("Unable to resolve method: " + signature);
419 Environment.Exit (1);
422 return methoddef.Resolve (code_gen, classdef);
425 public PEAPI.Method ResolveVarargMethod (string signature,
426 CodeGen code_gen, PEAPI.Type[] opt)
428 MethodDef methoddef = (MethodDef) method_table[signature];
430 if (methoddef == null) {
431 code_gen.Report.Error ("Unable to resolve method: " + signature);
432 Environment.Exit (1);
435 methoddef.Resolve (code_gen, classdef);
436 return methoddef.GetVarargSig (opt);
439 public PEAPI.Field ResolveField (string name, CodeGen code_gen)
441 FieldDef fielddef = (FieldDef) field_table[name];
443 return fielddef.Resolve (code_gen, classdef);
446 private string MakeFullName ()
448 if (name_space == null || name_space == String.Empty)
451 return name_space + "." + name;