2007-03-21 Bill Holmes <billholmes54@gmail.com>
authorBill Holmes <holmes@mono-cvs.ximian.com>
Wed, 21 Mar 2007 16:36:09 +0000 (16:36 -0000)
committerBill Holmes <holmes@mono-cvs.ximian.com>
Wed, 21 Mar 2007 16:36:09 +0000 (16:36 -0000)
In mcs :
        * class.cs:
        Added 2 MemberCoreArrayList objects, ordered_explicit_member_list and
        ordered_member_list, to TypeBuilder to store members to be defined
        in the order they were parsed in.
        - ordered_explicit_member_list contains all properties indexers
          and methods that are defined as explicit implementation of an
          interface or base class.
        - ordered_member_list contains all properties indexers and methods
          that are not defined as explicit implementation of an interface
          or base class.

        Removed MethodArrayList and IndexerArrayList from TypeBuilder.  The
        functionality in these removed classes has been replaced with
        ComputeIndexerName, EmitIndexerName, HasEqualss, HasGetHashCode, and
        CheckEqualsAndGetHashCode members defined and called in the TypeBuilderClass.

        Adding CheckForDuplications to PropertyBase.PropertyMethod and calls
        to CheckForDuplications inside GetMethod and SetMethod Define Method
        to handle method property and indexer name conflicts.

In errors :
        * gcs0111-2.cs:
        With the new member ordering change in class.cs, the error message
        for this test has changed and now matches csc output.

        Fixes #79434

        All code is contributed under the MIT/X11 license.

svn path=/trunk/mcs/; revision=74749

mcs/errors/ChangeLog
mcs/errors/gcs0111-2.cs
mcs/mcs/ChangeLog
mcs/mcs/class.cs

index e3a7d4cb7c4abe0b72edbca45094a641a22ccb27..12bb0330e2c3f1c9711abcb633e98e0a1f4ea5fe 100644 (file)
@@ -1,3 +1,12 @@
+2007-03-21  Bill Holmes  <billholmes54@gmail.com>
+       * gcs0111-2.cs:
+       With the new member ordering change in class.cs, the error message
+       for this test has changed and now matches csc output.
+
+       For Defect #79434
+
+       All code is contributed under the MIT/X11 license.
+
 2007-03-21  Bill Holmes  <billholmes54@gmail.com>
 
        * cs3005-6.cs
index 28b9788657bfc07e51901914bb4095067b94d162..42a706fc0b6276a616b1134e831055b73d25d29e 100644 (file)
@@ -1,4 +1,4 @@
-// gcs0111-2.cs: `Blah.I.M<T>(int)' is already defined. Rename this member or use different parameter types\r
+// gcs0111-2.cs: `Blah.I.M<U>(int)' is already defined. Rename this member or use different parameter types\r
 // Line : 12\r
 \r
 public interface I\r
index 85dd39e2edab47ac887740a8780b75b945a31e6b..e028786d169f6840949d14f33562e6c845d8ad76 100644 (file)
@@ -1,3 +1,28 @@
+2007-03-20  Bill Holmes  <billholmes54@gmail.com>
+       * class.cs: 
+       Added 2 MemberCoreArrayList objects, ordered_explicit_member_list and
+       ordered_member_list, to TypeBuilder to store members to be defined
+       in the order they were parsed in.
+       - ordered_explicit_member_list contains all properties indexers
+         and methods that are defined as explicit implementation of an
+         interface or base class.
+       - ordered_member_list contains all properties indexers and methods
+         that are not defined as explicit implementation of an interface
+         or base class.
+
+       Removed MethodArrayList and IndexerArrayList from TypeBuilder.  The 
+       functionality in these removed classes has been replaced with 
+       ComputeIndexerName, EmitIndexerName, HasEqualss, HasGetHashCode, and 
+       CheckEqualsAndGetHashCode members defined and called in the TypeBuilderClass.
+
+       Adding CheckForDuplications to PropertyBase.PropertyMethod and calls
+       to CheckForDuplications inside GetMethod and SetMethod Define Method
+       to handle method property and indexer name conflicts.
+
+       Fixes #79434
+
+       All code is contributed under the MIT/X11 license.
+
 2007-03-20  Martin Baulig  <martin@ximian.com>
 
        * class.cs (TypeContainer.Interfaces): Removed; they're now
