2002-01-17 Miguel de Icaza <miguel@ximian.com>
[mono.git] / mcs / mcs / interface.cs
index a024bbebc2c3fd5a6a775387b5828219db1cba85..3c2ed2c24830e93a305f42999dae9ee49e58947f 100755 (executable)
@@ -45,8 +45,6 @@ namespace Mono.CSharp {
                ArrayList method_builders;
                ArrayList property_builders;
                
-               TypeContainer parent;
-
                Attributes OptAttributes;
 
                // These will happen after the semantic analysis
@@ -58,17 +56,17 @@ namespace Mono.CSharp {
                ///   Modifiers allowed in a class declaration
                /// </summary>
                public const int AllowedModifiers =
-                       Modifiers.NEW |
-                       Modifiers.PUBLIC |
+                       Modifiers.NEW       |
+                       Modifiers.PUBLIC    |
                        Modifiers.PROTECTED |
-                       Modifiers.INTERNAL |
+                       Modifiers.INTERNAL  |
+                       Modifiers.UNSAFE    |
                        Modifiers.PRIVATE;
 
                public Interface (TypeContainer parent, string name, int mod, Attributes attrs, Location l)
-                       : base (name, l)
+                       : base (parent, name, l)
                {
-                       ModFlags = Modifiers.Check (AllowedModifiers, mod, Modifiers.PRIVATE);
-                       this.parent = parent;
+                       ModFlags = Modifiers.Check (AllowedModifiers, mod, Modifiers.PRIVATE, l);
                        OptAttributes = attrs;
                        
                        method_builders = new ArrayList ();
@@ -174,8 +172,8 @@ namespace Mono.CSharp {
 
                public bool IsTopLevel {
                        get {
-                               if (parent != null){
-                                       if (parent.Parent == null)
+                               if (Parent != null){
+                                       if (Parent.Parent == null)
                                                return true;
                                }
                                return false;
@@ -277,7 +275,7 @@ namespace Mono.CSharp {
                //
                void PopulateMethod (InterfaceMethod im)
                {
-                       Type return_type = LookupType (im.ReturnType, false);
+                       Type return_type = RootContext.LookupType (this, im.ReturnType, false, im.Location);
                        Type [] arg_types = im.ParameterTypes (this);
                        MethodBuilder mb;
                        Parameter [] p;
@@ -285,6 +283,14 @@ namespace Mono.CSharp {
 
                        if (return_type == null)
                                return;
+
+                       if (return_type.IsPointer && !UnsafeOK (this))
+                               return;
+
+                       foreach (Type t in arg_types){
+                               if (t.IsPointer && !UnsafeOK (this))
+                                       return;
+                       }
                        
                        //
                        // Create the method
@@ -321,11 +327,14 @@ namespace Mono.CSharp {
                {
                        PropertyBuilder pb;
                        MethodBuilder get = null, set = null;
-                       Type prop_type = LookupType (ip.Type, false);
+                       Type prop_type = RootContext.LookupType (this, ip.Type, false, ip.Location);
                        Type [] setter_args = new Type [1];
 
                        if (prop_type == null)
                                return;
+
+                       if (prop_type.IsPointer && !UnsafeOK (this))
+                               return;
                        
                        setter_args [0] = prop_type;
 
@@ -362,7 +371,7 @@ namespace Mono.CSharp {
 
                                set = TypeBuilder.DefineMethod (
                                        "set_" + ip.Name, property_attributes,
-                                       null, setter_args);
+                                       TypeManager.void_type, setter_args);
 
                                set.DefineParameter (1, ParameterAttributes.None, "value");
                                pb.SetSetMethod (set);
@@ -373,7 +382,7 @@ namespace Mono.CSharp {
                                Parameter [] parms = new Parameter [1];
                                parms [0] = new Parameter (ip.Type, "value", Parameter.Modifier.NONE, null);
                                InternalParameters ipp = new InternalParameters (
-                                       parent, new Parameters (parms, null));
+                                       Parent, new Parameters (parms, null, Location.Null));
                                        
                                if (!RegisterMethod (set, ipp, setter_args)) {
                                        Error111 (ip);
@@ -402,12 +411,15 @@ namespace Mono.CSharp {
                void PopulateIndexer (InterfaceIndexer ii)
                {
                        PropertyBuilder pb;
-                       Type prop_type = LookupType (ii.Type, false);
+                       Type prop_type = RootContext.LookupType (this, ii.Type, false, ii.Location);
                        Type [] arg_types = ii.ParameterTypes (this);
                        Type [] value_arg_types;
 
                        if (prop_type == null)
                                return;
+
+                       if (prop_type.IsPointer && !UnsafeOK (this))
+                               return;
                        
                        //
                        // Sets up the extra invisible `value' argument for setters.
@@ -418,6 +430,11 @@ namespace Mono.CSharp {
 
                                arg_types.CopyTo (value_arg_types, 0);
                                value_arg_types [count] = prop_type;
+
+                               foreach (Type t in arg_types){
+                                       if (t.IsPointer && !UnsafeOK (this))
+                                               return;
+                               }
                        } else {
                                value_arg_types = new Type [1];
 
@@ -460,7 +477,8 @@ namespace Mono.CSharp {
                                int i = 0;
                                
                                set_item = TypeBuilder.DefineMethod (
-                                       "set_Item", property_attributes, null, value_arg_types);
+                                       "set_Item", property_attributes,
+                                       TypeManager.void_type, value_arg_types);
                                pb.SetSetMethod (set_item);
                                //
                                // HACK because System.Reflection.Emit is lame
@@ -478,6 +496,7 @@ namespace Mono.CSharp {
                                                        i + 1,
                                                        p [i].Attributes, p [i].Name);
                                }
+                               
                                set_item.DefineParameter (i + 1, ParameterAttributes.None, "value");
                        }
                }
@@ -634,9 +653,9 @@ namespace Mono.CSharp {
                                                                  null,   // Parent Type
                                                                  ifaces);
                        } else {
-                               TypeBuilder builder = (TypeBuilder) parent_builder;
+                               TypeBuilder builder = (System.Reflection.Emit.TypeBuilder) parent_builder;
 
-                               TypeBuilder = builder.DefineNestedType (Name,
+                               TypeBuilder = builder.DefineNestedType (Basename,
                                                                        TypeAttributes.Interface |
                                                                        InterfaceAttr |
                                                                        TypeAttributes.Abstract,
@@ -674,18 +693,43 @@ namespace Mono.CSharp {
                                foreach (InterfaceEvent ie in defined_events)
                                        PopulateEvent (ie);
 
-                       if (defined_indexer != null)
+                       if (defined_indexer != null) {
                                foreach (InterfaceIndexer ii in defined_indexer)
                                        PopulateIndexer (ii);
 
+                               CustomAttributeBuilder cb = EmitDefaultMemberAttr (parent, ModFlags, Location);
+                               TypeBuilder.SetCustomAttribute (cb);
+                       }
+                       
                        return true;
                }
 
-               public void CloseType ()
+               public static CustomAttributeBuilder EmitDefaultMemberAttr (TypeContainer parent, int flags,
+                                                                           Location loc)
                {
-                       TypeBuilder.CreateType ();
+                       EmitContext ec = new EmitContext (parent, loc, null, null, flags);
+
+                       Expression ml = Expression.MemberLookup (ec, TypeManager.default_member_type,
+                                                                ".ctor", MemberTypes.Constructor,
+                                                                BindingFlags.Public | BindingFlags.Instance,
+                                                                Location.Null);
+                       
+                       if (!(ml is MethodGroupExpr)) {
+                               Console.WriteLine ("Internal error !!!!");
+                               return null;
+                       }
+                       
+                       MethodGroupExpr mg = (MethodGroupExpr) ml;
+
+                       MethodBase constructor = mg.Methods [0];
+
+                       string [] vals = { "Item" };
+
+                       CustomAttributeBuilder cb = new CustomAttributeBuilder ((ConstructorInfo) constructor, vals);
+
+                       return cb;
                }
-               
+
        }
 
        public class InterfaceMemberBase {
@@ -706,14 +750,17 @@ namespace Mono.CSharp {
                public readonly bool HasGet;
                public readonly string Type;
                public readonly string type;
+               public readonly Location Location;
                
                public InterfaceProperty (string type, string name,
-                                         bool is_new, bool has_get, bool has_set, Attributes attrs)
+                                         bool is_new, bool has_get, bool has_set,
+                                         Attributes attrs, Location loc)
                        : base (name, is_new, attrs)
                {
                        Type = type;
                        HasGet = has_get;
                        HasSet = has_set;
+                       Location = loc;
                }
        }
 
@@ -730,12 +777,15 @@ namespace Mono.CSharp {
        public class InterfaceMethod : InterfaceMemberBase {
                public readonly string     ReturnType;
                public readonly Parameters Parameters;
+               public readonly Location Location;
                
-               public InterfaceMethod (string return_type, string name, bool is_new, Parameters args, Attributes attrs)
+               public InterfaceMethod (string return_type, string name, bool is_new, Parameters args,
+                                       Attributes attrs, Location l)
                        : base (name, is_new, attrs)
                {
                        this.ReturnType = return_type;
                        this.Parameters = args;
+                       Location = l;
                }
 
                /// <summary>
@@ -743,7 +793,7 @@ namespace Mono.CSharp {
                /// </summary>
                public string GetSignature (DeclSpace ds)
                {
-                       Type ret = ds.LookupType (ReturnType, false);
+                       Type ret = RootContext.LookupType (ds, ReturnType, false, Location);
                        string args = Parameters.GetSignature (ds);
 
                        if ((ret == null) || (args == null))
@@ -762,15 +812,17 @@ namespace Mono.CSharp {
                public readonly bool HasGet, HasSet;
                public readonly Parameters Parameters;
                public readonly string Type;
+               public readonly Location Location;
                
-               public InterfaceIndexer (string type, Parameters args, bool do_get, bool do_set, bool is_new,
-                                        Attributes attrs)
+               public InterfaceIndexer (string type, Parameters args, bool do_get, bool do_set,
+                                        bool is_new, Attributes attrs, Location loc)
                        : base ("", is_new, attrs)
                {
                        Type = type;
                        Parameters = args;
                        HasGet = do_get;
                        HasSet = do_set;
+                       Location = loc;
                }
 
                public Type [] ParameterTypes (DeclSpace ds)