* codegen.cs (IResolveContent.GenericDeclContainer): Copy from gmcs.
[mono.git] / mcs / gmcs / decl.cs
index 5ddf637b017013ac00490672783721295b11d2ae..7ec2b071653b160d5d7f980d829d26c8e76866f5 100644 (file)
@@ -29,53 +29,58 @@ namespace Mono.CSharp {
                public readonly MemberName Left;
                public readonly Location Location;
 
-               public static readonly MemberName Null = new MemberName ("", Location.Null);
+               public static readonly MemberName Null = new MemberName ("");
 
                bool is_double_colon;
 
                private MemberName (MemberName left, string name, bool is_double_colon,
-                                   TypeArguments args, Location loc)
+                                   Location loc)
                {
                        this.Name = name;
                        this.Location = loc;
                        this.is_double_colon = is_double_colon;
-                       this.TypeArguments = args;
                        this.Left = left;
                }
 
-               public MemberName (string name, TypeArguments args, Location loc)
-                       : this (name, loc)
+               private MemberName (MemberName left, string name, bool is_double_colon,
+                                   TypeArguments args, Location loc)
+                       : this (left, name, is_double_colon, loc)
                {
                        this.TypeArguments = args;
                }
 
+               public MemberName (string name)
+                       : this (name, Location.Null)
+               { }
+
                public MemberName (string name, Location loc)
-               {
-                       this.Name = name;
-                       this.Location = loc;
-               }
+                       : this (null, name, false, loc)
+               { }
+
+               public MemberName (string name, TypeArguments args, Location loc)
+                       : this (null, name, false, args, loc)
+               { }
+
+               public MemberName (MemberName left, string name)
+                       : this (left, name, left != null ? left.Location : Location.Null)
+               { }
 
                public MemberName (MemberName left, string name, Location loc)
-                       : this (name, loc)
-               {
-                       this.Left = left;
-               }
+                       : this (left, name, false, loc)
+               { }
 
                public MemberName (MemberName left, string name, TypeArguments args, Location loc)
-                       : this (name, args, loc)
-               {
-                       this.Left = left;
-               }
+                       : this (left, name, false, args, loc)
+               { }
+
 
                public MemberName (string alias, string name, Location loc)
-                       : this (new MemberName (alias, loc), name, true, null, loc)
-               {
-               }
+                       : this (new MemberName (alias, loc), name, true, loc)
+               { }
 
                public MemberName (MemberName left, MemberName right)
                        : this (left, right, right.Location)
-               {
-               }
+               { }
 
                public MemberName (MemberName left, MemberName right, Location loc)
                        : this (null, right.Name, false, right.TypeArguments, loc)
@@ -85,26 +90,9 @@ namespace Mono.CSharp {
                        this.Left = (right.Left == null) ? left : new MemberName (left, right.Left);
                }
 
