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 ArrayList field_list
;
33 private Hashtable method_table
;
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
;
60 field_table
= new Hashtable ();
61 field_list
= new ArrayList ();
63 method_table
= new Hashtable ();
71 is_value_class
= false;
72 is_value_class
= false;
79 public string FullName
{
80 get { return MakeFullName (); }
83 public TypeDef OuterType
{
85 set { outer = value; }
88 public PEAPI
.ClassDef PeapiType
{
89 get { return classdef; }
92 public PEAPI
.ClassDef ClassDef
{
93 get { return classdef; }
96 public bool IsGenericType
{
97 get { return (typar_list == null); }
100 public bool IsDefined
{
101 get { return is_defined; }
104 public EventDef CurrentEvent
{
105 get { return current_event; }
108 public PropertyDef CurrentProperty
{
109 get { return current_property; }
113 public void AddOverride (MethodDef body
, ITypeRef parent
, string name
)
115 if (override_list
== null)
116 override_list
= new ArrayList ();
117 override_list
.Add (new DictionaryEntry (body
,
118 new DictionaryEntry (parent
, name
)));
121 public void AddOverride (string sig
, IMethodRef decl
)
123 if (override_long_list
== null)
124 override_long_list
= new ArrayList ();
125 override_long_list
.Add (new DictionaryEntry (sig
,
129 public void MakeValueClass ()
131 is_value_class
= true;
134 public void MakeEnumClass ()
136 is_enum_class
= true;
139 public void SetSize (int size
)
144 public void SetPack (int pack
)
149 public void AddFieldDef (FieldDef fielddef
)
151 field_table
.Add (fielddef
.Name
, fielddef
);
152 field_list
.Add (fielddef
);
155 public void AddMethodDef (MethodDef methoddef
)
157 method_table
.Add (methoddef
.Signature
, methoddef
);
160 public void BeginEventDef (EventDef event_def
)
162 if (current_event
!= null)
163 throw new Exception ("An event definition was not closed.");
165 current_event
= event_def
;
168 public void EndEventDef ()
170 if (event_list
== null)
171 event_list
= new ArrayList ();
173 event_list
.Add (current_event
);
174 current_event
= null;
177 public void BeginPropertyDef (PropertyDef property_def
)
179 if (current_property
!= null)
180 throw new Exception ("A property definition was not closed.");
182 current_property
= property_def
;
185 public void EndPropertyDef ()
187 if (property_list
== null)
188 property_list
= new ArrayList ();
190 property_list
.Add (current_property
);
191 current_property
= null;
194 public void AddCustomAttribute (CustomAttr customattr
)
196 if (customattr_list
== null)
197 customattr_list
= new ArrayList ();
199 customattr_list
.Add (customattr
);
202 public void AddGenericParam (string id
)
204 if (typar_list
== null)
205 typar_list
= new ArrayList ();
207 GenericInfo gi
= new GenericInfo ();
213 public void AddGenericConstraint (int index
, ITypeRef constraint
)
215 GenericInfo gi
= (GenericInfo
) typar_list
[index
];
217 if (gi
.ConstraintList
== null)
218 gi
.ConstraintList
= new ArrayList ();
219 gi
.ConstraintList
.Add (constraint
);
222 public void Define (CodeGen code_gen
)
228 // Circular definition
229 throw new Exception ("Circular definition of class: " + FullName
);
232 if (parent
!= null) {
234 parent
.Resolve (code_gen
);
235 is_intransit
= false;
236 if (parent
.PeapiClass
== null) {
237 throw new Exception ("this type can not be a base type: "
241 if (!outer
.IsDefined
)
242 outer
.Define (code_gen
);
243 classdef
= outer
.PeapiType
.AddNestedClass (attr
,
244 name_space
, name
, parent
.PeapiClass
);
246 if (is_value_class
) {
247 // Should probably confirm that the parent is System.ValueType
248 classdef
= code_gen
.PEFile
.AddValueClass (attr
,
251 classdef
= code_gen
.PEFile
.AddClass (attr
,
252 name_space
, name
, parent
.PeapiClass
);
257 if (!outer
.IsDefined
)
258 outer
.Define (code_gen
);
259 classdef
= outer
.PeapiType
.AddNestedClass (attr
,
262 if (is_value_class
) {
263 classdef
= code_gen
.PEFile
.AddValueClass (attr
,
266 classdef
= code_gen
.PEFile
.AddClass (attr
,
270 if (FullName
== "System.Object")
271 classdef
.SpecialNoSuper ();
275 classdef
.AddLayoutInfo (pack
, size
);
277 if (impl_list
!= null) {
278 foreach (IClassRef impl
in impl_list
) {
279 impl
.Resolve (code_gen
);
280 classdef
.AddImplementedInterface (impl
.PeapiClass
);
284 if (typar_list
!= null) {
286 foreach (GenericInfo gi
in typar_list
) {
287 PEAPI
.GenericParameter gp
= classdef
.AddGenericParameter (index
++, gi
.Id
);
288 if (gi
.ConstraintList
!= null) {
289 foreach (ITypeRef cnst
in gi
.ConstraintList
) {
290 cnst
.Resolve (code_gen
);
291 gp
.AddConstraint (cnst
.PeapiType
);
297 is_intransit
= false;
300 code_gen
.AddToDefineContentsList (this);
303 public void DefineContents (CodeGen code_gen
)
305 ArrayList fielddef_list
= new ArrayList ();
306 foreach (FieldDef fielddef
in field_list
) {
307 fielddef
.Define (code_gen
, classdef
);
308 fielddef_list
.Add (fielddef
.PeapiFieldDef
);
311 classdef
.SetFieldOrder (fielddef_list
);
313 foreach (MethodDef methoddef
in method_table
.Values
) {
314 methoddef
.Define (code_gen
, this);
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 if (methoddef
== null) {
367 code_gen
.Report
.Error ("Unable to resolve method: " + signature
);
368 Environment
.Exit (1);
371 return methoddef
.Resolve (code_gen
, classdef
);
374 public PEAPI
.Method
ResolveVarargMethod (string signature
,
375 CodeGen code_gen
, PEAPI
.Type
[] opt
)
377 MethodDef methoddef
= (MethodDef
) method_table
[signature
];
379 if (methoddef
== null) {
380 code_gen
.Report
.Error ("Unable to resolve method: " + signature
);
381 Environment
.Exit (1);
384 methoddef
.Resolve (code_gen
, classdef
);
385 return methoddef
.GetVarargSig (opt
);
388 public PEAPI
.Field
ResolveField (string name
, CodeGen code_gen
)
390 FieldDef fielddef
= (FieldDef
) field_table
[name
];
392 return fielddef
.Resolve (code_gen
, classdef
);
395 private string MakeFullName ()
397 if (name_space
== null || name_space
== String
.Empty
)
400 return name_space
+ "." + name
;