updated browser capabilities file
[mono.git] / mcs / gmcs / typemanager.cs
index f5b51016dd8fefee74797dc8ab5baf0010a4cdee..9c808accf068d3d75bb55245753e6f5cdbe54630 100755 (executable)
@@ -513,6 +513,11 @@ public class TypeManager {
        /// </summary>
        public static void AddAssembly (Assembly a)
        {
+               foreach (Assembly assembly in assemblies) {
+                       if (a == assembly)
+                               return;
+               }
+
                int top = assemblies.Length;
                Assembly [] n = new Assembly [top + 1];
 
@@ -564,7 +569,7 @@ public class TypeManager {
                //
                if (ret == null){
                        if (pointers [t] == null)
-                               pointers [t] = CodeGen.ModuleBuilder.GetType (tname);
+                               pointers [t] = CodeGen.Module.Builder.GetType (tname);
                        
                        ret = (Type) pointers [t];
                }
@@ -781,6 +786,29 @@ public class TypeManager {
                + match.Groups [2].Captures [0].Value;
        }
 
+        /// <summary>
+       ///  Returns the signature of the method with full namespace classification
+       /// </summary>
+       static public string GetFullNameSignature (MemberInfo mi)
+       {
+               return mi.DeclaringType.FullName.Replace ('+', '.') + '.' + mi.Name;
+       }
+
+       /// <summary>
+       ///   Returns the signature of the property and indexer
+       /// </summary>
+       static public string CSharpSignature (PropertyBuilder pb, bool is_indexer) 
+       {
+               if (!is_indexer) {
+                       return GetFullNameSignature (pb);
+               }
+
+               MethodBase mb = pb.GetSetMethod (true) != null ? pb.GetSetMethod (true) : pb.GetGetMethod (true);
+               string signature = GetFullNameSignature (mb);
+               string arg = TypeManager.LookupParametersByBuilder (mb).ParameterDesc (0);
+               return String.Format ("{0}.this[{1}]", signature.Substring (0, signature.LastIndexOf ('.')), arg);
+       }
+
         /// <summary>
         ///   Returns the signature of the method
         /// </summary>
@@ -807,7 +835,7 @@ public class TypeManager {
                 }
                 sig += ")";
 
-                return mb.DeclaringType.Name + "." + mb.Name + sig;
+                return GetFullNameSignature (mb) + sig;
         }
 
        /// <summary>
@@ -1026,7 +1054,7 @@ public class TypeManager {
                                args [2] = enum_type;
                                args [3] = void_type;
                                
-                               set_corlib_type_builders.Invoke (CodeGen.AssemblyBuilder, args);
+                               set_corlib_type_builders.Invoke (CodeGen.Assembly.Builder, args);
                        } else {
                                // Compatibility for an older version of the class libs.
                                set_corlib_type_builders = GetMethod (
@@ -1043,7 +1071,7 @@ public class TypeManager {
                                args [1] = value_type;
                                args [2] = enum_type;
                                
-                               set_corlib_type_builders.Invoke (CodeGen.AssemblyBuilder, args);
+                               set_corlib_type_builders.Invoke (CodeGen.Assembly.Builder, args);
                        }
                }
 
@@ -1466,7 +1494,7 @@ public class TypeManager {
                                return false;
 
                        for (int i = 0; i < aparams.Length; i++)
-                               if (aparams [i] != bparams [i])
+                               if (!aparams [i].Equals (bparams [i]))
                                        return false;
 
                        return true;
@@ -1475,6 +1503,14 @@ public class TypeManager {
                return false;
        }
 
+       public static bool IsEqual (Type a, Type b)
+       {
+               if (a.Equals (b))
+                       return true;
+               else
+                       return IsEqualGenericType (a, b);
+       }
+
        //
        // Checks whether `type' is a subclass or nested child of `parent'.
        //
@@ -1832,12 +1868,19 @@ public class TypeManager {
                return ret;
        }
                
+       static PtrHashtable iface_cache = new PtrHashtable ();
+               
        /// <summary>
        ///   This function returns the interfaces in the type `t'.  Works with
        ///   both types and TypeBuilders.
        /// </summary>
        public static TypeExpr [] GetInterfaces (Type t)
        {
+               
+               TypeExpr [] cached = iface_cache [t] as TypeExpr [];
+               if (cached != null)
+                       return cached;
+               
                //
                // The reason for catching the Array case is that Reflection.Emit
                // will not return a TypeBuilder for Array types of TypeBuilder types,
@@ -1867,17 +1910,30 @@ public class TypeManager {
                        parent_ifaces.CopyTo (result, 0);
                        type_ifaces.CopyTo (result, parent_count);
 
+                       iface_cache [t] = result;
                        return result;
                } else {
                        Type [] ifaces = t.GetInterfaces ();
+                       if (ifaces.Length == 0)
+                               return NoTypeExprs;
 
                        TypeExpr [] result = new TypeExpr [ifaces.Length];
                        for (int i = 0; i < ifaces.Length; i++)
                                result [i] = new TypeExpression (ifaces [i], Location.Null);
+                       
+                       iface_cache [t] = result;
                        return result;
                }
        }
        
+       //
+       // gets the interfaces that are declared explicitly on t
+       //
+       public static TypeExpr [] GetExplicitInterfaces (TypeBuilder t)
+       {
+               return (TypeExpr []) builder_to_ifaces [t];
+       }
+       
        /// <remarks>
        ///  The following is used to check if a given type implements an interface.
        ///  The cache helps us reduce the expense of hitting Type.GetInterfaces everytime.
@@ -2329,7 +2385,7 @@ public class TypeManager {
                        return false;
 
                if (((closure_qualifier_type == null) || (closure_qualifier_type == closure_invocation_type)) &&
-                   (m.DeclaringType == closure_invocation_type))
+                   (closure_invocation_type != null) && IsEqual (m.DeclaringType, closure_invocation_type))
                        return true;
 
                //
@@ -2341,7 +2397,8 @@ public class TypeManager {
                        MethodAttributes ma = mb.Attributes & MethodAttributes.MemberAccessMask;
 
                        if (ma == MethodAttributes.Private)
-                               return closure_private_ok || (closure_invocation_type == m.DeclaringType) ||
+                               return closure_private_ok ||
+                                       IsEqual (closure_invocation_type, m.DeclaringType) ||
                                        IsNestedChildOf (closure_invocation_type, m.DeclaringType);
 
                        //
@@ -2390,7 +2447,8 @@ public class TypeManager {
                        FieldAttributes fa = fi.Attributes & FieldAttributes.FieldAccessMask;
 
                        if (fa == FieldAttributes.Private)
-                               return closure_private_ok || (closure_invocation_type == m.DeclaringType) ||
+                               return closure_private_ok ||
+                                       IsEqual (closure_invocation_type, m.DeclaringType) ||
                                        IsNestedChildOf (closure_invocation_type, m.DeclaringType);
 
                        //