2007-01-10 Chris Toshok <toshok@ximian.com>
[mono.git] / mcs / mcs / ecore.cs
index 8f5398ecae40462e50a8ee6fdc5687452b9491c3..69c937ce0d956b0a008aff432cc9d06c0c0095eb 100644 (file)
@@ -313,7 +313,7 @@ namespace Mono.CSharp {
                        Report.Error (1547, loc, "Keyword `void' cannot be used in this context");
                }
 
-               public virtual void Error_ValueCannotBeConverted (Location loc, Type target, bool expl)
+               public virtual void Error_ValueCannotBeConverted (EmitContext ec, Location loc, Type target, bool expl)
                {
                        if (Type.FullName == target.FullName){
                                Report.ExtraInformation (loc,
@@ -332,9 +332,13 @@ namespace Mono.CSharp {
                        Expression e = (this is EnumConstant) ? ((EnumConstant)this).Child : this;
                        bool b = Convert.ExplicitNumericConversion (e, target) != null;
 
-                       if (b || Convert.ExplicitReferenceConversionExists (Type, target) ||
-                               Convert.ExplicitUnsafe (e, target) != null || Convert.UserDefinedConversion (null, this, target, Location.Null, true) != null) {
-                               Report.Error (266, loc, "Cannot implicitly convert type `{0}' to `{1}'. An explicit conversion exists (are you missing a cast?)",
+                       if (b ||
+                           Convert.ExplicitReferenceConversionExists (Type, target) ||
+                           Convert.ExplicitUnsafe (e, target) != null ||
+                           (ec != null && Convert.UserDefinedConversion (ec, this, target, Location.Null, true) != null))
+                       {
+                               Report.Error (266, loc, "Cannot implicitly convert type `{0}' to `{1}'. " +
+                                             "An explicit conversion exists (are you missing a cast?)",
                                        TypeManager.CSharpName (Type), TypeManager.CSharpName (target));
                                return;
                        }
@@ -887,7 +891,7 @@ namespace Mono.CSharp {
                        //
                        converted = Expression.GetOperatorTrue (ec, e, loc);
                        if (converted == null){
-                               e.Error_ValueCannotBeConverted (loc, TypeManager.bool_type, false);
+                               e.Error_ValueCannotBeConverted (ec, loc, TypeManager.bool_type, false);
                                return null;
                        }
                        return converted;
@@ -1106,7 +1110,7 @@ namespace Mono.CSharp {
                                        target = Convert.ImplicitConversion (ec, source, TypeManager.uint64_type, loc);
 
                                if (target == null) {
-                                       source.Error_ValueCannotBeConverted (loc, TypeManager.int32_type, false);
+                                       source.Error_ValueCannotBeConverted (ec, loc, TypeManager.int32_type, false);
                                        return null;
                                }
                        }
@@ -1387,9 +1391,9 @@ namespace Mono.CSharp {
                        return child.GetValue ();
                }
 
-               public override Constant Reduce (bool inCheckedContext, Type target_type)
+               public override Constant ConvertExplicitly (bool inCheckedContext, Type target_type)
                {
-                       return child.Reduce (inCheckedContext, target_type);
+                       return child.ConvertExplicitly (inCheckedContext, target_type);
                }
 
                public override Constant Increment ()
@@ -1412,9 +1416,9 @@ namespace Mono.CSharp {
                        child.Emit (ec);
                }
 
-               public override Constant ToType (Type type)
+               public override Constant ConvertImplicitly (Type type)
                {
-                       return child.ToType (type);
+                       return child.ConvertImplicitly (type);
                }
        }
 
@@ -1474,37 +1478,8 @@ namespace Mono.CSharp {
                
                public override string AsString ()
                {
-                       return Child.AsString ();
-               }
-
-               public override DoubleConstant ConvertToDouble ()
-               {
-                       return Child.ConvertToDouble ();
-               }
-
-               public override FloatConstant ConvertToFloat ()
-               {
-                       return Child.ConvertToFloat ();
-               }
-
-               public override ULongConstant ConvertToULong ()
-               {
-                       return Child.ConvertToULong ();
-               }
-
-               public override LongConstant ConvertToLong ()
-               {
-                       return Child.ConvertToLong ();
-               }
-
-               public override UIntConstant ConvertToUInt ()
-               {
-                       return Child.ConvertToUInt ();
-               }
-
-               public override IntConstant ConvertToInt ()
-               {
-                       return Child.ConvertToInt ();
+                       string value = System.Enum.GetName (type, Child.GetValue ());
+                       return value == null ? "0" : value;
                }
 
                public override Constant Increment()
@@ -1528,15 +1503,15 @@ namespace Mono.CSharp {
                        }
                }
 
-               public override Constant Reduce(bool inCheckedContext, Type target_type)
+               public override Constant ConvertExplicitly(bool inCheckedContext, Type target_type)
                {
                        if (Child.Type == target_type)
                                return Child;
 
-                       return Child.Reduce (inCheckedContext, target_type);
+                       return Child.ConvertExplicitly (inCheckedContext, target_type);
                }
 
-               public override Constant ToType (Type type)
+               public override Constant ConvertImplicitly (Type type)
                {
                        if (Type == type) {
                                // This is workaround of mono bug. It can be removed when the latest corlib spreads enough
@@ -1544,7 +1519,7 @@ namespace Mono.CSharp {
                                        return this;
 
                                if (type.UnderlyingSystemType != Child.Type)
-                                       Child = Child.ToType (type.UnderlyingSystemType);
+                                       Child = Child.ConvertImplicitly (type.UnderlyingSystemType);
                                return this;
                        }
 
@@ -1552,7 +1527,7 @@ namespace Mono.CSharp {
                                return null;
                        }
 
-                       return Child.ToType (type);
+                       return Child.ConvertImplicitly(type);
                }
 
        }
@@ -1951,14 +1926,19 @@ namespace Mono.CSharp {
                public static string RemoveGenericArity (string name)
                {
                        int start = 0;
-                       StringBuilder sb = new StringBuilder ();
-                       while (start < name.Length) {
+                       StringBuilder sb = null;
+                       do {
                                int pos = name.IndexOf ('`', start);
                                if (pos < 0) {
+                                       if (start == 0)
+                                               return name;
+
                                        sb.Append (name.Substring (start));
                                        break;
                                }
 
+                               if (sb == null)
+                                       sb = new StringBuilder ();
                                sb.Append (name.Substring (start, pos-start));
 
                                pos++;
@@ -1966,7 +1946,7 @@ namespace Mono.CSharp {
                                        pos++;
 
                                start = pos;
-                       }
+                       } while (start < name.Length);
 
                        return sb.ToString ();
                }
@@ -2823,7 +2803,10 @@ namespace Mono.CSharp {
                        Methods = new MethodBase [mi.Length];
                        mi.CopyTo (Methods, 0);
                        eclass = ExprClass.MethodGroup;
-                       type = TypeManager.object_type;
+
+                       // Set the type to something that will never be useful, which will
+                       // trigger the proper conversions.
+                       type = typeof (MethodGroupExpr);
                        loc = l;
                }
 
@@ -3536,8 +3519,6 @@ namespace Mono.CSharp {
                LocalTemporary temp;
                bool prepared;
 
-               internal static PtrHashtable AccessorTable = new PtrHashtable (); 
-
                public PropertyExpr (Type containerType, PropertyInfo pi, Location l)
                {
                        PropertyInfo = pi;
@@ -3617,7 +3598,7 @@ namespace Mono.CSharp {
                // We also perform the permission checking here, as the PropertyInfo does not
                // hold the information for the accessibility of its setter/getter
                //
-               // TODO: can use TypeManager.GetProperty to boost performance
+               // TODO: Refactor to use some kind of cache together with GetPropertyFromAccessor
                void ResolveAccessors (Type containerType)
                {
                        FindAccessors (containerType);
@@ -3628,7 +3609,6 @@ namespace Mono.CSharp {
                                if (md != null)
                                        md.SetMemberIsUsed ();
 
-                               AccessorTable [getter] = PropertyInfo;
                                is_static = getter.IsStatic;
                        }
 
@@ -3638,7 +3618,6 @@ namespace Mono.CSharp {
                                if (md != null)
                                        md.SetMemberIsUsed ();
 
-                               AccessorTable [setter] = PropertyInfo;
                                is_static = setter.IsStatic;
                        }
                }
@@ -3910,8 +3889,6 @@ namespace Mono.CSharp {
                bool is_static;
                MethodInfo add_accessor, remove_accessor;
 
-               internal static PtrHashtable AccessorTable = new PtrHashtable (); 
-               
                public EventExpr (EventInfo ei, Location loc)
                {
                        EventInfo = ei;
@@ -3920,11 +3897,6 @@ namespace Mono.CSharp {
 
                        add_accessor = TypeManager.GetAddMethod (ei);
                        remove_accessor = TypeManager.GetRemoveMethod (ei);
-                       if (add_accessor != null)
-                               AccessorTable [add_accessor] = ei;
-                       if (remove_accessor != null)
-                               AccessorTable [remove_accessor] = ei;
-                       
                        if (add_accessor.IsStatic || remove_accessor.IsStatic)
                                is_static = true;
 
@@ -4057,7 +4029,11 @@ namespace Mono.CSharp {
 
                public void EmitAddOrRemove (EmitContext ec, Expression source)
                {
-                       BinaryDelegate source_del = (BinaryDelegate) source;
+                       BinaryDelegate source_del = source as BinaryDelegate;
+                       if (source_del == null) {
+                               Emit (ec);
+                               return;
+                       }
                        Expression handler = source_del.Right;
                        
                        Argument arg = new Argument (handler, Argument.AType.Expression);