2001-09-12 Miguel de Icaza <miguel@ximian.com>
[mono.git] / mcs / mcs / class.cs
index 06f34f4400b384e0dc2a8df567dda30d143d3745..f05f3c0a3235859642fd452eaf38bc6387246957 100755 (executable)
@@ -28,6 +28,9 @@ namespace CIR {
                // Holds the list of enumerations
                ArrayList enums;
 
+               // Holds the list of delegates
+               ArrayList delegates;
+               
                // Holds the list of constructors
                ArrayList constructors;
 
@@ -55,6 +58,9 @@ namespace CIR {
                // Holds the indexers
                ArrayList indexers;
 
+               // Holds the operators
+               ArrayList operators;
+               
                //
                // Pointers to the default constructor and the default static constructor
                //
@@ -84,7 +90,10 @@ namespace CIR {
                //
                // This behaves like a property ;-)
                //
-               readonly public RootContext RootContext;
+               public readonly RootContext RootContext;
+
+               // Attributes for this type
+               protected Attributes attributes;
 
                public TypeContainer (RootContext rc, TypeContainer parent, string name) : base (name)
                {
@@ -168,6 +177,23 @@ namespace CIR {
                        return AdditionResult.Success;
                }
 
+               public AdditionResult AddDelegate (Delegate d)
+               {
+                       AdditionResult res;
+                       string name = d.Name;
+
+                       if ((res = IsValid (name)) != AdditionResult.Success)
+                               return res;
+
+                       if (delegates == null)
+                               delegates = new ArrayList ();
+                       
+                       DefineName (name, d);
+                       delegates.Add (d);
+
+                       return AdditionResult.Success;
+               }
+
                public AdditionResult AddMethod (Method method)
                {
                        string name = method.Name;
@@ -305,6 +331,16 @@ namespace CIR {
 
                        return AdditionResult.Success;
                }
+
+               public AdditionResult AddOperator (Operator op)
+               {
+                       if (operators == null)
+                               operators = new ArrayList ();
+
+                       operators.Add (op);
+
+                       return AdditionResult.Success;
+               }
                
                public TypeContainer Parent {
                        get {
@@ -376,12 +412,42 @@ namespace CIR {
                        }
                }
 
+               public ArrayList Events {
+                       get {
+                               return events;
+                       }
+               }
+               
                public ArrayList Enums {
                        get {
                                return enums;
                        }
                }
 
+               public ArrayList Indexers {
+                       get {
+                               return indexers;
+                       }
+               }
+
+               public ArrayList Operators {
+                       get {
+                               return operators;
+                       }
+               }
+
+               public ArrayList Delegates {
+                       get {
+                               return delegates;
+                       }
+               }
+               
+               public Attributes OptAttributes {
+                       get {
+                               return attributes;
+                       }
+               }
+               
                public Namespace Namespace {
                        get {
                                return my_namespace;
@@ -549,6 +615,38 @@ namespace CIR {
                                foreach (Method m in Methods)
                                        m.Define (this);
                        }
+
+                       if (Properties != null) {
+                               foreach (Property p in Properties)
+                                       p.Define (this);
+                       }
+
+                       if (Enums != null) {
+                               foreach (Enum e in Enums)
+                                       e.Define (this);
+                       }
+
+                       if (Events != null) {
+                               foreach (Event e in Events)
+                                       e.Define (this);
+                       }
+
+                       if (Indexers != null) {
+                               foreach (Indexer i in Indexers)
+                                       i.Define (this);
+                       }
+
+                       if (Operators != null) {
+                               foreach (Operator o in Operators)
+                                       o.Define (this);
+                       }
+
+                       if (Delegates != null) {
+                               foreach (Delegate d in Delegates)
+                                       d.Define (this);
+                       }
+                       
+                       
                }
 
                //
@@ -594,6 +692,62 @@ namespace CIR {
                {
                        return RootContext.LookupType (this, name, silent);
                }
+
+               // <summary>
+               // This method returns the members of this type just like Type.FindMembers would
+               // Only, we need to use this for types which are _being_ defined because MS' brain
+               // dead implementation can't take care of that ;-)
+               // </summary>
+               public MemberInfo [] FindMembers (MemberTypes mt, BindingFlags bf, MemberFilter filter, object criteria)
+               {
+                       // FIXME : Need to actually take care of all the various
+                       // arguments being passed in but for now, we only bother with
+                       // the MemberTypes and criteria arguments.
+
+                       switch (mt) {
+
+                       case MemberTypes.All:
+
+                               break;
+
+                       case MemberTypes.Constructor:
+
+                               break;
+                               
+                       case MemberTypes.Custom:
+
+                               break;
+
+                       case MemberTypes.Event:
+
+                               break;
+
+                       case MemberTypes.Field:
+
+                               break;
+
+                       case MemberTypes.Method:
+
+                               break;
+                               
+                       case MemberTypes.NestedType:
+
+                               break;
+                               
+                       case MemberTypes.Property:
+
+                               break;
+                               
+                       case MemberTypes.TypeInfo:
+
+                               break;
+
+                       }
+
+                       return null;
+                       
+               }
+               
        }
 
        public class Class : TypeContainer {
@@ -609,7 +763,7 @@ namespace CIR {
                        Modifiers.ABSTRACT |
                        Modifiers.SEALED;
 
-               public Class (RootContext rc, TypeContainer parent, string name, int mod)
+               public Class (RootContext rc, TypeContainer parent, string name, int mod, Attributes attrs)
                        : base (rc, parent, name)
                {
                        int accmods;
@@ -620,6 +774,7 @@ namespace CIR {
                                accmods = Modifiers.PRIVATE;
                        
                        this.mod_flags = Modifiers.Check (AllowedModifiers, mod, accmods);
+                       this.attributes = attrs;
                }
 
                //
@@ -644,7 +799,7 @@ namespace CIR {
                        Modifiers.INTERNAL |
                        Modifiers.PRIVATE;
 
-               public Struct (RootContext rc, TypeContainer parent, string name, int mod)
+               public Struct (RootContext rc, TypeContainer parent, string name, int mod, Attributes attrs)
                        : base (rc, parent, name)
                {
                        int accmods;
@@ -657,6 +812,8 @@ namespace CIR {
                        this.mod_flags = Modifiers.Check (AllowedModifiers, mod, accmods);
 
                        this.mod_flags |= Modifiers.SEALED;
+                       this.attributes = attrs;
+                       
                }
 
                //
@@ -680,16 +837,18 @@ namespace CIR {
                public readonly string     Name;
                public readonly int        ModFlags;
                public MethodBuilder MethodBuilder;
+               public readonly Attributes OptAttributes;
                
                Block block;
                
                // return_type can be "null" for VOID values.
-               public Method (string return_type, int mod, string name, Parameters parameters)
+               public Method (string return_type, int mod, string name, Parameters parameters, Attributes attrs)
                {
                        Name = name;
                        ReturnType = return_type;
                        Parameters = parameters;
                        ModFlags = Modifiers.Check (AllowedModifiers, mod, Modifiers.PRIVATE);
+                       OptAttributes = attrs;
                }
 
                // <summary>
@@ -754,7 +913,7 @@ namespace CIR {
                        cc = Parameters.GetCallingConvention ();
 
                        if (is_class)
-                               if ((ModFlags & Modifiers.STATIC) != 0)
+                               if ((ModFlags & Modifiers.STATIC) == 0)
                                        cc |= CallingConventions.HasThis;
 
                        return cc;
@@ -776,6 +935,17 @@ namespace CIR {
                                GetCallingConvention (parent is Class),
                                ret_type, parameters);
 
+                       //
+                       // This is used to track the Entry Point,
+                       //
+                       // FIXME: Allow pluggable entry point, check arguments, etc.
+                       //
+                       if (Name == "Main"){
+                               if ((ModFlags & Modifiers.STATIC) != 0){
+                                       parent.RootContext.EntryPoint = MethodBuilder;
+                               }
+                       }
+                       
                        //
                        // Define each type attribute (in/out/ref) and
                        // the argument names.
@@ -810,6 +980,7 @@ namespace CIR {
                public readonly Object Initializer;
                public readonly string Name;
                public readonly int    ModFlags;
+               public readonly Attributes OptAttributes;
                
                // <summary>
                //   Modifiers allowed in a class declaration
@@ -823,12 +994,13 @@ namespace CIR {
                        Modifiers.STATIC |
                        Modifiers.READONLY;
 
-               public Field (string type, int mod, string name, Object expr_or_array_init)
+               public Field (string type, int mod, string name, Object expr_or_array_init, Attributes attrs)
                {
                        Type = type;
                        ModFlags = Modifiers.Check (AllowedModifiers, mod, Modifiers.PRIVATE);
                        Name = name;
                        Initializer = expr_or_array_init;
+                       OptAttributes = attrs;
                }
        }
 
@@ -976,11 +1148,14 @@ namespace CIR {
        }
 
        public class Property {
-               string type;
-               string name;
-               int mod_flags;
-               Block get_block, set_block;
-
+               
+               public readonly string Type;
+               public readonly string Name;
+               public readonly int    ModFlags;
+               public Block           Get, Set;
+               public PropertyBuilder PropertyBuilder;
+               public Attributes OptAttributes;
+               
                const int AllowedModifiers =
                        Modifiers.NEW |
                        Modifiers.PUBLIC |
@@ -993,48 +1168,54 @@ namespace CIR {
                        Modifiers.ABSTRACT |
                        Modifiers.VIRTUAL;
                
-               public Property (string type, string name, int mod_flags, Block get_block, Block set_block)
+               public Property (string type, string name, int mod_flags, Block get_block, Block set_block, Attributes attrs)
                {
-                       this.type = type;
-                       this.name = name;
-                       this.mod_flags = Modifiers.Check (AllowedModifiers, mod_flags, Modifiers.PRIVATE);
-                       this.get_block = get_block;
-                       this.set_block = set_block;
+                       Type = type;
+                       Name = name;
+                       ModFlags = Modifiers.Check (AllowedModifiers, mod_flags, Modifiers.PRIVATE);
+                       Get = get_block;
+                       Set = set_block;
+                       OptAttributes = attrs;
                }
 
-               public string Type {
-                       get {
-                               return type;
-                       }
-               }
+               public void Define (TypeContainer parent)
+               {
 
-               public string Name {
-                       get {
-                               return name;
-                       }
-               }
+                       MethodAttributes method_attr = Modifiers.MethodAttr(ModFlags);
+                                       
+                       // FIXME - how to handle PropertyAttributes.HasDefault
+
+                       PropertyAttributes prop_attr = PropertyAttributes.RTSpecialName |
+                                                      PropertyAttributes.SpecialName;
                
-               public int ModFlags {
-                       get {
-                               return mod_flags;
-                       }
-               }
+               
+                       Type tp = parent.LookupType (Type, false);
+                       Type [] prop_type = new Type [1];
+                       prop_type [0] = tp;
 
-               public Block Get {
-                       get {
-                               return get_block;
+                       MethodBuilder mb;
+                       
+                       PropertyBuilder = parent.TypeBuilder.DefineProperty(Name, prop_attr, tp, null);
+                                       
+                       if (Get != null)
+                       {
+                               mb = parent.TypeBuilder.DefineMethod("get_" + Name, method_attr, tp, null);
+                               PropertyBuilder.SetGetMethod (mb);
                        }
-               }
-
-               public Block Set {
-                       get {
-                               return set_block;
+                       
+                       if (Set != null)
+                       {
+                               mb = parent.TypeBuilder.DefineMethod("set_" + Name, method_attr, null, prop_type);
+                               mb.DefineParameter(1, ParameterAttributes.None, "value"); 
+                               PropertyBuilder.SetSetMethod (mb);
                        }
+
                }
+
        }
 
        public class Event {
-
+               
                const int AllowedModifiers =
                        Modifiers.NEW |
                        Modifiers.PUBLIC |
@@ -1053,8 +1234,11 @@ namespace CIR {
                public readonly int       ModFlags;
                public readonly Block     Add;
                public readonly Block     Remove;
-
-               public Event (string type, string name, Object init, int flags, Block add_block, Block rem_block)
+               public EventBuilder       EventBuilder;
+               public Attributes         OptAttributes;
+               
+               public Event (string type, string name, Object init, int flags, Block add_block, Block rem_block,
+                             Attributes attrs)
                {
                        Type = type;
                        Name = name;
@@ -1062,7 +1246,36 @@ namespace CIR {
                        ModFlags = Modifiers.Check (AllowedModifiers, flags, Modifiers.PRIVATE);  
                        Add = add_block;
                        Remove = rem_block;
+                       OptAttributes = attrs;
                }
+
+               public void Define (TypeContainer parent)
+               {
+                       MethodAttributes m_attr = Modifiers.MethodAttr (ModFlags);
+
+                       EventAttributes e_attr = EventAttributes.RTSpecialName | EventAttributes.SpecialName;
+                       
+                       MethodBuilder mb;
+
+                       Type t = parent.LookupType (Type, false);
+                       Type [] p_type = new Type [1];
+                       p_type [0] = t;
+                       
+                       EventBuilder = parent.TypeBuilder.DefineEvent (Name, e_attr, t);
+                       
+                       if (Add != null) {
+                               mb = parent.TypeBuilder.DefineMethod ("add_" + Name, m_attr, null, p_type);
+                               mb.DefineParameter (1, ParameterAttributes.None, "value");
+                               EventBuilder.SetAddOnMethod (mb);
+                       }
+
+                       if (Remove != null) {
+                               mb = parent.TypeBuilder.DefineMethod ("remove_" + Name, m_attr, null, p_type);
+                               mb.DefineParameter (1, ParameterAttributes.None, "value");
+                               EventBuilder.SetRemoveOnMethod (mb);
+                       }
+               }
+               
        }
 
        public class Indexer {
@@ -1084,9 +1297,13 @@ namespace CIR {
                public readonly int        ModFlags;
                public readonly Block      Get;
                public readonly Block      Set;
+               public Attributes          OptAttributes;
+               public MethodBuilder GetMethodBuilder;
+               public MethodBuilder SetMethodBuilder;
+               
 
                public Indexer (string type, string int_type, int flags, Parameters parms,
-                               Block get_block, Block set_block)
+                               Block get_block, Block set_block, Attributes attrs)
                {
 
                        Type = type;
@@ -1095,7 +1312,128 @@ namespace CIR {
                        FormalParameters = parms;
                        Get = get_block;
                        Set = set_block;
+                       OptAttributes = attrs;
+               }
+
+               public void Define (TypeContainer parent)
+               {
+                       MethodAttributes attr = Modifiers.MethodAttr (ModFlags);
+                       
+                       Type ret_type = parent.LookupType (Type, false);
+                       Type [] param_types = FormalParameters.GetParameterInfo (parent);
+
+                       GetMethodBuilder = parent.TypeBuilder.DefineMethod ("get_Item", attr, ret_type, param_types);
+                       SetMethodBuilder = parent.TypeBuilder.DefineMethod ("set_Item", attr, ret_type, param_types);
+                       
+                       Parameter [] p = FormalParameters.FixedParameters;
+
+                       if (p != null) {
+                               int i;
+                               
+                               for (i = 0; i < p.Length; ++i) {
+                                       GetMethodBuilder.DefineParameter (i + 1, p [i].Attributes, p [i].Name);
+                                       SetMethodBuilder.DefineParameter (i + 1, p [i].Attributes, p [i].Name);
+                               }
+                               
+                               if (i != param_types.Length)
+                                       Console.WriteLine ("Implement type definition for params");
+                       }
+
+               }
+               
+       }
+
+       public class Operator {
+
+               const int AllowedModifiers =
+                       Modifiers.PUBLIC |
+                       Modifiers.STATIC;
+
+               public enum OpType {
+
+                       // Unary operators
+                       Bang,
+                       Tilde,
+                       Increment,
+                       Decrement,
+                       True,
+                       False,
+
+                       // Unary and Binary operators
+                       Plus,
+                       Minus,
+                       
+                       // Binary operators
+                       Star,
+                       Div,
+                       Percent,
+                       BitAnd,
+                       BitOr,
+                       Carret,
+                       ShiftLeft,
+                       ShiftRight,
+                       Eq,
+                       NotEq,
+                       GreaterThan,
+                       LesserThan,
+                       GreaterOrEq,
+                       LesserOrEq,
+
+                       // Implicit and Explicit
+                       Implicit,
+                       Explicit
+               };
+
+               public readonly OpType OperatorType;
+               public readonly string ReturnType;
+               public readonly string FirstArgType;
+               public readonly string FirstArgName;
+               public readonly string SecondArgType;
+               public readonly string SecondArgName;
+               public readonly int    ModFlags;
+               public readonly Block  Block;
+               public Attributes      OptAttributes;
+               public MethodBuilder   OperatorMethodBuilder;
+
+               public Operator (OpType type, string ret_type, int flags, string arg1type, string arg1name,
+                                string arg2type, string arg2name, Block block, Attributes attrs)
+               {
+                       OperatorType = type;
+                       ReturnType = ret_type;
+                       ModFlags = Modifiers.Check (AllowedModifiers, flags, Modifiers.PUBLIC);
+                       FirstArgType = arg1type;
+                       FirstArgName = arg1name;
+                       SecondArgType = arg2type;
+                       SecondArgName = arg2name;
+                       Block = block;
+                       OptAttributes = attrs;
                }
+
+               public void Define (TypeContainer parent)
+               {
+                       MethodAttributes attr = Modifiers.MethodAttr (ModFlags);
+
+                       string name = "Operator" + OperatorType;
+
+                       Type ret_type = parent.LookupType (ReturnType, false);
+
+                       Type [] param_types = new Type [2];
+
+                       param_types [0] = parent.LookupType (FirstArgType, false);
+                       if (SecondArgType != null)
+                               param_types [1] = parent.LookupType (SecondArgType, false);
+                       
+                       OperatorMethodBuilder = parent.TypeBuilder.DefineMethod (name, attr, ret_type, param_types);
+
+                       OperatorMethodBuilder.DefineParameter (1, ParameterAttributes.None, FirstArgName);
+
+                       if (SecondArgType != null)
+                               OperatorMethodBuilder.DefineParameter (2, ParameterAttributes.None, SecondArgName);
+
+               }
+               
+
        }
+
 }