2002-12-19 Gonzalo Paniagua Javier <gonzalo@ximian.com>
[mono.git] / mcs / mcs / typemanager.cs
index 1989521b91d15a69c1825601a32c1578fdd67635..f6fda8ca320dbd3b11d7622987e266f067667623 100755 (executable)
@@ -128,6 +128,8 @@ public class TypeManager {
        // These methods are called by code generated by the compiler
        //
        static public MethodInfo string_concat_string_string;
+       static public MethodInfo string_concat_string_string_string;
+       static public MethodInfo string_concat_string_string_string_string;
        static public MethodInfo string_concat_object_object;
        static public MethodInfo string_isinterneted_string;
        static public MethodInfo system_type_get_type_from_handle;
@@ -1004,6 +1006,12 @@ public class TypeManager {
                Type [] string_string = { string_type, string_type };
                string_concat_string_string = GetMethod (
                        string_type, "Concat", string_string);
+               Type [] string_string_string = { string_type, string_type, string_type };
+               string_concat_string_string_string = GetMethod (
+                       string_type, "Concat", string_string_string);
+               Type [] string_string_string_string = { string_type, string_type, string_type, string_type };
+               string_concat_string_string_string_string = GetMethod (
+                       string_type, "Concat", string_string_string_string);
 
                Type [] object_object = { object_type, object_type };
                string_concat_object_object = GetMethod (
@@ -1371,6 +1379,38 @@ public class TypeManager {
                }
        }
 
+       static Hashtable attr_to_allowmult;
+
+       public static void RegisterAttributeAllowMultiple (Type attr_type, bool allow)
+       {
+               if (attr_to_allowmult == null)
+                       attr_to_allowmult = new PtrHashtable ();
+
+               if (attr_to_allowmult.Contains (attr_type))
+                       return;
+
+               attr_to_allowmult.Add (attr_type, allow);
+                              
+       }
+
+       public static bool AreMultipleAllowed (Type attr_type)
+       {
+               if (!(attr_type is TypeBuilder)) {
+                       System.Attribute [] attrs = System.Attribute.GetCustomAttributes (attr_type);
+
+                       foreach (System.Attribute tmp in attrs)
+                               if (tmp is AttributeUsageAttribute)
+                                       return ((AttributeUsageAttribute) tmp).AllowMultiple;
+
+                       return false;
+               }
+               
+               if (attr_to_allowmult == null)
+                       return false;
+
+               return (bool) attr_to_allowmult [attr_type];
+       }
+
        static Hashtable builder_to_constant;
 
        public static void RegisterConstant (FieldBuilder fb, Const c)
@@ -1546,7 +1586,7 @@ public class TypeManager {
 
                        return (MethodInfo) pair.Second;
                } else
-                       return ei.GetAddMethod ();
+                       return ei.GetRemoveMethod ();
        }
 
        static Hashtable priv_fields_events;
@@ -1696,11 +1736,13 @@ public class TypeManager {
 
        // This is a custom version of Convert.ChangeType() which works
        // with the TypeBuilder defined types when compiling corlib.
-       public static object ChangeType (object value, Type conversionType)
+       public static object ChangeType (object value, Type conversionType, out bool error)
        {
-               if (!(value is IConvertible))
-                       throw new ArgumentException ();
-
+               if (!(value is IConvertible)){
+                       error = true;
+                       return null;
+               }
+               
                IConvertible convertValue = (IConvertible) value;
                CultureInfo ci = CultureInfo.CurrentCulture;
                NumberFormatInfo provider = ci.NumberFormat;
@@ -1711,6 +1753,7 @@ public class TypeManager {
                // the system type itself.  You cannot use Type.GetTypeCode()
                // on such a type - it'd always return TypeCode.Object.
                //
+               error = false;
                if (conversionType.Equals (typeof (Boolean)))
                        return (object)(convertValue.ToBoolean (provider));
                else if (conversionType.Equals (typeof (Byte)))
@@ -1744,7 +1787,8 @@ public class TypeManager {
                else if (conversionType.Equals (typeof (Object)))
                        return (object)(value);
                else 
-                       throw new InvalidCastException ();
+                       error = true;
+               return null;
        }
 
        //