Author: marek
Date: 2008-02-21 04:52:40 -0500 (Thu, 21 Feb 2008)
New Revision: 96328

Modified:
   trunk/mcs/mcs/ChangeLog
   trunk/mcs/mcs/class.cs
   trunk/mcs/mcs/typemanager.cs
Log:
2008-02-21  Marek Safar  <[EMAIL PROTECTED]>

        * class.cs, typemanager.cs: Rewrote operator matching logic to correctly
        handle missing matches when mutiple operators exist.
        


Modified: trunk/mcs/mcs/ChangeLog
===================================================================
--- trunk/mcs/mcs/ChangeLog     2008-02-21 09:42:00 UTC (rev 96327)
+++ trunk/mcs/mcs/ChangeLog     2008-02-21 09:52:40 UTC (rev 96328)
@@ -1,3 +1,8 @@
+2008-02-21  Marek Safar  <[EMAIL PROTECTED]>
+
+       * class.cs, typemanager.cs: Rewrote operator matching logic to correctly
+       handle missing matches when mutiple operators exist.
+       
 2008-02-20  Marek Safar  <[EMAIL PROTECTED]>
 
        A fix for bug #363218

Modified: trunk/mcs/mcs/class.cs
===================================================================
--- trunk/mcs/mcs/class.cs      2008-02-21 09:42:00 UTC (rev 96327)
+++ trunk/mcs/mcs/class.cs      2008-02-21 09:52:40 UTC (rev 96328)
@@ -97,48 +97,6 @@
                        }
 
                        //
-                       // Operator pair checking
-                       //
-                       class OperatorEntry
-                       {
-                               public int flags;
-                               public Type ret_type;
-                               public Type type1, type2;
-                               public Operator op;
-                               public Operator.OpType ot;
-                               
-                               public OperatorEntry (int f, Operator o)
-                               {
-                                       flags = f;
-
-                                       ret_type = o.MemberType;
-                                       Type [] pt = o.ParameterTypes;
-                                       type1 = pt [0];
-                                       type2 = pt [1];
-                                       op = o;
-                                       ot = o.OperatorType;
-                               }
-
-                               public override int GetHashCode ()
-                               {       
-                                       return ret_type.GetHashCode ();
-                               }
-
-                               public override bool Equals (object o)
-                               {
-                                       OperatorEntry other = (OperatorEntry) o;
-
-                                       if (other.ret_type != ret_type)
-                                               return false;
-                                       if (other.type1 != type1)
-                                               return false;
-                                       if (other.type2 != type2)
-                                               return false;
-                                       return true;
-                               }
-                       }
-                               
-                       //
                        // Checks that some operators come in pairs:
                        //  == and !=
                        // > and <
