updated browser capabilities file
[mono.git] / mcs / gmcs / interface.cs
index adc5931629322335fdf3c18947d8cb8725cc962f..426995a48ee4955775ed6d9f073dcddb39e9e23f 100755 (executable)
@@ -36,6 +36,7 @@ namespace Mono.CSharp {
                        MethodAttributes.Virtual;
                
                ArrayList bases;
+               Type[] baseTypes;
                
                ArrayList defined_method;
                ArrayList defined_indexer;
@@ -46,7 +47,6 @@ namespace Mono.CSharp {
                ArrayList property_builders;
                ArrayList event_builders;
                
-               Attributes OptAttributes;
 
                public string IndexerName;
 
@@ -55,6 +55,9 @@ namespace Mono.CSharp {
 
                bool members_defined;
 
+               EmitContext ec;
+               Type GenericType;
+
                // These will happen after the semantic analysis
                
                // Hashtable defined_indexers;
@@ -73,10 +76,9 @@ namespace Mono.CSharp {
 
                public Interface (NamespaceEntry ns, TypeContainer parent, string name, int mod,
                                  Attributes attrs, Location l)
-                       : base (ns, parent, name, l)
+                       : base (ns, parent, name, attrs, l)
                {
                        ModFlags = Modifiers.Check (AllowedModifiers, mod, Modifiers.PRIVATE, l);
-                       OptAttributes = attrs;
                        
                        method_builders = new ArrayList ();
                        property_builders = new ArrayList ();
@@ -278,13 +280,10 @@ namespace Mono.CSharp {
                                                members.Add (eb);
                        }
 
-                       if (((bf & BindingFlags.DeclaredOnly) == 0) && (TypeBuilder.BaseType != null)) {
-                               MemberList parent_mi;
-                               
-                               parent_mi = TypeContainer.FindMembers (
-                                       TypeBuilder.BaseType, mt, bf, filter, criteria);
-
-                               members.AddRange (parent_mi);
+                       if (((bf & BindingFlags.DeclaredOnly) == 0) && (baseTypes != null)) {
+                               foreach (Type baseType in baseTypes) {
+                                       members.AddRange (TypeContainer.FindMembers (baseType, mt, bf, filter, criteria));
+                               }
                        }
 
                        return new MemberList (members);
@@ -301,6 +300,9 @@ namespace Mono.CSharp {
                //
                void PopulateMethod (TypeContainer parent, DeclSpace decl_space, InterfaceMethod im)
                {
+                       if (im.ReturnType == null)
+                               return;
+
                        Type return_type = im.ReturnType.Type;
                        if (return_type == null)
                                return_type = this.ResolveType (im.ReturnType, false, im.Location);
@@ -347,7 +349,7 @@ namespace Mono.CSharp {
                         // removing the old code here.
                         //
                         
-                        im.Builder = mb;
+                        im.SetBuilder (mb);
                         
                 }
 
@@ -357,12 +359,12 @@ namespace Mono.CSharp {
                void PopulateProperty (TypeContainer parent, DeclSpace decl_space, InterfaceProperty ip)
                {
                        PropertyBuilder pb;
-                       MethodBuilder get = null, set = null;
-                       ip.Type = this.ResolveTypeExpr (ip.Type, false, ip.Location);
-                       if (ip.Type == null)
+
+                       ip.ReturnType = this.ResolveTypeExpr (ip.ReturnType, false, ip.Location);
+                       if (ip.ReturnType == null)
                                return;
                        
-                       Type prop_type = ip.Type.Type;
+                       Type prop_type = ip.ReturnType.Type;
                        Type [] setter_args = new Type [1];
 
                        if (prop_type == null)
@@ -381,6 +383,8 @@ namespace Mono.CSharp {
                                ip.Name, PropertyAttributes.None,
                                prop_type, null);
 
+                        MethodBuilder get = null, set = null;
+                        
                        if (ip.HasGet){
                                get = TypeBuilder.DefineMethod (
                                        "get_" + ip.Name, property_attributes ,
@@ -415,7 +419,7 @@ namespace Mono.CSharp {
                                // HACK because System.Reflection.Emit is lame
                                //
                                Parameter [] parms = new Parameter [1];
-                               parms [0] = new Parameter (ip.Type, "value", Parameter.Modifier.NONE, null);
+                               parms [0] = new Parameter (ip.ReturnType, "value", Parameter.Modifier.NONE, null);
                                InternalParameters ipp = new InternalParameters (
                                        this, new Parameters (parms, null, Location.Null));
                                        
@@ -427,7 +431,7 @@ namespace Mono.CSharp {
 
                        TypeManager.RegisterProperty (pb, get, set);
                        property_builders.Add (pb);
-                        ip.Builder = pb;
+                       ip.SetBuilders (pb, get, set);
                }
 
                //
@@ -441,11 +445,11 @@ namespace Mono.CSharp {
                        //
                        MyEventBuilder eb;
                        MethodBuilder add = null, remove = null;
-                       ie.Type = this.ResolveTypeExpr (ie.Type, false, ie.Location);
-                       if (ie.Type == null)
+                       ie.ReturnType = this.ResolveTypeExpr (ie.ReturnType, false, ie.Location);
+                       if (ie.ReturnType == null)
                                return;
                        
-                       Type event_type = ie.Type.Type;
+                       Type event_type = ie.ReturnType.Type;
 
                        if (event_type == null)
                                return;
@@ -476,7 +480,7 @@ namespace Mono.CSharp {
                        eb.SetRemoveOnMethod (remove);
 
                        Parameter [] parms = new Parameter [1];
-                       parms [0] = new Parameter (ie.Type, "value", Parameter.Modifier.NONE, null);
+                       parms [0] = new Parameter (ie.ReturnType, "value", Parameter.Modifier.NONE, null);
                        InternalParameters ip = new InternalParameters (
                                this, new Parameters (parms, null, Location.Null));
 
@@ -493,7 +497,7 @@ namespace Mono.CSharp {
                        TypeManager.RegisterEvent (eb, add, remove);
                        event_builders.Add (eb);
 
-                        ie.Builder = eb;
+                        ie.SetBuilder (eb);
                }
 
                //
@@ -502,11 +506,11 @@ namespace Mono.CSharp {
                void PopulateIndexer (TypeContainer parent, DeclSpace decl_space, InterfaceIndexer ii)
                {
                        PropertyBuilder pb;
-                       ii.Type = this.ResolveTypeExpr (ii.Type, false, ii.Location);
-                       if (ii.Type == null)
+                       ii.ReturnType = this.ResolveTypeExpr (ii.ReturnType, false, ii.Location);
+                       if (ii ==null || ii.ReturnType == null)
                                return;
                        
-                       Type prop_type = ii.Type.Type;
+                       Type prop_type = ii.ReturnType.Type;
                        Type [] arg_types = ii.ParameterTypes (this);
                        Type [] value_arg_types;
 
@@ -581,7 +585,7 @@ namespace Mono.CSharp {
                                
                                pv = new Parameter [p.Length + 1];
                                p.CopyTo (pv, 0);
-                               pv [p.Length] = new Parameter (ii.Type, "value", Parameter.Modifier.NONE, null);
+                               pv [p.Length] = new Parameter (ii.ReturnType, "value", Parameter.Modifier.NONE, null);
                                Parameters value_params = new Parameters (pv, null, Location.Null);
                                value_params.GetParameterInfo (decl_space);
                                
@@ -611,7 +615,7 @@ namespace Mono.CSharp {
 
                        property_builders.Add (pb);
 
-                        ii.Builder = pb;
+                       ii.SetBuilders (pb, get_item, set_item);
                }
 
                /// <summary>
@@ -732,8 +736,8 @@ namespace Mono.CSharp {
                        
                        InTransit = true;
                        
-                       EmitContext ec = new EmitContext (this, this, Location, null, null,
-                                                         ModFlags, false);
+                       ec = new EmitContext (this, this, Location, null, null,
+                                             ModFlags, false);
 
                        ifaces = GetInterfaceBases (out error);
 
@@ -752,7 +756,7 @@ namespace Mono.CSharp {
                                if (TypeManager.NamespaceClash (Name, Location))
                                        return null;
                                
-                               ModuleBuilder builder = CodeGen.ModuleBuilder;
+                               ModuleBuilder builder = CodeGen.Module.Builder;
 
                                TypeBuilder = builder.DefineType (
                                        Name,
@@ -774,6 +778,9 @@ namespace Mono.CSharp {
                        }
 
                        if (IsGeneric) {
+                               CurrentType = new ConstructedType (
+                                       Name, TypeParameters, Location);
+
                                foreach (TypeParameter type_param in TypeParameters)
                                        type_param.Define (TypeBuilder);
 
@@ -782,9 +789,11 @@ namespace Mono.CSharp {
                        }
 
                        if (ifaces != null) {
-                               foreach (TypeExpr iface in ifaces) {
-                                       Type itype = iface.ResolveType (ec);
+                               baseTypes = new Type[ifaces.Length];
+                               for (int i = 0; i < ifaces.Length; ++i) {
+                                       Type itype = ifaces [i].ResolveType (ec);
                                        TypeBuilder.AddInterfaceImplementation (itype);
+                                       baseTypes [i] = itype;
                                }
                        }
 
@@ -863,6 +872,12 @@ namespace Mono.CSharp {
                                        TypeBuilder.SetCustomAttribute (cb);
                        }
 
+                       if (CurrentType != null) {
+                               GenericType = CurrentType.ResolveType (ec);
+
+                               ec.ContainerType = GenericType;
+                       }
+
 #if CACHE
                        if (TypeBuilder.BaseType != null)
                                parent_container = TypeManager.LookupMemberContainer (TypeBuilder.BaseType);
@@ -885,50 +900,26 @@ namespace Mono.CSharp {
                 /// <summary>
                ///   Applies all the attributes.
                /// </summary>
-                public void Emit (TypeContainer tc)
-                {
+               public void Emit (TypeContainer tc) {
                         if (OptAttributes != null) {
-                               EmitContext ec = new EmitContext (tc, this, Location, null, null,
-                                                                 ModFlags, false);
+                               EmitContext ec = new EmitContext (tc, this, Location, null, null, ModFlags, false);
                                Attribute.ApplyAttributes (ec, TypeBuilder, this, OptAttributes);
                        }
 
-                        // Now emit attributes for each interface member
-                        if (defined_method != null) {
-                                foreach (InterfaceMethod im in defined_method) {
-                                        EmitContext ec = new EmitContext (tc, this, Location, null,
-                                                                          im.ReturnType.Type, ModFlags, false);
-  
-                                        MethodCore.LabelParameters (ec, im.Builder,
-                                                                    im.Parameters,
-                                                                    im.OptAttributes,
-                                                                    Location);
-                                        
-                                        if (im.OptAttributes != null)
-                                               Attribute.ApplyAttributes (ec, im.Builder,
-                                                                           im, im.OptAttributes);
-                                        
-                                }
-                        }
-
-                        if (defined_properties != null) {
-                                foreach (InterfaceProperty ip in defined_properties) {
-                                        EmitContext ec = new EmitContext (tc, this, Location, null,
-                                                                          null, ModFlags, false);
-                                        
-                                        if (ip.OptAttributes != null)
-                                               Attribute.ApplyAttributes (ec, ip.Builder, ip, ip.OptAttributes);
-                                }
-                        }
+                       EmitSubType (tc, defined_method);
+                       EmitSubType (tc, defined_properties);
+                       EmitSubType (tc, defined_indexer);
+                       EmitSubType (tc, defined_events);
+               }
 
-                        if (defined_events != null) {
-                                foreach (InterfaceEvent ie in defined_events) {
-                                        EmitContext ec = new EmitContext (tc, this, Location, null,
-                                                                          null, ModFlags, false);
+               void EmitSubType (TypeContainer tc, ArrayList subType) {
+                       if (subType == null)
+                               return;
                                         
-                                        if (ie.OptAttributes != null)
-                                               Attribute.ApplyAttributes (ec, ie.Builder, ie, ie.OptAttributes);
-                                }
+                       foreach (InterfaceMemberBase imb in subType) {
+                               //TODO: set it somewhere earlier
+                               imb.ModFlags = ModFlags;
+                               imb.Emit (tc, this);
                         }
                 }
 
@@ -944,11 +935,6 @@ namespace Mono.CSharp {
                                                                 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];
@@ -1007,6 +993,12 @@ namespace Mono.CSharp {
                        if ((bf & BindingFlags.Public) == 0)
                                return MemberList.Empty;
 
+                       BindingFlags new_bf = bf | BindingFlags.DeclaredOnly;
+
+                       if (GenericType != null)
+                               return TypeManager.FindMembers (GenericType, mt, new_bf,
+                                                               null, null);
+
                        ArrayList members = new ArrayList ();
 
                        if ((mt & MemberTypes.Method) != 0)
@@ -1022,65 +1014,149 @@ namespace Mono.CSharp {
                }
        }
 
-       public class InterfaceMemberBase {
-               public readonly string Name;
+       public abstract class InterfaceMemberBase: MemberCore, IAttributeSupport {
                public readonly bool IsNew;
-               public Attributes OptAttributes;
+                // Why is not readonly
+               public Expression ReturnType;
                
-               public InterfaceMemberBase (string name, bool is_new, Attributes attrs)
+               public InterfaceMemberBase (Expression type, string name, bool is_new, Attributes attrs, Location loc):
+                       base (name, attrs, loc)
                {
-                       Name = name;
+                       ReturnType = type;
                        IsNew = is_new;
-                       OptAttributes = attrs;
                }
-       }
+
+               public virtual EmitContext Emit (TypeContainer tc, DeclSpace ds) {
+                       EmitContext ec = null;
+                       if (OptAttributes != null) {
+                               ec = new EmitContext (tc, ds, Location, null, null, ModFlags, false);
+
+                               Attribute.ApplyAttributes (ec, null, this, OptAttributes);
+                       }
+
+                       return ec;
+               }
+
+               #region IAttributeSupport Members
+               public abstract void SetCustomAttribute (CustomAttributeBuilder customBuilder);
+               #endregion
        
-       public class InterfaceProperty : InterfaceMemberBase {
+               public override bool Define (TypeContainer parent) {
+                       throw new NotImplementedException ();
+               }
+       }
+
+       abstract public class InterfaceSetGetBase: InterfaceMemberBase 
+       {
+               internal sealed class PropertyAccessor: IAttributeSupport 
+               {
+                       Attributes m_attrs;
+                       MethodBuilder m_builder;
+
+                       public PropertyAccessor (Attributes attrs) {
+                               m_attrs = attrs;
+                       }
+                        
+                       public MethodBuilder Builder {
+                               set {
+                                       m_builder = value;
+                               }
+                       }
+                        
+                       public void Emit (EmitContext ec) {
+                               if (m_attrs != null) {
+                                       Attribute.ApplyAttributes (ec, this, this, m_attrs);
+                                }
+                       }
+                                       
+                       public void SetCustomAttribute (CustomAttributeBuilder customAttribute) {
+                               m_builder.SetCustomAttribute (customAttribute);
+                       }
+               }
+            
+
+               PropertyAccessor m_get;
+               PropertyAccessor m_set;
+               protected PropertyBuilder Builder;
+
                public readonly bool HasSet;
                public readonly bool HasGet;
-               public readonly Location Location;
-               public Expression Type;
-                public PropertyBuilder Builder;
                
-               public InterfaceProperty (Expression type, string name,
-                                         bool is_new, bool has_get, bool has_set,
-                                         Attributes attrs, Location loc)
-                       : base (name, is_new, attrs)
+               public InterfaceSetGetBase (Expression type, string name, bool is_new,
+                                               bool has_get, bool has_set, Attributes prop_attrs, Attributes get_attrs,
+                        Attributes set_attrs, Location loc)
+                       :base (type, name, is_new, prop_attrs, loc)
                {
-                       Type = type;
                        HasGet = has_get;
                        HasSet = has_set;
-                       Location = loc;
+                       m_get = new PropertyAccessor (get_attrs);
+                       m_set = new PropertyAccessor (set_attrs);
+                       ReturnType = type;
+               }
+
+               public override EmitContext Emit (TypeContainer tc, DeclSpace ds) {
+                       EmitContext ec = base.Emit (tc, ds);
+                       if (ec == null)
+                               ec = new EmitContext (tc, ds, Location, null, null, ModFlags, false);
+
+                       m_get.Emit (ec);
+                       m_set.Emit (ec);
+                       return ec;
                }
+
+               // TODO: It would be nice to have this method private
+               public void SetBuilders (PropertyBuilder pb, MethodBuilder gb, MethodBuilder sb) {
+                       Builder = pb;
+                       m_get.Builder = gb;
+                       m_set.Builder = sb;
+               }
+
+               public override void SetCustomAttribute (CustomAttributeBuilder customBuilder) {
+                       Builder.SetCustomAttribute (customBuilder);
+               }
+
        }
 
        public class InterfaceEvent : InterfaceMemberBase {
-               public readonly Location Location;
-               public Expression Type;
-                public MyEventBuilder Builder;
+               MyEventBuilder Builder;
                 
                public InterfaceEvent (Expression type, string name, bool is_new, Attributes attrs,
                                       Location loc)
-                       : base (name, is_new, attrs)
+                       : base (type, name, is_new, attrs, loc)
                {
-                       Type = type;
-                       Location = loc;
+               }
+
+               public override string GetSignatureForError () {
+                       return TypeManager.GetFullNameSignature (Builder);
+               }
+
+               public void SetBuilder (MyEventBuilder eb) {
+                       Builder = eb;
+               }
+
+               public override void SetCustomAttribute (CustomAttributeBuilder customBuilder) {
+                       Builder.SetCustomAttribute (customBuilder);
                }
        }
        
        public class InterfaceMethod : InterfaceMemberBase {
-               public Expression ReturnType;
                public readonly Parameters Parameters;
-               public readonly Location Location;
-                public MethodBuilder Builder;
+               MethodBuilder Builder;
                 
                public InterfaceMethod (Expression return_type, string name, bool is_new, Parameters args,
                                        Attributes attrs, Location l)
-                       : base (name, is_new, attrs)
+                       : base (return_type, name, is_new, attrs, l)
                {
-                       this.ReturnType = return_type;
                        this.Parameters = args;
-                       Location = l;
+               }
+
+               public override EmitContext Emit(TypeContainer tc, DeclSpace ds) {
+                       EmitContext ec = base.Emit(tc, ds);
+                       if (ec == null) 
+                               ec = new EmitContext (tc, ds, Location, null, null, ModFlags, false);
+
+                       MethodCore.LabelParameters (ec, Builder, Parameters, OptAttributes, Location);
+                       return ec;
                }
 
                /// <summary>
@@ -1101,32 +1177,55 @@ namespace Mono.CSharp {
                        return (IsNew ? "new-" : "") + ret.FullName + "(" + args + ")";
                }
 
+               public override string GetSignatureForError () {
+                       return TypeManager.CSharpSignature (Builder);
+               }
+
                public Type [] ParameterTypes (DeclSpace ds)
                {
                        return Parameters.GetParameterInfo (ds);
                }
+
+               public void SetBuilder (MethodBuilder mb) {
+                       Builder = mb;
+               }
+
+               public override void SetCustomAttribute(CustomAttributeBuilder customBuilder) {
+                       Builder.SetCustomAttribute (customBuilder);
+               }
+       }
+
+       public class InterfaceProperty : InterfaceSetGetBase 
+       {
+               public InterfaceProperty (Expression type, string name,
+                       bool is_new, bool has_get, bool has_set,
+                       Attributes prop_attrs, Attributes get_attrs,
+                       Attributes set_attrs, Location loc)
+                       : base (type, name, is_new, has_get, has_set, prop_attrs, get_attrs, set_attrs, loc)
+               {
+               }
+
+               public override string GetSignatureForError () {
+                       return TypeManager.CSharpSignature (Builder, false);
+               }       
        }
 
-       public class InterfaceIndexer : InterfaceMemberBase {
-               public readonly bool HasGet, HasSet;
+       public class InterfaceIndexer : InterfaceSetGetBase {
                public readonly Parameters Parameters;
-               public readonly Location Location;
-               public Expression Type;
-                public PropertyBuilder Builder;
-               
+                
                public InterfaceIndexer (Expression type, Parameters args, bool do_get, bool do_set,
-                                        bool is_new, Attributes attrs, Location loc)
-                       : base ("", is_new, attrs)
+                                        bool is_new, Attributes attrs, Attributes get_attrs, Attributes set_attrs,
+                                         Location loc)
+                       : base (type, "Item", is_new, do_get, do_set, attrs, get_attrs, set_attrs, loc)
                {
-                       Type = type;
                        Parameters = args;
-                       HasGet = do_get;
-                       HasSet = do_set;
-                       Location = loc;
                }
 
-               public Type [] ParameterTypes (DeclSpace ds)
-               {
+               public override string GetSignatureForError() {
+                       return TypeManager.CSharpSignature (Builder, true);
+               }
+
+               public Type [] ParameterTypes (DeclSpace ds) {
                        return Parameters.GetParameterInfo (ds);
                }
        }