index bcd54ec6608c536a7686895340d87aea89a6912e..fb7ed4b7131b38342b50216bdaaa50daa55aed8f 100644 (file)
@@ -88,130 +88,6 @@ namespace Mono.CSharp {
                        }
                }
 
-               public class MethodArrayList : MemberCoreArrayList
-               {
-                       [Flags]
-                       enum CachedMethods {
-                               Equals                  = 1,
-                               GetHashCode             = 1 << 1
-                       }
-                       CachedMethods cached_method;
-                       TypeContainer container;
-
-                       public MethodArrayList (TypeContainer container)
-                       {
-                               this.container = container;
-                       }
-                       /// <summary>
-                       /// Method container contains Equals method
-                       /// </summary>
-                       public bool HasEquals {
-                               set {
-                                       cached_method |= CachedMethods.Equals;
-                               }
-                               get {
-                                       return (cached_method & CachedMethods.Equals) != 0;
-                               }
-                       }
-                       /// <summary>
-                       /// Method container contains GetHashCode method
-                       /// </summary>
-                       public bool HasGetHashCode {
-                               set {
-                                       cached_method |= CachedMethods.GetHashCode;
-                               }
-                               get {
-                                       return (cached_method & CachedMethods.GetHashCode) != 0;
-                               }
-                       }
-                       public override void DefineContainerMembers ()
-                       {
-                               base.DefineContainerMembers ();
-                               if (HasEquals && !HasGetHashCode) {
-                                       Report.Warning (659, 3, container.Location, "`{0}' overrides Object.Equals(object) but does not override Object.GetHashCode()", container.GetSignatureForError ());
-                               }
-                       }
-               }
-
-               public sealed class IndexerArrayList : MemberCoreArrayList
-               {
-                       /// <summary>
-                       /// The indexer name for this container
-                       /// </summary>
-                       public string IndexerName = DefaultIndexerName;
-
-                       bool seen_normal_indexers = false;
-
-                       TypeContainer container;
-
-                       public IndexerArrayList (TypeContainer container)
-                       {
-                               this.container = container;
-                       }
-
-                       /// <summary>
-                       /// Defines the indexers, and also verifies that the IndexerNameAttribute in the
-                       /// class is consistent.  Either it is `Item' or it is the name defined by all the
-                       /// indexers with the `IndexerName' attribute.
-                       ///
-                       /// Turns out that the IndexerNameAttribute is applied to each indexer,
-                       /// but it is never emitted, instead a DefaultMember attribute is attached
-                       /// to the class.
-                       /// </summary>
-                       public override void DefineContainerMembers()
-                       {
-                               base.DefineContainerMembers ();
-
-                               string class_indexer_name = null;
-
-                               //
-                               // If there's both an explicit and an implicit interface implementation, the
-                               // explicit one actually implements the interface while the other one is just
-                               // a normal indexer.  See bug #37714.
-                               //
-
-                               // Invariant maintained by AddIndexer(): All explicit interface indexers precede normal indexers
-                               foreach (Indexer i in this) {
-                                       if (i.InterfaceType != null) {
-                                               if (seen_normal_indexers)
-                                                       throw new Exception ("Internal Error: 'Indexers' array not sorted properly.");
-                                               continue;
-                                       }
-
-                                       seen_normal_indexers = true;
-
-                                       if (class_indexer_name == null) {
-                                               class_indexer_name = i.ShortName;
-                                               continue;
-                                       }
-
-                                       if (i.ShortName != class_indexer_name)
-                                               Report.Error (668, i.Location, "Two indexers have different names; the IndexerName attribute must be used with the same name on every indexer within a type");
-                               }
-
-                               if (class_indexer_name != null)
-                                       IndexerName = class_indexer_name;
-                       }
-
-                       public override void Emit ()
-                       {
-                               base.Emit ();
-
-                               if (!seen_normal_indexers)
-                                       return;
-
-                               CustomAttributeBuilder cb = new CustomAttributeBuilder (TypeManager.default_member_ctor, new string [] { IndexerName });
-                               container.TypeBuilder.SetCustomAttribute (cb);
-                       }
-               }
-
                public class OperatorArrayList: MemberCoreArrayList
                {
                        TypeContainer container;
@@ -372,10 +248,10 @@ namespace Mono.CSharp {
                                }
 
                                if (has_equality_or_inequality && (RootContext.WarningLevel > 2)) {
-                                       if (container.Methods == null || !container.Methods.HasEquals)
+                                       if (container.Methods == null || !container.HasEquals)
                                                Report.Warning (660, 2, container.Location, "`{0}' defines operator == or operator != but does not override Object.Equals(object o)", container.GetSignatureForError ());
  
-                                       if (container.Methods == null || !container.Methods.HasGetHashCode)
+                                       if (container.Methods == null || !container.HasGetHashCode)
                                                Report.Warning (661, 2, container.Location, "`{0}' defines operator == or operator != but does not override Object.GetHashCode()", container.GetSignatureForError ());
                                }
                        }