@@ -149,101 +107,53 @@
                        //
                        void CheckPairedOperators ()
                        {
-                               IDictionary pairs = new HybridDictionary ();
-                               Operator true_op = null;
-                               Operator false_op = null;
                                bool has_equality_or_inequality = false;
-                               
-                               // Register all the operators we care about.
-                               foreach (Operator op in this){
-                                       int reg = 0;
+                               Operator[] operators = (Operator[]) ToArray 
(typeof (Operator));
+                               bool [] has_pair = new bool [operators.Length];
 
-                                       // Skip erroneous code.
-                                       if (op.MethodBuilder == null)
+                               for (int i = 0; i < Count; ++i) {
+                                       if (operators [i] == null)
                                                continue;
 
-                                       switch (op.OperatorType){
-                                       case Operator.OpType.Equality:
-                                               reg = 1;
+                                       Operator o_a = operators [i];
+                                       Operator.OpType o_type = 
o_a.OperatorType;
+                                       if (o_type == Operator.OpType.Equality 
|| o_type == Operator.OpType.Inequality)
                                                has_equality_or_inequality = 
true;
-                                               break;
-                                       case Operator.OpType.Inequality:
-                                               reg = 2;
-                                               has_equality_or_inequality = 
true;
-                                               break;
 
-                                       case Operator.OpType.True:
-                                               true_op = op;
-                                               break;
-                                       case Operator.OpType.False:
-                                               false_op = op;
-                                               break;
-                                               
-                                       case Operator.OpType.GreaterThan:
-                                               reg = 1; break;
-                                       case Operator.OpType.LessThan:
-                                               reg = 2; break;
-                                               
-                                       case Operator.OpType.GreaterThanOrEqual:
-                                               reg = 1; break;
-                                       case Operator.OpType.LessThanOrEqual:
-                                               reg = 2; break;
-                                       }
-                                       if (reg == 0)
+                                       Operator.OpType matching_type = 
o_a.GetMatchingOperator ();
+                                       if (matching_type == 
Operator.OpType.TOP) {
+                                               operators [i] = null;
                                                continue;
+                                       }
+       
+                                       for (int ii = 0; ii < Count; ++ii) {
+                                               Operator o_b = operators [ii];
+                                               if (o_b == null || 
o_b.OperatorType != matching_type)
+                                                       continue;
 
-                                       OperatorEntry oe = new OperatorEntry 
(reg, op);
+                                               if (!TypeManager.IsEqual 
(o_a.ReturnType, o_b.ReturnType))
+                                                       continue;
 
-                                       object o = pairs [oe];
-                                       if (o == null)
-                                               pairs [oe] = oe;
-                                       else {
-                                               oe = (OperatorEntry) o;
-                                               oe.flags |= reg;
+                                               if (!TypeManager.IsEqual 
(o_a.ParameterTypes, o_b.ParameterTypes))
+                                                       continue;
+
+                                               operators [i] = null;
+
+                                               //
+                                               // Used to ignore duplicate 
user conversions
+                                               //
+                                               has_pair [ii] = true;
                                        }
                                }
 
-                               if (true_op != null){
-                                       if (false_op == null)
-                                               Report.Error (216, 
true_op.Location, "The operator `{0}' requires a matching operator `false' to 
also be defined",
-                                                       
true_op.GetSignatureForError ());
-                               } else if (false_op != null)
-                                       Report.Error (216, false_op.Location, 
"The operator `{0}' requires a matching operator `true' to also be defined",
-                                               false_op.GetSignatureForError 
());
-                               
-                               //
-                               // Look for the mistakes.
-                               //
-                               foreach (DictionaryEntry de in pairs){
-                                       OperatorEntry oe = (OperatorEntry) 
de.Key;
-
-                                       if (oe.flags == 3)
+                               for (int i = 0; i < Count; ++i) {
+                                       if (operators [i] == null || has_pair 
[i])
                                                continue;
 
-                                       string s = "";
-                                       switch (oe.ot){
-                                       case Operator.OpType.Equality:
-                                               s = "!=";
-                                               break;
-                                       case Operator.OpType.Inequality: 
-                                               s = "==";
-                                               break;
-                                       case Operator.OpType.GreaterThan: 
-                                               s = "<";
-                                               break;
-                                       case Operator.OpType.LessThan:
-                                               s = ">";
-                                               break;
-                                       case Operator.OpType.GreaterThanOrEqual:
-                                               s = "<=";
-                                               break;
-                                       case Operator.OpType.LessThanOrEqual:
-                                               s = ">=";
-                                               break;
-                                       }
-                                       Report.Error (216, oe.op.Location,
+                                       Operator o = operators [i];
+                                       Report.Error (216, o.Location,
                                                "The operator `{0}' requires a 
matching operator `{1}' to also be defined",
-                                               oe.op.GetSignatureForError (), 
s);
+                                               o.GetSignatureForError (), 
Operator.GetName (o.GetMatchingOperator ()));
                                }
 
                                if (has_equality_or_inequality && 
Report.WarningLevel > 2) {
@@ -8187,6 +8097,30 @@
                        }
                }
 
+               public OpType GetMatchingOperator ()
+               {
+                       switch (OperatorType) {
+                               case OpType.Equality:
+                                       return OpType.Inequality;
+                               case OpType.Inequality:
+                                       return OpType.Equality;
+                               case OpType.True:
+                                       return OpType.False;
+                               case OpType.False:
+                                       return OpType.True;
+                               case OpType.GreaterThan:
+                                       return OpType.LessThan;
+                               case OpType.LessThan:
+                                       return OpType.GreaterThan;
+                               case OpType.GreaterThanOrEqual:
+                                       return OpType.LessThanOrEqual;
+                               case OpType.LessThanOrEqual:
+                                       return OpType.GreaterThanOrEqual;
+                               default:
+                                       return OpType.TOP;
+                       }
+               }
+
                public static OpType GetOperatorType (string name)
                {
                        if (name.StartsWith ("op_")){

Modified: trunk/mcs/mcs/typemanager.cs
===================================================================
--- trunk/mcs/mcs/typemanager.cs        2008-02-21 09:42:00 UTC (rev 96327)
+++ trunk/mcs/mcs/typemanager.cs        2008-02-21 09:52:40 UTC (rev 96328)
@@ -2817,6 +2817,19 @@
                return false;
        }
 
+       public static bool IsEqual (Type[] a, Type[] b)
+       {
+               if (a.Length != b.Length)
+                       return false;
+
+               for (int i = 0; i < a.Length; ++i) {
+                       if (!IsEqual (a [i], b [i]))
+                               return false;
+               }
+
+               return true;
+       }
+
        public static Type DropGenericTypeArguments (Type t)
        {
 #if GMCS_SOURCE

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to