2003-07-16 Gonzalo Paniagua Javier <gonzalo@ximian.com>
[mono.git] / mcs / mbas / decl.cs
index a02a568934b09b1af0856187dc4de8ff32b4c5a9..6b49c3b908511b219aaf04f8a56dd5bcb5146898 100644 (file)
@@ -396,9 +396,11 @@ namespace Mono.CSharp {
                        if (type_resolve_ec == null)
                                type_resolve_ec = GetTypeResolveEmitContext (parent, loc);
                        type_resolve_ec.loc = loc;
+
+                       int errors = Report.Errors;
                        Expression d = e.Resolve (type_resolve_ec, ResolveFlags.Type);
                        if (d == null || d.eclass != ExprClass.Type){
-                               if (!silent){
+                               if (!silent && errors == Report.Errors){
                                        Report.Error (246, loc, "Cannot find type `"+ e.ToString () +"'");
                                }
                                return null;
@@ -445,13 +447,20 @@ namespace Mono.CSharp {
                        
                        t = parent.DefineType ();
                        if (t == null){
-                               Report.Error (146, "Class definition is circular: `"+name+"'");
+                               Report.Error (146, Location, "Class definition is circular: `"+name+"'");
                                error = true;
                                return null;
                        }
                        return t;
                }
-               
+
+               public static void Error_AmbiguousTypeReference (Location loc, string name, Type t1, Type t2)
+               {
+                       Report.Error (104, loc,
+                                     String.Format ("`{0}' is an ambiguous reference ({1} or {2}) ", name,
+                                                    t1.FullName, t2.FullName));
+               }
+
                /// <summary>
                ///   GetType is used to resolve type names at the DeclSpace level.
                ///   Use this to lookup class/struct bases, interface bases or 
@@ -464,7 +473,7 @@ namespace Mono.CSharp {
                ///   during the tree resolution process and potentially define
                ///   recursively the type
                /// </remarks>
-               public Type FindType (string name)
+               public Type FindType (Location loc, string name)
                {
                        Type t;
                        bool error;
@@ -538,17 +547,24 @@ namespace Mono.CSharp {
                                if (using_list == null)
                                        continue;
 
+                               Type match = null;
                                foreach (Namespace.UsingEntry ue in using_list){
-                                       t = LookupInterfaceOrClass (ue.Name, name, out error);
+                                       match = LookupInterfaceOrClass (ue.Name, name, out error);
                                        if (error)
                                                return null;
 
-                                       if (t != null){
+                                       if (match != null){
+                                               if (t != null){
+                                                       Error_AmbiguousTypeReference (loc, name, t, match);
+                                                       return null;
+                                               }
+                                               
+                                               t = match;
                                                ue.Used = true;
-                                               return t;
                                        }
                                }
-                               
+                               if (t != null)
+                                       return t;
                        }
 
                        //Report.Error (246, Location, "Can not find type `"+name+"'");
@@ -796,8 +812,9 @@ namespace Mono.CSharp {
        /// </summary>
        public class MemberCache {
                public readonly IMemberContainer Container;
-               protected Hashtable member_hash;
-               protected Hashtable method_hash;
+               protected CaseInsensitiveHashtable member_hash;
+               protected CaseInsensitiveHashtable method_hash;
+               protected CaseInsensitiveHashtable interface_hash;
 
                /// <summary>
                ///   Create a new MemberCache for the given IMemberContainer `container'.
@@ -809,6 +826,8 @@ namespace Mono.CSharp {
                        Timer.IncrementCounter (CounterType.MemberCache);
                        Timer.StartTimer (TimerType.CacheInit);
 
+                       interface_hash = new CaseInsensitiveHashtable ();
+
                        // If we have a parent class (we have a parent class unless we're
                        // TypeManager.object_type), we deep-copy its MemberCache here.
                        if (Container.Parent != null)
@@ -816,13 +835,13 @@ namespace Mono.CSharp {
                        else if (Container.IsInterface)
                                member_hash = SetupCacheForInterface ();
                        else
-                               member_hash = new Hashtable ();
+                               member_hash = new CaseInsensitiveHashtable ();
 
                        // If this is neither a dynamic type nor an interface, create a special
                        // method cache with all declared and inherited methods.
                        Type type = container.Type;
                        if (!(type is TypeBuilder) && !type.IsInterface) {
-                               method_hash = new Hashtable ();
+                               method_hash = new CaseInsensitiveHashtable ();
                                AddMethods (type);
                        }
 
@@ -835,9 +854,9 @@ namespace Mono.CSharp {
                /// <summary>
                ///   Bootstrap this member cache by doing a deep-copy of our parent.
                /// </summary>
-               Hashtable SetupCache (MemberCache parent)
+               CaseInsensitiveHashtable SetupCache (MemberCache parent)
                {
-                       Hashtable hash = new Hashtable ();
+                       CaseInsensitiveHashtable hash = new CaseInsensitiveHashtable ();
 
                        IDictionaryEnumerator it = parent.member_hash.GetEnumerator ();
                        while (it.MoveNext ()) {
@@ -847,6 +866,14 @@ namespace Mono.CSharp {
                        return hash;
                }
 
+               void AddInterfaces (MemberCache parent)
+               {
+                       foreach (Type iface in parent.interface_hash.Keys) {
+                               if (!interface_hash.Contains (iface))
+                                       interface_hash.Add (iface, true);
+                       }
+               }
+
                /// <summary>
                ///   Add the contents of `new_hash' to `hash'.
                /// </summary>
@@ -867,17 +894,22 @@ namespace Mono.CSharp {
                ///   Type.GetMembers() won't return any inherited members for interface types,
                ///   so we need to do this manually.  Interfaces also inherit from System.Object.
                /// </summary>
-               Hashtable SetupCacheForInterface ()
+               CaseInsensitiveHashtable SetupCacheForInterface ()
                {
-                       Hashtable hash = SetupCache (TypeHandle.ObjectType.MemberCache);
+                       CaseInsensitiveHashtable hash = SetupCache (TypeHandle.ObjectType.MemberCache);
                        Type [] ifaces = TypeManager.GetInterfaces (Container.Type);
 
                        foreach (Type iface in ifaces) {
+                               if (interface_hash.Contains (iface))
+                                       continue;
+                               interface_hash.Add (iface, true);
+
                                IMemberContainer iface_container =
                                        TypeManager.LookupMemberContainer (iface);
 
                                MemberCache iface_cache = iface_container.MemberCache;
                                AddHashtable (hash, iface_cache.member_hash);
+                               AddInterfaces (iface_cache);
                        }
 
                        return hash;
@@ -1128,7 +1160,7 @@ namespace Mono.CSharp {
                        // If we have a method cache and we aren't already doing a method-only search,
                        // then we restart a method search if the first match is a method.
                        bool do_method_search = !method_search && (method_hash != null);
-
+bf |= BindingFlags.IgnoreCase;
                        ArrayList applicable;
 
                        // If this is a method-only search, we try to use the method cache if