* MethodDef.cs: Report when defining methods just like MS.
[mono.git] / mcs / ilasm / codegen / TypeDef.cs
index 04bf6e7a63ed764fa2b2ab01fab036aae2cfbb69..2aee3ebd80ae915c71fa40505ff70a9987fef852 100644 (file)
@@ -15,17 +15,37 @@ namespace Mono.ILASM {
 
         public class TypeDef {
 
+                protected class GenericInfo {
+                        public string Id;
+                        public ArrayList ConstraintList;
+                }
+
                 private PEAPI.TypeAttr attr;
                 private string name_space;
                 private string name;
-                private bool is_resolved;
+                private bool is_defined;
                 private bool is_intransit;
                 private IClassRef parent;
                 private ArrayList impl_list;
                 private PEAPI.ClassDef classdef;
-                private ArrayList field_list;
-                private ArrayList method_list;
-                private ArrayList data_list;
+                private Hashtable field_table;
+                private Hashtable method_table;
+                private ArrayList customattr_list;
+                private ArrayList event_list;
+                private ArrayList property_list;
+                private ArrayList typar_list;
+                private ArrayList override_list;
+                private ArrayList override_long_list;
+                private TypeDef outer;
+
+                private EventDef current_event;
+                private PropertyDef current_property;
+
+                private int size;
+                private int pack;
+
+                private bool is_value_class;
+                private bool is_enum_class;
 
                 public TypeDef (PEAPI.TypeAttr attr, string name_space, string name,
                                 IClassRef parent, ArrayList impl_list, Location location)
@@ -35,15 +55,32 @@ namespace Mono.ILASM {
                         this.name = name;
                         this.parent = parent;
                         this.impl_list = impl_list;
-                        field_list = new ArrayList ();
-                        method_list = new ArrayList ();
-                        data_list = new ArrayList ();
+                        field_table = new Hashtable ();
+                        method_table = new Hashtable ();
+
+                        size = -1;
+                        pack = -1;
+
+                        is_defined = false;
+                        is_intransit = false;
+
+                        is_value_class = false;
+                        is_value_class = false;
+                }
+
+                public string Name {
+                        get { return name; }
                 }
 
                 public string FullName {
                         get { return MakeFullName (); }
                 }
 
+                public TypeDef OuterType {
+                        get { return outer; }
+                        set { outer = value; }
+                }
+
                 public PEAPI.ClassDef PeapiType {
                         get { return classdef; }
                 }
@@ -52,60 +89,298 @@ namespace Mono.ILASM {
                         get { return classdef; }
                 }
 
-                public bool IsResolved {
-                        get { return is_resolved; }
+                public bool IsGenericType {
+                        get { return (typar_list == null); }
                 }
 
-                public void AddFieldDef (FieldDef fielddef)
+                public bool IsDefined {
+                        get { return is_defined; }
+                }
+
+                public EventDef CurrentEvent {
+                        get { return current_event; }
+                }
+
+                public PropertyDef CurrentProperty {
+                        get { return current_property; }
+                }
+
+
+                public void AddOverride (MethodDef body, ITypeRef parent, string name)
                 {
-                        field_list.Add (fielddef);
+                        if (override_list == null)
+                                override_list = new ArrayList ();
+                        override_list.Add (new DictionaryEntry (body,
+                                           new DictionaryEntry (parent, name)));
                 }
 
-                public void AddDataDef (DataDef datadef)
+                public void AddOverride (string sig, IMethodRef decl)
                 {
-                        data_list.Add (datadef);
+                        if (override_long_list == null)
+                                override_long_list = new ArrayList ();
+                        override_long_list.Add (new DictionaryEntry (sig,
+                                                                decl));
+                }
+
+                public void MakeValueClass ()
+                {
+                        is_value_class = true;
+                }
+
+                public void MakeEnumClass ()
+                {
+                        is_enum_class = true;
+                }
+
+                public void SetSize (int size)
+                {
+                        this.size = size;
+                }
+
+                public void SetPack (int pack)
+                {
+                        this.pack = pack;
+                }
+
+                public void AddFieldDef (FieldDef fielddef)
+                {
+                        field_table.Add (fielddef.Name, fielddef);
                 }
 
                 public void AddMethodDef (MethodDef methoddef)
                 {
-                        method_list.Add (methoddef);
+                        method_table.Add (methoddef.Signature, methoddef);
+                }
+
+                public void BeginEventDef (EventDef event_def)
+                {
+                        if (current_event != null)
+                                throw new Exception ("An event definition was not closed.");
+
+                        current_event = event_def;
+                }
+
+                public void EndEventDef ()
+                {
+                        if (event_list == null)
+                                event_list = new ArrayList ();
+
+                        event_list.Add (current_event);
+                        current_event = null;
+                }
+
+                public void BeginPropertyDef (PropertyDef property_def)
+                {
+                        if (current_property != null)
+                                throw new Exception ("A property definition was not closed.");
+
+                        current_property = property_def;
+                }
+
+                public void EndPropertyDef ()
+                {
+                        if (property_list == null)
+                                property_list = new ArrayList ();
+
+                        property_list.Add (current_property);
+                        current_property = null;
+                }
+
+                public void AddCustomAttribute (CustomAttr customattr)
+                {
+                        if (customattr_list == null)
+                                customattr_list = new ArrayList ();
+
+                        customattr_list.Add (customattr);
+                }
+
+                public void AddGenericParam (string id)
+                {
+                        if (typar_list == null)
+                                typar_list = new ArrayList ();
+
+                        GenericInfo gi = new GenericInfo ();
+                        gi.Id = id;
+
+                        typar_list.Add (gi);
+                }
+
+                public void AddGenericConstraint (int index, ITypeRef constraint)
+                {
+                        GenericInfo gi = (GenericInfo) typar_list[index];
+
+                        if (gi.ConstraintList == null)
+                                gi.ConstraintList = new ArrayList ();
+                        gi.ConstraintList.Add (constraint);
                 }
 
                 public void Define (CodeGen code_gen)
                 {
-                        if (is_resolved)
+                        if (is_defined)
                                 return;
 
                         if (is_intransit) {
                                 // Circular definition
-                                throw new Exception ("Circular definition of class: " + this);
+                                throw new Exception ("Circular definition of class: " + FullName);
                         }
 
-                        is_intransit = true;
-
                         if (parent != null) {
+                                is_intransit = true;
                                 parent.Resolve (code_gen);
+                                is_intransit = false;
                                 if (parent.PeapiClass == null) {
                                         throw new Exception ("this type can not be a base type: "
                                                         + parent);
                                 }
-                                classdef = code_gen.PEFile.AddClass (attr,
-                                                name_space, name, parent.PeapiClass);
+                                if (outer != null) {
+                                        if (!outer.IsDefined)
+                                                outer.Define (code_gen);
+                                        classdef = outer.PeapiType.AddNestedClass (attr,
+                                                        name_space, name, parent.PeapiClass);
+                                } else {
+                                        if (is_value_class) {
+                                                // Should probably confirm that the parent is System.ValueType
+                                                classdef = code_gen.PEFile.AddValueClass (attr,
+                                                        name_space, name);
+                                        } else {
+                                                classdef = code_gen.PEFile.AddClass (attr,
+                                                        name_space, name, parent.PeapiClass);
+                                        }
+                                }
                         } else {
-                                classdef = code_gen.PEFile.AddClass (attr,
+                                if (outer != null) {
+                                        if (!outer.IsDefined)
+                                                outer.Define (code_gen);
+                                        classdef = outer.PeapiType.AddNestedClass (attr,
                                                 name_space, name);
+                                } else {
+                                        if (is_value_class) {
+                                                classdef = code_gen.PEFile.AddValueClass (attr,
+                                                        name_space, name);
+                                        } else {
+                                                classdef = code_gen.PEFile.AddClass (attr,
+                                                        name_space, name);
+                                        }
+                                }
+                                if (FullName == "System.Object")
+                                        classdef.SpecialNoSuper ();
+                        }
+
+                        if (size != -1)
+                                classdef.AddLayoutInfo (pack, size);
+
+                        if (impl_list != null) {
+                                foreach (IClassRef impl in impl_list) {
+                                        impl.Resolve (code_gen);
+                                        classdef.AddImplementedInterface (impl.PeapiClass);
+                                }
+                        }
+
+                        if (typar_list != null) {
+                                short index = 0;
+                                foreach (GenericInfo gi in typar_list) {
+                                        PEAPI.GenericParameter gp = classdef.AddGenericParameter (index++, gi.Id);
+                                        if (gi.ConstraintList != null) {
+                                                foreach (ITypeRef cnst in gi.ConstraintList) {
+                                                        cnst.Resolve (code_gen);
+                                                        gp.AddConstraint (cnst.PeapiType);
+                                                }
+                                        }
+                                }
                         }
 
                         is_intransit = false;
+                        is_defined = true;
 
-                        foreach (FieldDef fielddef in field_list) {
+                        code_gen.AddToDefineContentsList (this);
+                }
+
+                public void DefineContents (CodeGen code_gen)
+                {
+                        foreach (FieldDef fielddef in field_table.Values) {
                                 fielddef.Define (code_gen, classdef);
                         }
 
-                        foreach (MethodDef methoddef in method_list) {
-                                methoddef.Define (code_gen, classdef);
+                        foreach (MethodDef methoddef in method_table.Values) {
+                                methoddef.Define (code_gen, this);
+                        }
+
+                        if (event_list != null) {
+                                foreach (EventDef eventdef in event_list) {
+                                        eventdef.Define (code_gen, classdef);
+                                }
+                        }
+
+                        if (property_list != null) {
+                                foreach (PropertyDef propdef in property_list) {
+                                        propdef.Define (code_gen, classdef);
+                                }
+
+                        }
+
+                        if (customattr_list != null) {
+                                foreach (CustomAttr customattr in customattr_list)
+                                        customattr.AddTo (code_gen, classdef);
+                        }
+
+                        if (override_list != null) {
+                                foreach (DictionaryEntry entry in override_list) {
+                                        MethodDef body = (MethodDef) entry.Key;
+                                        DictionaryEntry decl = (DictionaryEntry) entry.Value;
+                                        ITypeRef parent_type = (ITypeRef) decl.Key;
+                                        parent_type.Resolve (code_gen);
+                                        string over_name = (string) decl.Value;
+                                        IMethodRef over_meth = parent_type.GetMethodRef (body.RetType,
+                                                        body.CallConv, over_name, body.ParamTypeList ());
+                                        over_meth.Resolve (code_gen);
+                                        classdef.AddMethodOverride (over_meth.PeapiMethod,
+                                                        body.PeapiMethodDef);
+                                }
                         }
 
+                        if (override_long_list != null) {
+                                foreach (DictionaryEntry entry in override_long_list) {
+                                        string sig = (string) entry.Key;
+                                        IMethodRef decl = (IMethodRef) entry.Value;
+                                        MethodDef body = (MethodDef) method_table[sig];
+                                        decl.Resolve (code_gen);
+                                        classdef.AddMethodOverride (decl.PeapiMethod,
+                                                        body.PeapiMethodDef);
+                                }
+                        }
+                }
+
+                public PEAPI.MethodDef ResolveMethod (string signature, CodeGen code_gen)
+                {
+                        MethodDef methoddef = (MethodDef) method_table[signature];
+
+                        if (methoddef == null) {
+                                code_gen.Report.Error ("Unable to resolve method: " + signature);
+                                Environment.Exit (1);
+                        }
+
+                        return methoddef.Resolve (code_gen, classdef);
+                }
+
+                public PEAPI.Method ResolveVarargMethod (string signature,
+                                CodeGen code_gen, PEAPI.Type[] opt)
+                {
+                        MethodDef methoddef = (MethodDef) method_table[signature];
+
+                        if (methoddef == null) {
+                                code_gen.Report.Error ("Unable to resolve method: " + signature);
+                                Environment.Exit (1);
+                        }
+
+                        methoddef.Resolve (code_gen, classdef);
+                        return methoddef.GetVarargSig (opt);
+                }
+
+                public PEAPI.Field ResolveField (string name, CodeGen code_gen)
+                {
+                        FieldDef fielddef = (FieldDef) field_table[name];
+
+                        return fielddef.Resolve (code_gen, classdef);
                 }
 
                 private string MakeFullName ()