Nothing to see here
[mono.git] / mcs / mcs / typemanager.cs
index fc89ddb4b101e27dd0575714386d7cf3a8d43bcf..4ee2508abedac106cabb08e1ba73a8e4b8246767 100644 (file)
@@ -77,7 +77,9 @@ namespace Mono.CSharp {
        static public Type decimal_constant_attribute_type;
        static public Type dllimport_type;
        static public Type methodimpl_attr_type;
+#if !NET_2_0
        static public Type marshal_as_attr_type;
+#endif
        static public Type param_array_type;
        static public Type void_ptr_type;
        static public Type indexer_name_type;
@@ -113,7 +115,6 @@ namespace Mono.CSharp {
        static internal Type default_charset_type;
        static internal Type type_forwarder_attr_type;
        static internal Type isvolatile_type;
-       static public Type activator_type;
        static public Type generic_ilist_type;
        static public Type generic_icollection_type;
        static public Type generic_ienumerator_type;
@@ -146,7 +147,7 @@ namespace Mono.CSharp {
        //
        // These methods are called by code generated by the compiler
        //
-       static public MethodInfo string_isinterned_string;
+       static public FieldInfo string_empty;
        static public MethodInfo system_type_get_type_from_handle;
        static public MethodInfo bool_movenext_void;
        static public MethodInfo void_dispose_void;
@@ -180,6 +181,7 @@ namespace Mono.CSharp {
 
        // C# 2.0
        static internal ConstructorInfo fixed_buffer_attr_ctor;
+       static internal CustomAttributeBuilder unsafe_value_type_attr;
 
        // C# 3.0
        static internal CustomAttributeBuilder extension_attribute_attr;
@@ -194,12 +196,6 @@ namespace Mono.CSharp {
        // </remarks>
        static PtrHashtable builder_to_ifaces;
 
-       // <remarks>
-       //   Maps PropertyBuilder to a Type array that contains
-       //   the arguments to the indexer
-       // </remarks>
-       static Hashtable indexer_arguments;
-
        // <remarks>
        //   Maps a MethodBase to its ParameterData (either InternalParameters or ReflectionParameters)
        // <remarks>
@@ -235,7 +231,6 @@ namespace Mono.CSharp {
                builder_to_member_cache = null;
                builder_to_ifaces = null;
                builder_to_type_param = null;
-               indexer_arguments = null;
                method_params = null;
                builder_to_method = null;
                
@@ -289,7 +284,6 @@ namespace Mono.CSharp {
                builder_to_type_param = new PtrHashtable ();
                method_params = new PtrHashtable ();
                method_overrides = new PtrHashtable ();
-               indexer_arguments = new PtrHashtable ();
                builder_to_ifaces = new PtrHashtable ();
                
                fieldbuilders_to_fields = new Hashtable ();
@@ -299,7 +293,6 @@ namespace Mono.CSharp {
                assembly_internals_vis_attrs = new PtrHashtable ();
 
                // TODO: I am really bored by all this static stuff
-               string_isinterned_string =
                system_type_get_type_from_handle =
                bool_movenext_void =
                void_dispose_void =
@@ -328,6 +321,7 @@ namespace Mono.CSharp {
 
                param_array_attr =
                compiler_generated_attr =
+               unsafe_value_type_attr =
                extension_attribute_attr = null;
 
                isvolatile_type = null;
@@ -606,8 +600,11 @@ namespace Mono.CSharp {
                if (t == typeof (AnonymousMethodBody))
                        return "anonymous method";
 
+               if (t == null)
+                       return "internal error";
+
                return CSharpName (GetFullName (t));
-    }
+       }
 
        static readonly char [] elements = new char [] { '*', '[' };
 
@@ -658,19 +655,8 @@ namespace Mono.CSharp {
                }
                return sb.ToString ();
        }
-       
-       // Used for error reporting to show symbolic name instead of underlying value
-       public static string CSharpEnumValue (Type t, object value)
-       {
-               t = DropGenericTypeArguments (t);
-               Enum e = LookupDeclSpace (t) as Enum;
-               if (e == null)
-                       return System.Enum.GetName (t, value);
 
-               return e.GetDefinition (value).GetSignatureForError ();
-       }
-
-        /// <summary>
+       /// <summary>
        ///  Returns the signature of the method with full namespace classification
        /// </summary>
        static public string GetFullNameSignature (MemberInfo mi)
@@ -780,15 +766,21 @@ namespace Mono.CSharp {
                StringBuilder sig = new StringBuilder (CSharpName (mb.DeclaringType));
                sig.Append ('.');
 
-               ParameterData iparams = GetParameterData (mb);
+               AParametersCollection iparams = GetParameterData (mb);
                string parameters = iparams.GetSignatureForError ();
                int accessor_end = 0;
 
                if (!mb.IsConstructor && TypeManager.IsSpecialMethod (mb)) {
                        string op_name = Operator.GetName (mb.Name);
                        if (op_name != null) {
-                               sig.Append ("operator ");
-                               sig.Append (op_name);
+                               if (op_name == "explicit" || op_name == "implicit") {
+                                       sig.Append (op_name);
+                                       sig.Append (" operator ");
+                                       sig.Append (CSharpName (((MethodInfo)mb).ReturnType));
+                               } else {
+                                       sig.Append ("operator ");
+                                       sig.Append (op_name);
+                               }
                                sig.Append (parameters);
                                return sig.ToString ();
                        }
@@ -925,7 +917,7 @@ namespace Mono.CSharp {
                                        if (mb == null)
                                                continue;
 
-                                       ParameterData pd = TypeManager.GetParameterData (mb);
+                                       AParametersCollection pd = TypeManager.GetParameterData (mb);
                                        if (IsEqual (pd.Types, args))
                                                return member;
                                }
@@ -1051,6 +1043,28 @@ namespace Mono.CSharp {
        //
        public static void InitOptionalCoreTypes ()
        {
+               system_string_expr.Type = string_type;
+               system_boolean_expr.Type = bool_type;
+               system_decimal_expr.Type = decimal_type;
+               system_single_expr.Type = float_type;
+               system_double_expr.Type = double_type;
+               system_sbyte_expr.Type = sbyte_type;
+               system_byte_expr.Type = byte_type;
+               system_int16_expr.Type = short_type;
+               system_uint16_expr.Type = ushort_type;
+               system_int32_expr.Type = int32_type;
+               system_uint32_expr.Type = uint32_type;
+               system_int64_expr.Type = int64_type;
+               system_uint64_expr.Type = uint64_type;
+               system_char_expr.Type = char_type;
+               system_void_expr.Type = void_type;
+
+               //
+               // These are only used for compare purposes
+               //
+               anonymous_method_type = typeof (AnonymousMethodBody);
+               null_type = typeof (NullLiteral);
+               
                void_ptr_type = GetPointerType (void_type);
                char_ptr_type = GetPointerType (char_type);
 
@@ -1074,12 +1088,14 @@ namespace Mono.CSharp {
                if (obsolete_attribute_type != null) {
                        Class c = TypeManager.LookupClass (obsolete_attribute_type);
                        if (c != null)
-                               c.DefineMembers ();
+                               c.Define ();
                }
 
                dllimport_type = CoreLookupType ("System.Runtime.InteropServices", "DllImportAttribute", Kind.Class, false);
                methodimpl_attr_type = CoreLookupType ("System.Runtime.CompilerServices", "MethodImplAttribute", Kind.Class, false);
+#if !NET_2_0
                marshal_as_attr_type = CoreLookupType ("System.Runtime.InteropServices", "MarshalAsAttribute", Kind.Class, false);
+#endif
                in_attribute_type = CoreLookupType ("System.Runtime.InteropServices", "InAttribute", Kind.Class, false);
                indexer_name_type = CoreLookupType ("System.Runtime.CompilerServices", "IndexerNameAttribute", Kind.Class, false);
                conditional_attribute_type = CoreLookupType ("System.Diagnostics", "ConditionalAttribute", Kind.Class, false);
@@ -1147,28 +1163,6 @@ namespace Mono.CSharp {
                                        TypeManager.CSharpName (system_4_type_arg));
                        }
                }
-
-               system_string_expr.Type = string_type;
-               system_boolean_expr.Type = bool_type;
-               system_decimal_expr.Type = decimal_type;
-               system_single_expr.Type = float_type;
-               system_double_expr.Type = double_type;
-               system_sbyte_expr.Type = sbyte_type;
-               system_byte_expr.Type = byte_type;
-               system_int16_expr.Type = short_type;
-               system_uint16_expr.Type = ushort_type;
-               system_int32_expr.Type = int32_type;
-               system_uint32_expr.Type = uint32_type;
-               system_int64_expr.Type = int64_type;
-               system_uint64_expr.Type = uint64_type;
-               system_char_expr.Type = char_type;
-               system_void_expr.Type = void_type;
-
-               //
-               // These are only used for compare purposes
-               //
-               anonymous_method_type = typeof (AnonymousMethodBody);
-               null_type = typeof (NullLiteral);
        }
 
        const BindingFlags instance_and_static = BindingFlags.Static | BindingFlags.Instance;
@@ -1396,7 +1390,7 @@ namespace Mono.CSharp {
                        return false;
 #endif
 
-               if (t == TypeManager.delegate_type)
+               if (t == TypeManager.delegate_type || t == TypeManager.multicast_delegate_type)
                        return false;
 
                t = DropGenericTypeArguments (t);
@@ -1633,6 +1627,11 @@ namespace Mono.CSharp {
                return false;
        }
 
+       public static bool IsSpecialType (Type t)
+       {
+               return t == arg_iterator_type || t == typed_reference_type;
+       }
+
        //
        // Checks whether `extern_type' is friend of the output assembly
        //
@@ -1703,10 +1702,9 @@ namespace Mono.CSharp {
 
        static void Error_FriendAccessNameNotMatching (string other_name)
        {
-               Report.Error (281, "Friend access was granted to `" + other_name + 
-                               "', but the output assembly is named `" + CodeGen.Assembly.Name.FullName +
-                               "'. Try adding a reference to `" + other_name + 
-                               "' or change the output assembly name to match it");
+               Report.Error (281,
+                       "Friend access was granted to `{0}', but the output assembly is named `{1}'. Try adding a reference to `{0}' or change the output assembly name to match it",
+                       other_name, CodeGen.Assembly.Name.FullName);
        }
 #endif
 
@@ -1738,7 +1736,7 @@ namespace Mono.CSharp {
                        return e.UnderlyingType;
 
                // TODO: cache it ?
-               FieldInfo fi = GetPredefinedField (t, Enum.UnderlyingValueField, Location.Null);
+               FieldInfo fi = GetPredefinedField (t, Enum.UnderlyingValueField, Location.Null, Type.EmptyTypes);
                if (fi == null)
                        return TypeManager.int32_type;
 
@@ -1754,23 +1752,30 @@ namespace Mono.CSharp {
        ///   for anything which is dynamic, and we need this in a number of places,
        ///   we register this information here, and use it afterwards.
        /// </remarks>
-       static public void RegisterMethod (MethodBase mb, Parameters ip)
+       static public void RegisterMethod (MethodBase mb, AParametersCollection ip)
        {
                method_params.Add (mb, ip);
        }
+
+       static public void RegisterIndexer (PropertyBuilder pb, AParametersCollection p)
+       {
+               method_params.Add (pb, p);
+       }
        
-       static public ParameterData GetParameterData (MethodBase mb)
+       static public AParametersCollection GetParameterData (MethodBase mb)
        {
-               ParameterData pd = (ParameterData)method_params [mb];
+               AParametersCollection pd = (AParametersCollection) method_params [mb];
                if (pd == null) {
 #if MS_COMPATIBLE
                        if (mb.IsGenericMethod && !mb.IsGenericMethodDefinition) {
                                MethodInfo mi = ((MethodInfo) mb).GetGenericMethodDefinition ();
                                pd = GetParameterData (mi);
+                               /*
                                if (mi.IsGenericMethod)
                                        pd = pd.InflateTypes (mi.GetGenericArguments (), mb.GetGenericArguments ());
                                else
                                        pd = pd.InflateTypes (mi.DeclaringType.GetGenericArguments (), mb.GetGenericArguments ());
+                               */
                                method_params.Add (mb, pd);
                                return pd;
                        }
@@ -1779,14 +1784,41 @@ namespace Mono.CSharp {
                                throw new InternalErrorException ("Parameters are not registered for method `{0}'",
                                        TypeManager.CSharpName (mb.DeclaringType) + "." + mb.Name);
                        }
+
+                       pd = ParametersCollection.Create (mb);
+#else
+                       MethodBase generic = TypeManager.DropGenericMethodArguments (mb);
+                       if (generic != mb) {
+                               pd = TypeManager.GetParameterData (generic);
+                               pd = ParametersCollection.Create (pd, mb);
+                       } else {
+                               pd = ParametersCollection.Create (mb);
+                       }
 #endif
-                       pd = new ReflectionParameters (mb);
                        method_params.Add (mb, pd);
                }
                return pd;
        }
 
-       public static ParameterData GetDelegateParameters (Type t)
+       public static AParametersCollection GetParameterData (PropertyInfo pi)
+       {
+               AParametersCollection pd = (AParametersCollection)method_params [pi];
+               if (pd == null) {
+                       if (pi is PropertyBuilder)
+                               return Parameters.EmptyReadOnlyParameters;
+
+                       ParameterInfo [] p = pi.GetIndexParameters ();
+                       if (p == null)
+                               return Parameters.EmptyReadOnlyParameters;
+
+                       pd = ParametersCollection.Create (p, null);
+                       method_params.Add (pi, pd);
+               }
+
+               return pd;
+       }
+
+       public static AParametersCollection GetDelegateParameters (Type t)
        {
                Delegate d = builder_to_declspace [t] as Delegate;
                if (d != null)
@@ -1820,38 +1852,6 @@ namespace Mono.CSharp {
                return (MethodBase) method_overrides [m];
        }
 
-       /// <summary>
-       ///    Returns the argument types for an indexer based on its PropertyInfo
-       ///
-       ///    For dynamic indexers, we use the compiler provided types, for
-       ///    indexers from existing assemblies we load them from GetParameters,
-       ///    and insert them into the cache
-       /// </summary>
-       static public Type [] GetArgumentTypes (PropertyInfo indexer)
-       {
-               if (indexer_arguments.Contains (indexer))
-                       return (Type []) indexer_arguments [indexer];
-               else if (indexer is PropertyBuilder)
-                       // If we're a PropertyBuilder and not in the
-                       // `indexer_arguments' hash, then we're a property and
-                       // not an indexer.
-                       return Type.EmptyTypes;
-               else {
-                       ParameterInfo [] pi = indexer.GetIndexParameters ();
-                       // Property, not an indexer.
-                       if (pi == null)
-                               return Type.EmptyTypes;
-                       int c = pi.Length;
-                       Type [] types = new Type [c];
-                       
-                       for (int i = 0; i < c; i++)
-                               types [i] = pi [i].ParameterType;
-
-                       indexer_arguments.Add (indexer, types);
-                       return types;
-               }
-       }
-       
        public static void RegisterConstant (FieldInfo fb, IConstant ic)
        {
                fields.Add (fb, ic);
@@ -1925,14 +1925,6 @@ namespace Mono.CSharp {
                return (EventField) events [ei];
        }
 
-       static public bool RegisterIndexer (PropertyBuilder pb, MethodBase get,
-                                            MethodBase set, Type[] args)
-       {
-               indexer_arguments.Add (pb, args);
-
-               return true;
-       }
-
        public static bool CheckStructCycles (TypeContainer tc, Hashtable seen)
        {
                Hashtable hash = new Hashtable ();
@@ -2432,11 +2424,14 @@ namespace Mono.CSharp {
        //
        // Returns whether the array of memberinfos contains the given method
        //
-       public static bool ArrayContainsMethod (MemberInfo [] array, MethodBase new_method)
+       public static bool ArrayContainsMethod (MemberInfo [] array, MethodBase new_method, bool ignoreDeclType)
        {
                Type [] new_args = TypeManager.GetParameterData (new_method).Types;
                
                foreach (MethodBase method in array) {
+                       if (!ignoreDeclType && method.DeclaringType != new_method.DeclaringType)
+                               continue;
+               
                        if (method.Name != new_method.Name)
                                continue;
 
@@ -2490,7 +2485,7 @@ namespace Mono.CSharp {
                foreach (MemberInfo mi in new_members){
                        MethodBase new_method = (MethodBase) mi;
                        
-                       if (!ArrayContainsMethod (target_array, new_method))
+                       if (!ArrayContainsMethod (target_array, new_method, true))
                                target_list.Add (new_method);
                }
                return target_list;
@@ -2587,6 +2582,10 @@ namespace Mono.CSharp {
                        if (a.BaseType == TypeManager.enum_type || b.BaseType == TypeManager.enum_type)
                                return a.FullName == b.FullName;
 
+                       // Some types are never equal
+                       if (a == TypeManager.null_type || a == TypeManager.anonymous_method_type)
+                               return false;
+
                        return true;
                }
 
@@ -2638,7 +2637,7 @@ namespace Mono.CSharp {
 
        public static bool IsEqual (Type[] a, Type[] b)
        {
-               if (a.Length != b.Length)
+               if (a == null || b == null || a.Length != b.Length)
                        return false;
 
                for (int i = 0; i < a.Length; ++i) {
@@ -3292,12 +3291,36 @@ namespace Mono.CSharp {
        {
                MethodInfo get_method = pi.GetGetMethod (true);
                MethodInfo set_method = pi.GetSetMethod (true);
+               int g_count = 0;
+               int s_count = 0;
                if (get_method != null && set_method != null) {
-                       int g_count = get_method.GetParameters ().Length;
-                       int s_count = set_method.GetParameters ().Length;
+                       g_count = get_method.GetParameters ().Length;
+                       s_count = set_method.GetParameters ().Length;
                        if (g_count + 1 != s_count)
                                return false;
+               } else if (get_method != null) {
+                       g_count = get_method.GetParameters ().Length;
+               } else if (set_method != null) {
+                       s_count = set_method.GetParameters ().Length;
                }
+
+               //
+               // DefaultMemberName and indexer name has to match to identify valid C# indexer
+               //
+               if ((s_count > 1 || g_count > 0) && TypeManager.default_member_type != null) {
+                       object[] o = pi.DeclaringType.GetCustomAttributes (TypeManager.default_member_type, false);
+                       if (o.Length == 0)
+                               return false;
+                       
+                       DefaultMemberAttribute dma = (DefaultMemberAttribute) o [0];
+                       if (dma.MemberName != pi.Name)
+                               return false;
+                       if (get_method != null && "get_" + dma.MemberName != get_method.Name)
+                               return false;
+                       if (set_method != null && "set_" + dma.MemberName != set_method.Name)
+                               return false;
+               }
+
                return true;
        }