updated browser capabilities file
[mono.git] / mcs / gmcs / class.cs
index 92e9191e0de7a3e31c98b499ff7d410091fffde3..d9826277297703ecb4952d2d738b80384f6464d8 100755 (executable)
@@ -113,9 +113,6 @@ namespace Mono.CSharp {
 
                ArrayList type_bases;
 
-               // Attributes for this type
-               protected Attributes attributes;
-
                // Information in the case we are an attribute type
 
                public AttributeTargets Targets = AttributeTargets.All;
@@ -134,8 +131,14 @@ namespace Mono.CSharp {
                //
                public string IndexerName;
 
-               public TypeContainer (NamespaceEntry ns, TypeContainer parent, string name, Location l)
-                       : base (ns, parent, name, l)
+               Type GenericType;
+
+               public TypeContainer ():
+                       this (null, null, "", null, new Location (-1)) {
+               }
+
+               public TypeContainer (NamespaceEntry ns, TypeContainer parent, string name, Attributes attrs, Location l)
+                       : base (ns, parent, name, attrs, l)
                {
                        types = new ArrayList ();
 
@@ -340,12 +343,20 @@ namespace Mono.CSharp {
                public AdditionResult AddProperty (Property prop)
                {
                        AdditionResult res;
-                       string basename = prop.Name;
-                       string fullname = Name + "." + basename;
 
-                       if ((res = IsValid (basename, fullname)) != AdditionResult.Success)
+                       if ((res = AddProperty (prop, prop.Name)) != AdditionResult.Success)
                                return res;
 
+                       if (prop.Get != null) {
+                               if ((res = AddProperty (prop, "get_" + prop.Name)) != AdditionResult.Success)
+                                       return res;
+                       }
+
+                       if (prop.Set != null) {
+                               if ((res = AddProperty (prop, "set_" + prop.Name)) != AdditionResult.Success)
+                               return res;
+                       }
+
                        if (properties == null)
                                properties = new ArrayList ();
 
@@ -353,6 +364,18 @@ namespace Mono.CSharp {
                                properties.Insert (0, prop);
                        else
                                properties.Add (prop);
+
+                       return AdditionResult.Success;
+               }
+
+               AdditionResult AddProperty (Property prop, string basename)
+               {
+                       AdditionResult res;
+                       string fullname = Name + "." + basename;
+
+                       if ((res = IsValid (basename, fullname)) != AdditionResult.Success)
+                               return res;
+
                        DefineName (fullname, prop);
 
                        return AdditionResult.Success;
@@ -376,7 +399,7 @@ namespace Mono.CSharp {
                        return AdditionResult.Success;
                }
 
-               public AdditionResult AddIndexer (Indexer i)
+               public void AddIndexer (Indexer i)
                {
                        if (indexers == null)
                                indexers = new ArrayList ();
@@ -385,8 +408,6 @@ namespace Mono.CSharp {
                                indexers.Insert (0, i);
                        else
                                indexers.Add (i);
-
-                       return AdditionResult.Success;
                }
 
                public AdditionResult AddOperator (Operator op)
@@ -396,6 +417,12 @@ namespace Mono.CSharp {
 
                        operators.Add (op);
 
+                       string basename = op.Name;
+                       string fullname = Name + "." + basename;
+                       if (!defined_names.Contains (fullname))
+                       {
+                               DefineName (fullname, op);
+                       }
                        return AdditionResult.Success;
                }
 
@@ -499,12 +526,6 @@ namespace Mono.CSharp {
                        }
                }
                
-               public Attributes OptAttributes {
-                       get {
-                               return attributes;
-                       }
-               }
-               
                public bool HaveStaticConstructor {
                        get {
                                return have_static_constructor;
@@ -562,22 +583,26 @@ namespace Mono.CSharp {
                void DefineDefaultConstructor (bool is_static)
                {
                        Constructor c;
-                       int mods = 0;
 
-                       c = new Constructor (this, Basename, Parameters.EmptyReadOnlyParameters,
+                       // The default constructor is public
+                       // If the class is abstract, the default constructor is protected
+                       // The default static constructor is private
+
+                       int mods = Modifiers.PUBLIC;
+                       if (is_static)
+                               mods = Modifiers.STATIC | Modifiers.PRIVATE;
+                       else if ((ModFlags & Modifiers.ABSTRACT) != 0)
+                               mods = Modifiers.PROTECTED;
+
+                       c = new Constructor (this, Basename, mods, Parameters.EmptyReadOnlyParameters,
                                             new ConstructorBaseInitializer (
                                                     null, Parameters.EmptyReadOnlyParameters,
                                                     Location),
                                             Location);
                        
-                       if (is_static)
-                               mods = Modifiers.STATIC;
-
-                       c.ModFlags = mods;
-
                        AddConstructor (c);
                        
-                       c.Block = new Block (null);
+                       c.Block = new ToplevelBlock (null, Location);
                        
                }
 
@@ -809,7 +834,7 @@ namespace Mono.CSharp {
                                        return null;
                                }
 
-                               ModuleBuilder builder = CodeGen.ModuleBuilder;
+                               ModuleBuilder builder = CodeGen.Module.Builder;
                                TypeBuilder = builder.DefineType (
                                        Name, type_attributes, ptype, null);
                                
@@ -823,6 +848,9 @@ namespace Mono.CSharp {
                        }
 
                        if (IsGeneric) {
+                               CurrentType = new ConstructedType (
+                                       Name, CurrentTypeParameters, Location);
+
                                foreach (TypeParameter type_param in TypeParameters)
                                        type_param.Define (TypeBuilder);
                        }
@@ -1161,6 +1189,13 @@ namespace Mono.CSharp {
                        if (delegates != null)
                                DefineMembers (delegates, defined_names);
 
+                       if (CurrentType != null) {
+                               GenericType = CurrentType.ResolveType (ec);
+
+                               ec.ContainerType = GenericType;
+                       }
+
+
 #if CACHE
                        if (TypeBuilder.BaseType != null)
                                parent_container = TypeManager.LookupMemberContainer (TypeBuilder.BaseType);
@@ -1628,7 +1663,7 @@ namespace Mono.CSharp {
                {
                        if (constants != null)
                                foreach (Const con in constants)
-                                       con.EmitConstant (this);
+                                       con.Emit (this);
                        return;
                }
 
@@ -1786,7 +1821,7 @@ namespace Mono.CSharp {
                        default_constructor = null;
                        default_static_constructor = null;
                        type_bases = null;
-                       attributes = null;
+                       OptAttributes = null;
                        ifaces = null;
                        parent_container = null;
                        member_cache = null;
@@ -1943,11 +1978,6 @@ namespace Mono.CSharp {
                        return true;
                }
 
-               public static void Error_ExplicitInterfaceNotMemberInterface (Location loc, string name)
-               {
-                       Report.Error (539, loc, "Explicit implementation: `" + name + "' is not a member of the interface");
-               }
-
                //
                // IMemberContainer
                //
@@ -1984,7 +2014,13 @@ namespace Mono.CSharp {
 
                MemberList IMemberContainer.GetMembers (MemberTypes mt, BindingFlags bf)
                {
-                       return FindMembers (mt, bf | BindingFlags.DeclaredOnly, null, null);
+                       BindingFlags new_bf = bf | BindingFlags.DeclaredOnly;
+
+                       if (GenericType != null)
+                               return TypeManager.FindMembers (GenericType, mt, new_bf,
+                                                               null, null);
+                       else
+                               return FindMembers (mt, new_bf, null, null);
                }
 
                //
@@ -2176,7 +2212,7 @@ namespace Mono.CSharp {
                        Modifiers.UNSAFE;
 
                public Class (NamespaceEntry ns, TypeContainer parent, string name, int mod, Attributes attrs, Location l)
-                       : base (ns, parent, name, l)
+                       : base (ns, parent, name, attrs, l)
                {
                        int accmods;
 
@@ -2186,7 +2222,6 @@ namespace Mono.CSharp {
                                accmods = Modifiers.PRIVATE;
 
                        this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
-                       this.attributes = attrs;
                }
 
                //
@@ -2213,7 +2248,7 @@ namespace Mono.CSharp {
                        Modifiers.PRIVATE;
 
                public Struct (NamespaceEntry ns, TypeContainer parent, string name, int mod, Attributes attrs, Location l)
-                       : base (ns, parent, name, l)
+                       : base (ns, parent, name, attrs, l)
                {
                        int accmods;
                        
@@ -2225,8 +2260,6 @@ namespace Mono.CSharp {
                        this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
 
                        this.ModFlags |= Modifiers.SEALED;
-                       this.attributes = attrs;
-                       
                }
 
                //
@@ -2453,6 +2486,7 @@ namespace Mono.CSharp {
                        Modifiers.OVERRIDE |
                        Modifiers.ABSTRACT |
                        Modifiers.UNSAFE |
+                       Modifiers.METHOD_YIELDS | 
                        Modifiers.EXTERN;
 
                //
@@ -2461,7 +2495,8 @@ namespace Mono.CSharp {
                public Method (DeclSpace ds, Expression return_type, int mod, string name,
                               Parameters parameters, Attributes attrs, Location l)
                        : base (ds, return_type, mod, AllowedModifiers, name, attrs, parameters, l)
-               { }
+               {
+               }
 
                public Method (GenericMethod generic, Expression return_type, int mod, string name,
                               Parameters parameters, Attributes attrs, Location l)
@@ -2625,15 +2660,18 @@ namespace Mono.CSharp {
                //
                public override bool Define (TypeContainer container)
                {
-                       if (!DoDefine (container))
-                               return false;
-
+                       DeclSpace decl;
                        MethodBuilder mb = null;
                        if (GenericMethod != null) {
                                mb = container.TypeBuilder.DefineGenericMethod (Name, flags);
                                if (!GenericMethod.Define (mb))
                                        return false;
-                       }
+                               decl = GenericMethod;
+                       } else
+                               decl = container;
+
+                       if (!DoDefine (decl, container))
+                               return false;
 
                        if (!CheckBase (container))
                                return false;
@@ -2732,7 +2770,7 @@ namespace Mono.CSharp {
                        Expression parent_constructor_group;
                        Type t;
 
-                       ec.CurrentBlock = new Block (null, Block.Flags.Implicit, parameters);
+                       ec.CurrentBlock = new ToplevelBlock (Block.Flags.Implicit, parameters, loc);
 
                        if (argument_list != null){
                                foreach (Argument a in argument_list){
@@ -2808,7 +2846,6 @@ namespace Mono.CSharp {
        public class Constructor : MethodCore {
                public ConstructorBuilder ConstructorBuilder;
                public ConstructorInitializer Initializer;
-               new public Attributes OptAttributes;
 
                // <summary>
                //   Modifiers allowed for a constructor.
@@ -2826,9 +2863,9 @@ namespace Mono.CSharp {
                // The spec claims that static is not permitted, but
                // my very own code has static constructors.
                //
-               public Constructor (DeclSpace ds, string name, Parameters args,
+               public Constructor (DeclSpace ds, string name, int mod, Parameters args,
                                    ConstructorInitializer init, Location l)
-                       : base (ds, null, 0, AllowedModifiers, name, null, args, l)
+                       : base (ds, null, mod, AllowedModifiers, name, null, args, l)
                {
                        Initializer = init;
                }
@@ -3287,8 +3324,7 @@ namespace Mono.CSharp {
                                                member.InterfaceType, name, ReturnType, ParameterTypes);
 
                                if (member.InterfaceType != null && implementing == null){
-                                       TypeContainer.Error_ExplicitInterfaceNotMemberInterface (
-                                               Location, name);
+                                       Report.Error (539, Location, "'{0}' in explicit interface declaration is not an interface", method_name);
                                        return false;
                                }
                        }
@@ -3388,7 +3424,9 @@ namespace Mono.CSharp {
                                        method_name, flags, CallingConventions,
                                        ReturnType, ParameterTypes);
                        else
-                               builder.SetGenericMethodSignature (ReturnType, ParameterTypes);
+                               builder.SetGenericMethodSignature (
+                                       flags, CallingConventions,
+                                       ReturnType, ParameterTypes);
 
                        if (builder == null)
                                return false;
@@ -3503,7 +3541,7 @@ namespace Mono.CSharp {
                        //
                        // FIXME: This code generates buggy code
                        //
-                       if (member.Name == "Finalize" && ReturnType == TypeManager.void_type)
+                       if (member is Destructor)
                                EmitDestructor (ec, block);
                        else {
                                SymbolWriter sw = CodeGen.SymbolWriter;
@@ -3525,18 +3563,15 @@ namespace Mono.CSharp {
                        ILGenerator ig = ec.ig;
                        
                        Label finish = ig.DefineLabel ();
-                       bool old_in_try = ec.InTry;
+
+                       block.SetDestructor ();
                        
                        ig.BeginExceptionBlock ();
-                       ec.InTry = true;
                        ec.ReturnLabel = finish;
                        ec.HasReturnLabel = true;
                        ec.EmitTopBlock (block, null, Location);
-                       ec.InTry = old_in_try;
                        
                        // ig.MarkLabel (finish);
-                       bool old_in_finally = ec.InFinally;
-                       ec.InFinally = true;
                        ig.BeginFinallyBlock ();
                        
                        if (ec.ContainerType.BaseType != null) {
@@ -3551,7 +3586,6 @@ namespace Mono.CSharp {
                                        ig.Emit (OpCodes.Call, (MethodInfo) parent_destructor.Methods [0]);
                                }
                        }
-                       ec.InFinally = old_in_finally;
                        
                        ig.EndExceptionBlock ();
                        //ig.MarkLabel (ec.ReturnLabel);
@@ -3559,9 +3593,17 @@ namespace Mono.CSharp {
                }
        }
 
+       public class Destructor : Method {
+
+               public Destructor (DeclSpace ds, Expression return_type, int mod, string name,
+                                  Parameters parameters, Attributes attrs, Location l)
+                       : base (ds, return_type, mod, name, parameters, attrs, l)
+               { }
+
+       }
+       
        abstract public class MemberBase : MemberCore {
                public Expression Type;
-               public readonly Attributes OptAttributes;
 
                protected MethodAttributes flags;
 
@@ -3608,12 +3650,11 @@ namespace Mono.CSharp {
                //
                protected MemberBase (Expression type, int mod, int allowed_mod, int def_mod, string name,
                                      Attributes attrs, Location loc)
-                       : base (name, loc)
+                       : base (name, attrs, loc)
                {
                        explicit_mod_flags = mod;
                        Type = type;
                        ModFlags = Modifiers.Check (allowed_mod, mod, def_mod, loc);
-                       OptAttributes = attrs;
                }
 
                protected virtual bool CheckBase (TypeContainer container)
@@ -3813,7 +3854,7 @@ namespace Mono.CSharp {
                        return !error;
                }
 
-               protected virtual bool DoDefine (TypeContainer container)
+               protected virtual bool DoDefine (DeclSpace decl, TypeContainer container)
                {
                        if (Name == null)
                                Name = "this";
@@ -3824,7 +3865,7 @@ namespace Mono.CSharp {
                        flags = Modifiers.MethodAttr (ModFlags);
 
                        // Lookup Type, verify validity
-                       MemberType = container.ResolveType (Type, false, Location);
+                       MemberType = decl.ResolveType (Type, false, Location);
                        if (MemberType == null)
                                return false;
 
@@ -3886,6 +3927,11 @@ namespace Mono.CSharp {
                                if (InterfaceType == null)
                                        return false;
 
+                               if (InterfaceType.IsClass) {
+                                       Report.Error (538, Location, "'{0}' in explicit interface declaration is not an interface", ExplicitInterfaceName);
+                                       return false;
+                               }
+
                                // Compute the full name that we need to export.
                                Name = InterfaceType.FullName + "." + ShortName;
                                
@@ -4067,10 +4113,17 @@ namespace Mono.CSharp {
                                return false;
                        }
 
+                       try {
                        FieldBuilder = container.TypeBuilder.DefineField (
                                Name, t, Modifiers.FieldAttr (ModFlags));
 
                        TypeManager.RegisterFieldBase (FieldBuilder, this);
+                       }
+                       catch (ArgumentException) {
+                               Report.Warning (-24, Location, "The Microsoft runtime is unable to use [void|void*] as a field type, try using the Mono runtime.");
+                               return false;
+                       }
+
                        return true;
                }
 
@@ -4122,9 +4175,9 @@ namespace Mono.CSharp {
                        Set = set_block;
                }
 
-               protected override bool DoDefine (TypeContainer container)
+               protected override bool DoDefine (DeclSpace decl, TypeContainer container)
                {
-                       if (!base.DoDefine (container))
+                       if (!base.DoDefine (decl, container))
                                return false;
 
                        ec = new EmitContext (container, Location, null, MemberType, ModFlags);
@@ -4271,7 +4324,7 @@ namespace Mono.CSharp {
                }
        }
                        
-       public class Property : PropertyBase {
+       public class Property : PropertyBase, IIteratorContainer {
                const int AllowedModifiers =
                        Modifiers.NEW |
                        Modifiers.PUBLIC |
@@ -4284,6 +4337,7 @@ namespace Mono.CSharp {
                        Modifiers.ABSTRACT |
                        Modifiers.UNSAFE |
                        Modifiers.EXTERN |
+                       Modifiers.METHOD_YIELDS |
                        Modifiers.VIRTUAL;
 
                public Property (DeclSpace ds, Expression type, string name, int mod_flags,
@@ -4297,7 +4351,7 @@ namespace Mono.CSharp {
 
                public override bool Define (TypeContainer container)
                {
-                       if (!DoDefine (container))
+                       if (!DoDefine (container, container))
                                return false;
 
                        if (!CheckBase (container))
@@ -4315,6 +4369,20 @@ namespace Mono.CSharp {
                                                          parameters, ip, CallingConventions.Standard,
                                                          Get.OptAttributes, ModFlags, flags, false);
 
+                               //
+                               // Setup iterator if we are one
+                               //
+                               if ((ModFlags & Modifiers.METHOD_YIELDS) != 0){
+                                       IteratorHandler ih = new  IteratorHandler (
+                                                                                  "get", container, MemberType,
+                                                                                  parameters, ip, ModFlags, Location);
+                                       
+                                       Block new_block = ih.Setup (block);
+                                       if (new_block == null)
+                                               return false;
+                                       block = new_block;
+                               }
+                               
                                if (!GetData.Define (container))
                                        return false;
 
@@ -4371,6 +4439,11 @@ namespace Mono.CSharp {
                        }
                        return true;
                }
+
+               public void SetYields ()
+               {
+                       ModFlags |= Modifiers.METHOD_YIELDS;
+               }
        }
 
        /// </summary>
@@ -4551,7 +4624,7 @@ namespace Mono.CSharp {
                        EventAttributes e_attr = EventAttributes.RTSpecialName | EventAttributes.SpecialName;
                        MethodAttributes m_attr = MethodAttributes.HideBySig | MethodAttributes.SpecialName
 ;
-                       if (!DoDefine (container))
+                       if (!DoDefine (container, container))
                                return false;
 
                        if (init != null && ((ModFlags & Modifiers.ABSTRACT) != 0)){
@@ -4732,7 +4805,7 @@ namespace Mono.CSharp {
                                PropertyAttributes.RTSpecialName |
                                PropertyAttributes.SpecialName;
                        
-                       if (!DoDefine (container))
+                       if (!DoDefine (container, container))
                                return false;
 
                        IndexerName = Attribute.ScanForIndexerName (ec, OptAttributes);
@@ -4752,6 +4825,9 @@ namespace Mono.CSharp {
                                Name = ShortName;
                        }
 
+                       if (!CheckNameCollision (container))
+                               return false;
+
                        if (!CheckBase (container))
                                return false;
 
@@ -4865,9 +4941,53 @@ namespace Mono.CSharp {
 
                        return true;
                }
+
+               bool CheckNameCollision (TypeContainer container) {
+                       switch (VerifyName (container)){
+                               case DeclSpace.AdditionResult.NameExists:
+                                       Report.Error (102, Location, "The container '{0}' already contains a definition for '{1}'", container.GetSignatureForError (), Name);
+                                       return false;
+
+                               case DeclSpace.AdditionResult.Success:
+                                       return true;
+                       }
+                       throw new NotImplementedException ();
+               }
+
+               DeclSpace.AdditionResult VerifyName (TypeContainer container) {
+                       if (!AddIndexer (container, container.Name + "." + Name))
+                               return DeclSpace.AdditionResult.NameExists;
+
+                       if (Get != null) {
+                               if (!AddIndexer (container, container.Name + ".get_" + Name))
+                                       return DeclSpace.AdditionResult.NameExists;
+                       }
+
+                       if (Set != null) {
+                               if (!AddIndexer (container, container.Name + ".set_" + Name))
+                                       return DeclSpace.AdditionResult.NameExists;
+                       }
+                       return DeclSpace.AdditionResult.Success;
+               }
+
+               bool AddIndexer (TypeContainer container, string fullname)
+               {
+                       object value = container.GetDefinition (fullname);
+
+                       if (value != null) {
+                               return value.GetType () != GetType () ? false : true;
+                       }
+
+                       container.DefineName (fullname, this);
+                       return true;
+               }
+
+               public override string GetSignatureForError () {
+                       return TypeManager.CSharpSignature (PropertyBuilder, true);
+               }
        }
 
-       public class Operator : MemberBase {
+       public class Operator : MemberBase, IIteratorContainer {
 
                const int AllowedModifiers =
                        Modifiers.PUBLIC |
@@ -4934,6 +5054,7 @@ namespace Mono.CSharp {
                        : base (ret_type, mod_flags, AllowedModifiers, Modifiers.PUBLIC, "", attrs, loc)
                {
                        OperatorType = type;
+                       Name = "op_" + OperatorType;
                        ReturnType = ret_type;
                        FirstArgType = arg1type;
                        FirstArgName = arg1name;
@@ -4977,6 +5098,7 @@ namespace Mono.CSharp {
                                                     new Parameters (param_list, null, Location),
                                                     OptAttributes, Location);
 
+                       OperatorMethod.Block = Block;
                        OperatorMethod.IsOperator = true;                       
                        OperatorMethod.Define (container);
 
@@ -5091,7 +5213,6 @@ namespace Mono.CSharp {
                        if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
                                return;
                        
-                       OperatorMethod.Block = Block;
                        OperatorMethod.Emit (container);
                        Block = null;
                }
@@ -5173,6 +5294,11 @@ namespace Mono.CSharp {
                                        GetName (OperatorType),
                                        param_types [0], param_types [1]);
                }
+
+               public void SetYields ()
+               {
+                       ModFlags |= Modifiers.METHOD_YIELDS;
+               }
        }
 
        //
@@ -5348,10 +5474,7 @@ namespace Mono.CSharp {
                        // If only accessible to the defining assembly or 
                        if (prot == MethodAttributes.FamANDAssem ||
                            prot == MethodAttributes.Assembly){
-                               if (m.DeclaringType.Assembly == CodeGen.AssemblyBuilder)
-                                       return true;
-                               else
-                                       return false;
+                               return m.DeclaringType.Assembly == CodeGen.Assembly.Builder;
                        }
 
                        // Anything else (FamOrAssembly and Public) is fine