@@ -387,6 +263,12 @@ namespace Mono.CSharp {
                        }
                }
 
+               [Flags]
+               enum CachedMethods {
+                       Equals                  = 1,
+                       GetHashCode             = 1 << 1
+               }
+
 
                // Whether this is a struct, class or interface
                public readonly Kind Kind;
@@ -394,6 +276,9 @@ namespace Mono.CSharp {
                // Holds a list of classes and structures
                protected ArrayList types;
 
+               MemberCoreArrayList ordered_explicit_member_list;
+               MemberCoreArrayList ordered_member_list;
+
                // Holds the list of properties
                MemberCoreArrayList properties;
 
@@ -416,13 +301,13 @@ namespace Mono.CSharp {
                MemberCoreArrayList constants;
 
                // Holds the methods.
-               MethodArrayList methods;
+               MemberCoreArrayList methods;
 
                // Holds the events
                protected MemberCoreArrayList events;
 
                // Holds the indexers
-               IndexerArrayList indexers;
+               ArrayList indexers;
 
                // Holds the operators
                MemberCoreArrayList operators;
@@ -468,6 +353,11 @@ namespace Mono.CSharp {
 
                public const string DefaultIndexerName = "Item";
 
+               private bool seen_normal_indexers = false;
+               private string indexer_name = DefaultIndexerName;
+
+               private CachedMethods cached_method;
+
 #if GMCS_SOURCE
                GenericTypeParameterBuilder[] gen_params;
 #endif
@@ -603,18 +493,36 @@ namespace Mono.CSharp {
                        delegates.Add (d);
                }
 
+               private void AddMemberToList (MemberCore mc, ArrayList alist, bool isexplicit)
+               {
+                       if (ordered_explicit_member_list == null)  {
+                               ordered_explicit_member_list = new MemberCoreArrayList ();
+                               ordered_member_list = new MemberCoreArrayList ();
+                       }
+
+                       if(isexplicit) {
+                               ordered_explicit_member_list.Add (mc);
+                               alist.Insert (0, mc);
+                       } 
+                       else {
+                               ordered_member_list.Add (mc);
+                               alist.Add (mc);
+                       }
+
+               }
+               
                public void AddMethod (Method method)
                {
                        if (!AddMember (method))
                                return;
 
                        if (methods == null)
-                               methods = new MethodArrayList (this);
-                       
-                       if (method.MemberName.Left != null)
-                               methods.Insert (0, method);
+                               methods = new MemberCoreArrayList ();
+
+                       if (method.MemberName.Left != null) 
+                               AddMemberToList (method, methods, true);
                        else 
-                               methods.Add (method);
+                               AddMemberToList (method, methods, false);
                }
 
                //
@@ -628,9 +536,9 @@ namespace Mono.CSharp {
                                return;
 
                        if (methods == null)
-                               methods = new MethodArrayList (this);
+                               methods = new MemberCoreArrayList ();
 
-                       methods.Add (method);
+                       AddMemberToList (method, methods, false);
                }
 
                public void AddConstructor (Constructor c)
@@ -710,9 +618,9 @@ namespace Mono.CSharp {
                                properties = new MemberCoreArrayList ();
 
                        if (prop.MemberName.Left != null)
-                               properties.Insert (0, prop);
-                       else
-                               properties.Add (prop);
+                               AddMemberToList (prop, properties, true);
+                       else 
+                               AddMemberToList (prop, properties, false);
                }
 
                public void AddEvent (Event e)
@@ -740,12 +648,12 @@ namespace Mono.CSharp {
                public void AddIndexer (Indexer i)
                {
                        if (indexers == null)
-                               indexers = new IndexerArrayList (this);
+                               indexers = new ArrayList ();
 
                        if (i.IsExplicitImpl)
-                               indexers.Insert (0, i);
-                       else
-                               indexers.Add (i);
+                               AddMemberToList (i, indexers, true);
+                       else 
+                               AddMemberToList (i, indexers, false);
                }
 
                public void AddOperator (Operator op)
@@ -793,7 +701,7 @@ namespace Mono.CSharp {
                        }
                }
 
-               public MethodArrayList Methods {
+               public MemberCoreArrayList Methods {
                        get {
                                return methods;
                        }
@@ -877,7 +785,7 @@ namespace Mono.CSharp {
 
                public string IndexerName {
                        get {
-                               return indexers == null ? DefaultIndexerName : indexers.IndexerName;
+                               return indexers == null ? DefaultIndexerName : indexer_name;
                        }
                }
 
@@ -1631,13 +1539,16 @@ namespace Mono.CSharp {
                        //
                        DefineContainerMembers (instance_constructors);
                
-                       DefineContainerMembers (properties);
                        DefineContainerMembers (events);
-                       DefineContainerMembers (indexers);
-                       DefineContainerMembers (methods);
+                       DefineContainerMembers (ordered_explicit_member_list);
+                       DefineContainerMembers (ordered_member_list);
+
                        DefineContainerMembers (operators);
                        DefineContainerMembers (delegates);
 
+                       ComputeIndexerName();
+                       CheckEqualsAndGetHashCode();
+
                        if (CurrentType != null) {
                                GenericType = CurrentType;
                        }
@@ -1658,6 +1569,61 @@ namespace Mono.CSharp {
                        if (mcal != null)
                                mcal.DefineContainerMembers ();
                }
+               
+               protected virtual void ComputeIndexerName ()
+               {
+                       if (indexers == null)
+                               return;
+
+                       string class_indexer_name = null;
+
+                       //
+                       // If there's both an explicit and an implicit interface implementation, the
+                       // explicit one actually implements the interface while the other one is just
+                       // a normal indexer.  See bug #37714.
+                       //
+
+                       // Invariant maintained by AddIndexer(): All explicit interface indexers precede normal indexers
+                       foreach (Indexer i in indexers) {
+                               if (i.InterfaceType != null) {
+                                       if (seen_normal_indexers)
+                                               throw new Exception ("Internal Error: 'Indexers' array not sorted properly.");
+                                       continue;
+                               }
+
+                               seen_normal_indexers = true;
+
+                               if (class_indexer_name == null) {
+                                       class_indexer_name = i.ShortName;
+                                       continue;
+                               }
+
+                               if (i.ShortName != class_indexer_name)
+                                       Report.Error (668, i.Location, "Two indexers have different names; the IndexerName attribute must be used with the same name on every indexer within a type");
+                       }
+
+                       if (class_indexer_name != null)
+                               indexer_name = class_indexer_name;
+               }
+
+               protected virtual void EmitIndexerName ()
+               {
+                       if (!seen_normal_indexers)
+                               return;
+
+                       CustomAttributeBuilder cb = new CustomAttributeBuilder (TypeManager.default_member_ctor, new string [] { IndexerName });
+                       TypeBuilder.SetCustomAttribute (cb);
+               }
+
+               protected virtual void CheckEqualsAndGetHashCode ()
+               {
+                       if (methods == null)
+                               return;
+
+                       if (HasEquals && !HasGetHashCode) {
+                               Report.Warning (659, 3, this.Location, "`{0}' overrides Object.Equals(object) but does not override Object.GetHashCode()", this.GetSignatureForError ());
+                       }
+               }
 
                public override bool Define ()
                {
@@ -2363,8 +2329,10 @@ namespace Mono.CSharp {
                                foreach (Property p in properties)
                                        p.Emit ();
 
-                       if (indexers != null){
-                               indexers.Emit ();
+                       if (indexers != null) {
+                               foreach (Indexer indx in indexers)
+                                       indx.Emit ();
+                               EmitIndexerName ();
                        }
                        
                        if (fields != null)
@@ -2442,6 +2410,8 @@ namespace Mono.CSharp {
                        initialized_fields = null;
                        initialized_static_fields = null;
                        constants = null;
+                       ordered_explicit_member_list = null;
+                       ordered_member_list = null;
                        methods = null;
                        events = null;
                        indexers = null;
@@ -2642,12 +2612,30 @@ namespace Mono.CSharp {
 
                public void Mark_HasEquals ()
                {
-                       Methods.HasEquals = true;
+                       cached_method |= CachedMethods.Equals;
                }
 
                public void Mark_HasGetHashCode ()
                {
-                       Methods.HasGetHashCode = true;
+                       cached_method |= CachedMethods.GetHashCode;
+               }
+
+               /// <summary>
+               /// Method container contains Equals method
+               /// </summary>
+               public bool HasEquals {
+                       get {
+                               return (cached_method & CachedMethods.Equals) != 0;
+                       }
+               }
+               /// <summary>
+               /// Method container contains GetHashCode method
+               /// </summary>
+               public bool HasGetHashCode {
+                       get {
+                               return (cached_method & CachedMethods.GetHashCode) != 0;
+                       }
                }
 
                //
@@ -6335,7 +6323,7 @@ namespace Mono.CSharp {
 
                        Type[] param_types = method.ParameterTypes;
 
-                       if (param_types.Length != ParameterTypes.Length)
+                       if (param_types == null || param_types.Length != ParameterTypes.Length)
                                return false;
 
                        for (int i = 0; i < param_types.Length; i++)
@@ -6399,6 +6387,12 @@ namespace Mono.CSharp {
 
                        public override MethodBuilder Define (DeclSpace parent)
                        {
+                               if (!CheckForDuplications ())
+                                       return null;
+
+                               if (IsDummy)
+                                       return null;
+                               
                                base.Define (parent);
                                
                                method_data = new MethodData (method, ModFlags, flags, this);
@@ -6474,6 +6468,9 @@ namespace Mono.CSharp {
 
                        public override MethodBuilder Define (DeclSpace parent)
                        {
+                               if (!CheckForDuplications ())
+                                       return null;
+                               
                                if (IsDummy)
                                        return null;
 
@@ -6657,6 +6654,25 @@ namespace Mono.CSharp {
                                caching_flags |= Flags.TestMethodDuplication;
                                return true;
                        }
+
+                       protected bool CheckForDuplications () 
+                       {
+                               if ((caching_flags & Flags.TestMethodDuplication) == 0)
+                                       return true;
+                               
+                               ArrayList ar = Parent.PartialContainer.Methods;
+                               if (ar != null) {
+                                       int arLen = ar.Count;
+                                       
+                                       for (int i = 0; i < arLen; i++) {
+                                               Method m = (Method) ar [i];
+                                               if (IsDuplicateImplementation (m))
+                                                       return false;
+                                       }
+                               }
+
+                               return true;
+                       }
                }
 
                public PropertyMethod Get, Set;
@@ -6732,20 +6748,17 @@ namespace Mono.CSharp {
 
                bool DefineGet ()
                {
-                       if (Get.IsDummy)
-                               return true;
-
                        GetBuilder = Get.Define (Parent);
-                       return GetBuilder != null;
+                       return (Get.IsDummy) ? true : GetBuilder != null;
                }
 
                bool DefineSet (bool define)
                {
-                       if (!define || Set.IsDummy)
+                       if (!define)
                                return true;
 
                        SetBuilder = Set.Define (Parent);
-                       return SetBuilder != null;
+                       return (Set.IsDummy) ? true : SetBuilder != null;
                }
 
                protected bool DefineAccessors ()