-               static readonly char [] dot_array = { '.' };
-
-               public static MemberName FromDotted (string name, Location loc)
-               {
-                       string [] elements = name.Split (dot_array);
-                       int count = elements.Length;
-                       int i = 0;
-                       MemberName n = new MemberName (elements [i++], loc);
-                       while (i < count)
-                               n = new MemberName (n, elements [i++], loc);
-                       return n;
-               }
-
                public string GetName ()
                {
-                       string connect = is_double_colon ? "::" : ".";
-                       if (Left != null)
-                               return Left.GetName () + connect + Name;
-                       else
-                               return Name;
+                       return GetName (false);
                }
 
                public bool IsGeneric {
@@ -128,71 +116,15 @@ namespace Mono.CSharp {
                                return name;
                }
 
-               public int CountTypeArguments {
-                       get {
-                               if (TypeArguments == null)
-                                       return 0;
-                               else
-                                       return TypeArguments.Count;
-                       }
-               }
-
-               public string MethodName {
-                       get {
-                               string connect = is_double_colon ? "::" : ".";
-                               if (Left != null)
-                                       return Left.FullName + connect + Name;
-                               else
-                                       return Name;
-                       }
-               }
-
-               public static string MakeName (string name, TypeArguments args)
-               {
-                       if (args == null)
-                               return name;
-                       else
-                               return name + "`" + args.Count;
-               }
-
-               public static string MakeName (string name, int count)
-               {
-                       return name + "`" + count;
-               }
-
                public string GetTypeName ()
                {
                        string connect = is_double_colon ? "::" : ".";
                        if (Left != null)
-                               return Left.GetTypeName () + connect +
-                                       MakeName (Name, TypeArguments);
+                               return Left.GetTypeName () + connect + MakeName (Name, TypeArguments);
                        else
                                return MakeName (Name, TypeArguments);
                }
 
-               protected bool IsUnbound {
-                       get {
-                               if ((Left != null) && Left.IsUnbound)
-                                       return true;
-                               else if (TypeArguments == null)
-                                       return false;
-                               else
-                                       return TypeArguments.IsUnbound;
-                       }
-               }
-
-               protected bool CheckUnbound (Location loc)
-               {
-                       if ((Left != null) && !Left.CheckUnbound (loc))
-                               return false;
-                       if ((TypeArguments != null) && !TypeArguments.IsUnbound) {
-                               Report.Error (1031, loc, "Type expected");
-                               return false;
-                       }
-
-                       return true;
-               }
-
                public Expression GetTypeExpression ()
                {
                        if (IsUnbound) {
@@ -243,6 +175,16 @@ namespace Mono.CSharp {
                        }
                }
 
+               public string MethodName {
+                       get {
+                               string connect = is_double_colon ? "::" : ".";
+                               if (Left != null)
+                                       return Left.FullName + connect + Name;
+                               else
+                                       return Name;
+                       }
+               }
+
                public override string ToString ()
                {
                        string connect = is_double_colon ? "::" : ".";
@@ -292,6 +234,51 @@ namespace Mono.CSharp {
 
                        return hash & 0x7FFFFFFF;
                }
+
+               public int CountTypeArguments {
+                       get {
+                               if (TypeArguments == null)
+                                       return 0;
+                               else
+                                       return TypeArguments.Count;
+                       }
+               }
+
+               public static string MakeName (string name, TypeArguments args)
+               {
+                       if (args == null)
+                               return name;
+                       else
+                               return name + "`" + args.Count;
+               }
+
+               public static string MakeName (string name, int count)
+               {
+                       return name + "`" + count;
+               }
+
+               protected bool IsUnbound {
+                       get {
+                               if ((Left != null) && Left.IsUnbound)
+                                       return true;
+                               else if (TypeArguments == null)
+                                       return false;
+                               else
+                                       return TypeArguments.IsUnbound;
+                       }
+               }
+
+               protected bool CheckUnbound (Location loc)
+               {
+                       if ((Left != null) && !Left.CheckUnbound (loc))
+                               return false;
+                       if ((TypeArguments != null) && !TypeArguments.IsUnbound) {
+                               Report.Error (1031, loc, "Type expected");
+                               return false;
+                       }
+
+                       return true;
+               }
        }
 
        /// <summary>
@@ -323,7 +310,7 @@ namespace Mono.CSharp {
                /// </summary>
                public int ModFlags;
 
-               public /*readonly*/ DeclSpace Parent;
+               public readonly DeclSpace Parent;
 
                /// <summary>
                ///   Location where this declaration happens
@@ -335,7 +322,7 @@ namespace Mono.CSharp {
                /// <summary>
                ///   XML documentation comment
                /// </summary>
-               public string DocComment;
+               protected string comment;
 
                /// <summary>
                ///   Represents header string for documentation comment 
@@ -357,7 +344,8 @@ namespace Mono.CSharp {
                        Excluded = 1 << 9,                                      // Method is conditional
                        TestMethodDuplication = 1 << 10,                // Test for duplication must be performed
                        IsUsed = 1 << 11,
-                       IsAssigned = 1 << 12                            // Field is assigned
+                       IsAssigned = 1 << 12,                           // Field is assigned
+                       HasExplicitLayout       = 1 << 13
                }
 
                /// <summary>
@@ -368,10 +356,7 @@ namespace Mono.CSharp {
                public MemberCore (DeclSpace parent, MemberName name, Attributes attrs)
                        : base (attrs)
                {
-                       if (parent is PartialContainer && !(this is PartialContainer))
-                               throw new InternalErrorException ("A PartialContainer cannot be the direct parent of a member");
-
-                       Parent = parent;
+                       this.Parent = parent;
                        member_name = name;
                        caching_flags = Flags.Obsolete_Undetected | Flags.ClsCompliance_Undetected | Flags.HasCompliantAttribute_Undetected | Flags.Excluded_Undetected;
                }
@@ -384,15 +369,24 @@ namespace Mono.CSharp {
 
                public abstract bool Define ();
 
+               public virtual string DocComment {
+                       get {
+                               return comment;
+                       }
+                       set {
+                               comment = value;
+                       }
+               }
+
                // 
                // Returns full member name for error message
                //
                public virtual string GetSignatureForError ()
                {
                        if (Parent == null || Parent.Parent == null)
-                               return Name;
+                               return member_name.ToString ();
 
-                       return String.Concat (Parent.GetSignatureForError (), '.', Name);
+                       return String.Concat (Parent.GetSignatureForError (), '.', member_name.ToString ());
                }
 
                /// <summary>
@@ -403,7 +397,7 @@ namespace Mono.CSharp {
                        if (!RootContext.VerifyClsCompliance)
                                return;
 
-                       VerifyClsCompliance (Parent);
+                       VerifyClsCompliance ();
                }
 
                public virtual bool IsUsed {
@@ -459,18 +453,6 @@ namespace Mono.CSharp {
                        AttributeTester.Report_ObsoleteMessage (oa, GetSignatureForError (), loc);
                }
 
-               protected void CheckObsoleteType (Expression type)
-               {
-                       ObsoleteAttribute obsolete_attr = AttributeTester.GetObsoleteAttribute (type.Type);
-                       if (obsolete_attr == null)
-                               return;
-
-                       if (IsInObsoleteScope)
-                               return;
-
-                       AttributeTester.Report_ObsoleteMessage (obsolete_attr, TypeManager.CSharpName (type.Type), type.Location);
-               }
-
                /// <summary>
                /// Analyze whether CLS-Compliant verification must be execute for this MemberCore.
                /// </summary>
@@ -479,7 +461,7 @@ namespace Mono.CSharp {
                        if ((caching_flags & Flags.ClsCompliance_Undetected) == 0)
                                return (caching_flags & Flags.ClsCompliant) != 0;
 
-                       if (GetClsCompliantAttributeValue (Parent) && IsExposedFromAssembly (Parent)) {
+                       if (GetClsCompliantAttributeValue () && IsExposedFromAssembly ()) {
                                caching_flags &= ~Flags.ClsCompliance_Undetected;
                                caching_flags |= Flags.ClsCompliant;
                                return true;
@@ -492,12 +474,12 @@ namespace Mono.CSharp {
                /// <summary>
                /// Returns true when MemberCore is exposed from assembly.
                /// </summary>
-               public bool IsExposedFromAssembly (DeclSpace ds)
+               public bool IsExposedFromAssembly ()
                {
                        if ((ModFlags & (Modifiers.PUBLIC | Modifiers.PROTECTED)) == 0)
                                return false;
                        
-                       DeclSpace parentContainer = ds;
+                       DeclSpace parentContainer = Parent;
                        while (parentContainer != null && parentContainer.ModFlags != 0) {
                                if ((parentContainer.ModFlags & (Modifiers.PUBLIC | Modifiers.PROTECTED)) == 0)
                                        return false;
@@ -507,19 +489,33 @@ namespace Mono.CSharp {
                }
 
                /// <summary>
-               /// Resolve CLSCompliantAttribute value or gets cached value.
+               /// Goes through class hierarchy and gets value of first found CLSCompliantAttribute.
+               /// If no is attribute exists then assembly CLSCompliantAttribute is returned.
                /// </summary>
-               bool GetClsCompliantAttributeValue (DeclSpace ds)
+               public virtual bool GetClsCompliantAttributeValue ()
                {
+                       if ((caching_flags & Flags.HasCompliantAttribute_Undetected) == 0)
+                               return (caching_flags & Flags.ClsCompliantAttributeTrue) != 0;
+
+                       caching_flags &= ~Flags.HasCompliantAttribute_Undetected;
+
                        if (OptAttributes != null) {
                                Attribute cls_attribute = OptAttributes.Search (
                                        TypeManager.cls_compliant_attribute_type);
                                if (cls_attribute != null) {
                                        caching_flags |= Flags.HasClsCompliantAttribute;
-                                       return cls_attribute.GetClsCompliantAttributeValue ();
+                                       bool value = cls_attribute.GetClsCompliantAttributeValue ();
+                                       if (value)
+                                               caching_flags |= Flags.ClsCompliantAttributeTrue;
+                                       return value;
                                }
                        }
-                       return ds.GetClsCompliantAttributeValue ();
+
+                       if (Parent.GetClsCompliantAttributeValue ()) {
+                               caching_flags |= Flags.ClsCompliantAttributeTrue;
+                               return true;
+                       }
+                       return false;
                }
 
                /// <summary>
@@ -545,11 +541,11 @@ namespace Mono.CSharp {
                /// CLS-Compliant which means that CLS-Compliant tests are not necessary. A descendants override it
                /// and add their extra verifications.
                /// </summary>
-               protected virtual bool VerifyClsCompliance (DeclSpace ds)
+               protected virtual bool VerifyClsCompliance ()
                {
                        if (!IsClsComplianceRequired ()) {
                                if (HasClsCompliantAttribute && RootContext.WarningLevel >= 2) {
-                                       if (!IsExposedFromAssembly (ds))
+                                       if (!IsExposedFromAssembly ())
                                                Report.Warning (3019, 2, Location, "CLS compliance checking will not be performed on `{0}' because it is not visible from outside this assembly", GetSignatureForError ());
                                        if (!CodeGen.Assembly.IsClsCompliant)
                                                Report.Warning (3021, 2, Location, "`{0}' does not need a CLSCompliant attribute because the assembly is not marked as CLS-compliant", GetSignatureForError ());
@@ -576,7 +572,7 @@ namespace Mono.CSharp {
                // Raised (and passed an XmlElement that contains the comment)
                // when GenerateDocComment is writing documentation expectedly.
                //
-               internal virtual void OnGenerateDocComment (DeclSpace ds, XmlElement intermediateNode)
+               internal virtual void OnGenerateDocComment (XmlElement intermediateNode)
                {
                }
 
@@ -602,17 +598,17 @@ namespace Mono.CSharp {
                }
 
                public override IResolveContext ResolveContext {
-                       get {
-                               return this;
-                       }
+                       get { return this; }
                }
 
                #region IResolveContext Members
 
-               public virtual DeclSpace DeclContainer {
-                       get {
-                               return Parent;
-                       }
+               public DeclSpace DeclContainer {
+                       get { return Parent; }
+               }
+
+               public virtual DeclSpace GenericDeclContainer {
+                       get { return DeclContainer; }
                }
 
                public bool IsInObsoleteScope {
@@ -670,6 +666,8 @@ namespace Mono.CSharp {
                
                protected Hashtable defined_names;
 
+               public TypeContainer PartialContainer;
+
                readonly bool is_generic;
                readonly int count_type_params;
                readonly int count_current_type_params;
@@ -697,6 +695,7 @@ namespace Mono.CSharp {
                        NamespaceEntry = ns;
                        Basename = name.Basename;
                        defined_names = new Hashtable ();
+                       PartialContainer = null;
                        if (name.TypeArguments != null) {
                                is_generic = true;
                                count_type_params = count_current_type_params = name.TypeArguments.Count;
@@ -705,32 +704,15 @@ namespace Mono.CSharp {
                                count_type_params += parent.count_type_params;
                }
 
-               public override DeclSpace DeclContainer {
-                       get {
-                               return this;
-                       }
+               public override DeclSpace GenericDeclContainer {
+                       get { return this; }
                }
 
                /// <summary>
                /// Adds the member to defined_names table. It tests for duplications and enclosing name conflicts
                /// </summary>
-               protected bool AddToContainer (MemberCore symbol, string name)
-               {
-                       if (name == MemberName.Name && !(this is Interface) && !(this is Enum)) {
-                               if (symbol is TypeParameter)
-                                       Report.Error (694, symbol.Location,
-                                                     "Type parameter `{0}' has same name as " +
-                                                     "containing type, or method", name);
-                               else {
-                                       Report.SymbolRelatedToPreviousError (this);
-                                       Report.Error (542,  symbol.Location,
-                                                     "`{0}': member names cannot be the same " +
-                                                     "as their enclosing type",
-                                                     symbol.GetSignatureForError ());
-                                       return false;
-                               }
-                       }
-
+               protected virtual bool AddToContainer (MemberCore symbol, string name)
+               {
                        MemberCore mc = (MemberCore) defined_names [name];
 
                        if (mc == null) {
@@ -742,10 +724,8 @@ namespace Mono.CSharp {
                                return true;
 
                        Report.SymbolRelatedToPreviousError (mc);
-                       if (symbol is PartialContainer || mc is PartialContainer) {
-                               Report.Error (260, symbol.Location,
-                                       "Missing partial modifier on declaration of type `{0}'. Another partial declaration of this type exists",
-                                       name);
+                       if ((mc.ModFlags & Modifiers.PARTIAL) != 0 && (symbol is ClassOrStruct || symbol is Interface)) {
+                               Error_MissingPartialModifier (symbol);
                                return false;
                        }
 
@@ -827,6 +807,13 @@ namespace Mono.CSharp {
                        return true;
                }
 
+               protected void Error_MissingPartialModifier (MemberCore type)
+               {
+                       Report.Error (260, type.Location,
+                               "Missing partial modifier on declaration of type `{0}'. Another partial declaration of this type exists",
+                               type.GetSignatureForError ());
+               }
+
                public override string GetSignatureForError ()
                {
                        if (IsGeneric) {
@@ -835,15 +822,6 @@ namespace Mono.CSharp {
                        // Parent.GetSignatureForError
                        return Name;
                }
-
-               // <summary>
-               //    Resolves the expression `e' for a type, and will recursively define
-               //    types.  This should only be used for resolving base types.
-               // </summary>
-               protected TypeExpr ResolveBaseTypeExpr (Expression e)
-               {
-                       return e.ResolveAsTypeTerminal (this, false);
-               }
                
                public bool CheckAccessLevel (Type check_type) 
                {
@@ -1039,15 +1017,6 @@ namespace Mono.CSharp {
                        return ~ (~ mAccess | pAccess) == 0;
                }
 
-               //
-               // Return the nested type with name @name.  Ensures that the nested type
-               // is defined if necessary.  Do _not_ use this when you have a MemberCache handy.
-               //
-               public virtual Type FindNestedType (string name)
-               {
-                       return null;
-               }
-
                private Type LookupNestedTypeInHierarchy (string name)
                {
                        // if the member cache has been created, lets use it.
@@ -1062,10 +1031,11 @@ namespace Mono.CSharp {
                             current_type = current_type.BaseType) {
                                current_type = TypeManager.DropGenericTypeArguments (current_type);
                                if (current_type is TypeBuilder) {
-                                       DeclSpace decl = this;
-                                       if (current_type != TypeBuilder)
-                                               decl = TypeManager.LookupDeclSpace (current_type);
-                                       t = decl.FindNestedType (name);
+                                       TypeContainer tc = current_type == TypeBuilder
+                                               ? PartialContainer
+                                               : TypeManager.LookupTypeContainer (current_type);
+                                       if (tc != null)
+                                               t = tc.FindNestedType (name);
                                } else {
                                        t = TypeManager.GetNestedType (current_type, name);
                                }
@@ -1086,9 +1056,6 @@ namespace Mono.CSharp {
                //
                public FullNamedExpression LookupType (string name, Location loc, bool ignore_cs0104)
                {
-                       if (this is PartialContainer)
-                               throw new InternalErrorException ("Should not get here");
-
                        if (Cache.Contains (name))
                                return (FullNamedExpression) Cache [name];
 
@@ -1096,7 +1063,7 @@ namespace Mono.CSharp {
                        Type t = LookupNestedTypeInHierarchy (name);
                        if (t != null)
                                e = new TypeExpression (t, Location.Null);
-                       else if (Parent != null && Parent != RootContext.Tree.Types)
+                       else if (Parent != null)
                                e = Parent.LookupType (name, loc, ignore_cs0104);
                        else
                                e = NamespaceEntry.LookupNamespaceOrType (this, name, loc, ignore_cs0104);
@@ -1130,44 +1097,6 @@ namespace Mono.CSharp {
                        TypeBuilder.SetCustomAttribute (cb);
                }
 
-               /// <summary>
-               /// Goes through class hierarchy and get value of first CLSCompliantAttribute that found.
-               /// If no is attribute exists then return assembly CLSCompliantAttribute.
-               /// </summary>
-               public bool GetClsCompliantAttributeValue ()
-               {
-                       if ((caching_flags & Flags.HasCompliantAttribute_Undetected) == 0)
-                               return (caching_flags & Flags.ClsCompliantAttributeTrue) != 0;
-
-                       caching_flags &= ~Flags.HasCompliantAttribute_Undetected;
-
-                       if (OptAttributes != null) {
-                               Attribute cls_attribute = OptAttributes.Search (TypeManager.cls_compliant_attribute_type);
-                               if (cls_attribute != null) {
-                                       caching_flags |= Flags.HasClsCompliantAttribute;
-                                       if (cls_attribute.GetClsCompliantAttributeValue ()) {
-                                               caching_flags |= Flags.ClsCompliantAttributeTrue;
-                                               return true;
-                                       }
-                                       return false;
-                               }
-                       }
-
-                       if (Parent == null) {
-                               if (CodeGen.Assembly.IsClsCompliant) {
-                                       caching_flags |= Flags.ClsCompliantAttributeTrue;
-                                       return true;
-                               }
-                               return false;
-                       }
-
-                       if (Parent.GetClsCompliantAttributeValue ()) {
-                               caching_flags |= Flags.ClsCompliantAttributeTrue;
-                               return true;
-                       }
-                       return false;
-               }
-
                //
                // Extensions for generics
                //
@@ -1195,9 +1124,11 @@ namespace Mono.CSharp {
                                if (param.Name != name)
                                        continue;
 
+                               Report.SymbolRelatedToPreviousError (Parent);
+                               // TODO: Location is wrong (parent instead of child)
                                Report.Warning (693, 3, Location,
-                                       "Type parameter `{0}' has same name as type parameter from outer type `{1}'",
-                                       name, Parent.GetInstantiationName ());
+                                       "Type parameter `{0}' has the same name as the type parameter from outer type `{1}'",
+                                       name, Parent.GetSignatureForError ());
 
                                return false;
                        }
@@ -1260,11 +1191,18 @@ namespace Mono.CSharp {
 
                                Constraints constraints = null;
                                if (constraints_list != null) {
-                                       foreach (Constraints constraint in constraints_list) {
-                                               if (constraint == null)
+                                       int total = constraints_list.Count;
+                                       for (int ii = 0; ii < total; ++ii) {
+                                               Constraints constraints_at = (Constraints)constraints_list[ii];
+                                               // TODO: it is used by iterators only
+                                               if (constraints_at == null) {
+                                                       constraints_list.RemoveAt (ii);
+                                                       --total;
                                                        continue;
-                                               if (constraint.TypeParameter == name.Name) {
-                                                       constraints = constraint;
+                                               }
+                                               if (constraints_at.TypeParameter == name.Name) {
+                                                       constraints = constraints_at;
+                                                       constraints_list.RemoveAt(ii);
                                                        break;
                                                }
                                        }
@@ -1276,6 +1214,13 @@ namespace Mono.CSharp {
 
                                AddToContainer (type_params [i], name.Name);
                        }
+
+                       if (constraints_list != null && constraints_list.Count > 0) {
+                               foreach (Constraints constraint in constraints_list) {
+                                       Report.Error(699, constraint.Location, "`{0}': A constraint references nonexistent type parameter `{1}'", 
+                                               GetSignatureForError (), constraint.TypeParameter);
+                               }
+                       }
                }
 
                public TypeParameter[] TypeParameters {
@@ -1317,11 +1262,15 @@ namespace Mono.CSharp {
                        if (!IsGeneric)
                                return null;
 
-                       foreach (TypeParameter type_param in CurrentTypeParameters) {
-                               if (type_param.Name != name)
-                                       continue;
+                       TypeParameter [] current_params;
+                       if (this is TypeContainer)
+                               current_params = PartialContainer.CurrentTypeParameters;
+                       else
+                               current_params = CurrentTypeParameters;
 
-                               return new TypeParameterExpr (type_param, loc);
+                       foreach (TypeParameter type_param in current_params) {
+                               if (type_param.Name == name)
+                                       return new TypeParameterExpr (type_param, loc);
                        }
 
                        if (Parent != null)
@@ -1334,9 +1283,9 @@ namespace Mono.CSharp {
                        get { return attribute_targets; }
                }
 
-               protected override bool VerifyClsCompliance (DeclSpace ds)
+               protected override bool VerifyClsCompliance ()
                {
-                       if (!base.VerifyClsCompliance (ds)) {
+                       if (!base.VerifyClsCompliance ()) {
                                return false;
                        }
 
@@ -1355,9 +1304,6 @@ namespace Mono.CSharp {
                                Report.SymbolRelatedToPreviousError (t);
                        }
                        else {
-                               if (val is PartialContainer)
-                                       return true;
-
                                Report.SymbolRelatedToPreviousError ((DeclSpace)val);
                        }
                        Report.Warning (3005, 1, Location, "Identifier `{0}' differing only in case is not CLS-compliant", GetSignatureForError ());
@@ -1645,7 +1591,7 @@ namespace Mono.CSharp {
                /// <summary>
                ///   Bootstrap this member cache by doing a deep-copy of our base.
                /// </summary>
-               Hashtable SetupCache (MemberCache base_class)
+               static Hashtable SetupCache (MemberCache base_class)
                {
                        Hashtable hash = new Hashtable ();
 
@@ -1997,6 +1943,7 @@ namespace Mono.CSharp {
 
                        IMemberContainer current = Container;
 
+                       bool do_interface_search = current.IsInterface;
 
                        // `applicable' is a list of all members with the given member name `name'
                        // in the current class and all its base classes.  The list is sorted in
@@ -2012,7 +1959,10 @@ namespace Mono.CSharp {
                                // iteration of this loop if there are no members with the name we're
                                // looking for in the current class).
                                if (entry.Container != current) {
-                                       if (declared_only || DoneSearching (global))
+                                       if (declared_only)
+                                               break;
+
+                                       if (!do_interface_search && DoneSearching (global))
                                                break;
 
                                        current = entry.Container;
@@ -2028,8 +1978,28 @@ namespace Mono.CSharp {
 
                                // Apply the filter to it.
                                if (filter (entry.Member, criteria)) {
-                                       if ((entry.EntryType & EntryType.MaskType) != EntryType.Method)
+                                       if ((entry.EntryType & EntryType.MaskType) != EntryType.Method) {
                                                do_method_search = false;
+                                       }
+                                       
+                                       // Because interfaces support multiple inheritance we have to be sure that
+                                       // base member is from same interface, so only top level member will be returned
+                                       if (do_interface_search && global.Count > 0) {
+                                               bool member_already_exists = false;
+
+                                               foreach (MemberInfo mi in global) {
+                                                       if (mi is MethodBase)
+                                                               continue;
+
+                                                       if (IsInterfaceBaseInterface (TypeManager.GetInterfaces (mi.DeclaringType), entry.Member.DeclaringType)) {
+                                                               member_already_exists = true;
+                                                               break;
+                                                       }
+                                               }
+                                               if (member_already_exists)
+                                                       continue;
+                                       }
+
                                        global.Add (entry.Member);
                                }
                        }
@@ -2051,6 +2021,22 @@ namespace Mono.CSharp {
                        global.CopyTo (copy);
                        return copy;
                }
+
+               /// <summary>
+               /// Returns true if iterface exists in any base interfaces (ifaces)
+               /// </summary>
+               static bool IsInterfaceBaseInterface (Type[] ifaces, Type ifaceToFind)
+               {
+                       foreach (Type iface in ifaces) {
+                               if (iface == ifaceToFind)
+                                       return true;
+
+                               Type[] base_ifaces = TypeManager.GetInterfaces (iface);
+                               if (base_ifaces.Length > 0 && IsInterfaceBaseInterface (base_ifaces, ifaceToFind))
+                                       return true;
+                       }
+                       return false;
+               }
                
                // find the nested type @name in @this.
                public Type FindNestedType (string name)
@@ -2323,7 +2309,9 @@ namespace Mono.CSharp {
                /// <summary>
                /// Cls compliance check whether methods or constructors parameters differing only in ref or out, or in array rank
                /// </summary>
-               public void VerifyClsParameterConflict (ArrayList al, MethodCore method, MemberInfo this_builder)
+               /// 
+               // TODO: refactor as method is always 'this'
+               public static void VerifyClsParameterConflict (ArrayList al, MethodCore method, MemberInfo this_builder)
                {
                        EntryType tested_type = (method is Constructor ? EntryType.Constructor : EntryType.Method) | EntryType.Public;