Rename lookup method for consistency
[mono.git] / mcs / mcs / namespace.cs
index 3e9140e9649e3927b8d9a298f22a787f0c927cbd..a19f5938a784baa4eccbcf7faffd5e8a04aa3a80 100644 (file)
 //
 using System;
 using System.Collections.Generic;
-using System.Reflection;
 using System.Linq;
 
 namespace Mono.CSharp {
 
        public class RootNamespace : Namespace {
 
-               protected readonly string alias_name;
-               protected Assembly [] referenced_assemblies;
-
-               Dictionary<string, Namespace> all_namespaces;
+               readonly string alias_name;
+               readonly Dictionary<string, Namespace> all_namespaces;
 
                public RootNamespace (string alias_name)
                        : base (null, String.Empty)
                {
                        this.alias_name = alias_name;
-                       referenced_assemblies = new Assembly [0];
 
                        all_namespaces = new Dictionary<string, Namespace> ();
                        all_namespaces.Add ("", this);
                }
 
-               public void AddAssemblyReference (Assembly a)
-               {
-                       foreach (Assembly assembly in referenced_assemblies) {
-                               if (a == assembly)
-                                       return;
-                       }
-
-                       int top = referenced_assemblies.Length;
-                       Assembly [] n = new Assembly [top + 1];
-                       referenced_assemblies.CopyTo (n, 0);
-                       n [top] = a;
-                       referenced_assemblies = n;
-               }
-
-               public void ImportTypes (CompilerContext ctx)
-               {
-                       foreach (Assembly a in referenced_assemblies) {
-                               try {
-                                       ImportAssembly (a);
-                               } catch (TypeLoadException e) {
-                                       ctx.Report.Error (11, Location.Null, e.Message);
-                               } catch (System.IO.FileNotFoundException) {
-                                       ctx.Report.Error (12, Location.Null, "An assembly `{0}' is used without being referenced",
-                                               a.FullName);
-                               }
+               public string Alias {
+                       get {
+                               return alias_name;
                        }
                }
 
@@ -77,140 +51,35 @@ namespace Mono.CSharp {
                                GetNamespace (dotted_name, true);
                }
 
-               public void ImportAssembly (Assembly assembly)
-               {
-                       Type extension_type = null;
-                       var all_attributes = CustomAttributeData.GetCustomAttributes (assembly);
-                       foreach (var attr in all_attributes) {
-                               var dt = attr.Constructor.DeclaringType;
-                               if (dt.Name == "ExtensionAttribute" && dt.Namespace == "System.Runtime.CompilerServices") {
-                                       extension_type = dt;
-                                       break;
-                               }
-                       }
-
-                       Namespace ns = this;
-                       string prev_namespace = null;
-                       foreach (var t in assembly.GetTypes ()) {
-                               if (t.IsNested)
-                                       continue;
-
-                               if (t.Name[0] == '<')
-                                       continue;
-
-                               var it = Import.CreateType (t);
-                               if (it == null)
-                                       continue;
-
-                               if (prev_namespace != t.Namespace) {
-                                       ns = t.Namespace == null ? this : GetNamespace (t.Namespace, true);
-                                       prev_namespace = t.Namespace;
-                               }
-
-                               ns.AddType (it);
-
-                               if (it.IsStatic && extension_type != null && t.IsDefined (extension_type, false)) {
-                                       it.SetExtensionMethodContainer ();
-                               }
-                       }
-               }
-
                public override string GetSignatureForError ()
                {
                        return alias_name + "::";
                }
        }
 
-       public class GlobalRootNamespace : RootNamespace {
-               Module [] modules;
-               Dictionary<string, RootNamespace> root_namespaces;
-
-               public static GlobalRootNamespace Instance = new GlobalRootNamespace ();
-
-               GlobalRootNamespace ()
+       public class GlobalRootNamespace : RootNamespace
+       {
+               public GlobalRootNamespace ()
                        : base ("global")
                {
-                       root_namespaces = new Dictionary<string, RootNamespace> ();
-                       root_namespaces.Add (alias_name, this);
-               }
-
-               public static void Reset ()
-               {
-                       Instance = new GlobalRootNamespace ();
-               }
-
-               public Assembly [] Assemblies {
-                   get { return referenced_assemblies; }
-               }
-
-               public Module [] Modules {
-                       get { return modules; }
-               }
-
-               public void AddModuleReference (Module m)
-               {
-                       int top = modules != null ? modules.Length : 0;
-                       Module [] n = new Module [top + 1];
-                       if (modules != null)
-                               modules.CopyTo (n, 0);
-                       n [top] = m;
-                       modules = n;
-
-                       if (m == RootContext.ToplevelTypes.Builder)
-                               return;
-
-                       foreach (var t in m.GetTypes ())
-                               RegisterNamespace (t.Namespace);
-               }
-
-               public void ComputeNamespaces (CompilerContext ctx)
-               {
-                       foreach (RootNamespace rn in root_namespaces.Values) {
-                               rn.ImportTypes (ctx);
-                       }
-               }
-
-               public void DefineRootNamespace (string alias, Assembly assembly, CompilerContext ctx)
-               {
-                       if (alias == alias_name) {
-                               NamespaceEntry.Error_GlobalNamespaceRedefined (Location.Null, ctx.Report);
-                               return;
-                       }
-
-                       RootNamespace retval = GetRootNamespace (alias);
-                       if (retval == null) {
-                               retval = new RootNamespace (alias);
-                               root_namespaces.Add (alias, retval);
-                       }
-
-                       retval.AddAssemblyReference (assembly);
                }
 
                public override void Error_NamespaceDoesNotExist (Location loc, string name, int arity, IMemberContext ctx)
                {
-                       ctx.Compiler.Report.Error (400, loc,
+                       ctx.Module.Compiler.Report.Error (400, loc,
                                "The type or namespace name `{0}' could not be found in the global namespace (are you missing an assembly reference?)",
                                name);
                }
-
-               public RootNamespace GetRootNamespace (string name)
-               {
-                       RootNamespace rn;
-                       if (!root_namespaces.TryGetValue (name, out rn))
-                               return null;
-
-                       return rn;
-               }
        }
 
-       /// <summary>
-       ///   Keeps track of the namespaces defined in the C# code.
-       ///
-       ///   This is an Expression to allow it to be referenced in the
-       ///   compiler parse/intermediate tree during name resolution.
-       /// </summary>
-       public class Namespace : FullNamedExpression {
-               
+       //
+       // Namespace cache for imported and compiled namespaces
+       //
+       // This is an Expression to allow it to be referenced in the
+       // compiler parse/intermediate tree during name resolution.
+       //
+       public class Namespace : FullNamedExpression
+       {
                Namespace parent;
                string fullname;
                protected Dictionary<string, Namespace> namespaces;
@@ -230,7 +99,7 @@ namespace Mono.CSharp {
                {
                        // Expression members.
                        this.eclass = ExprClass.Namespace;
-                       this.Type = InternalType.FakeInternalType;
+                       this.Type = InternalType.Namespace;
                        this.loc = Location.Null;
 
                        this.parent = parent;
@@ -292,19 +161,19 @@ namespace Mono.CSharp {
 
                public virtual void Error_NamespaceDoesNotExist (Location loc, string name, int arity, IMemberContext ctx)
                {
-                       FullNamedExpression retval = Lookup (ctx.Compiler, name, -System.Math.Max (1, arity), loc);
+                       var retval = LookupType (ctx, name, -System.Math.Max (1, arity), loc);
                        if (retval != null) {
-                               Error_TypeArgumentsCannotBeUsed (ctx.Compiler.Report, loc, retval.Type, arity);
+                               Error_TypeArgumentsCannotBeUsed (ctx, retval.Type, arity, loc);
                                return;
                        }
 
                        Namespace ns;
                        if (arity > 0 && namespaces.TryGetValue (name, out ns)) {
-                               ns.Error_TypeArgumentsCannotBeUsed (ctx.Compiler.Report, loc, null, arity);
+                               ns.Error_TypeArgumentsCannotBeUsed (ctx, null, arity, loc);
                                return;
                        }
 
-                       ctx.Compiler.Report.Error (234, loc,
+                       ctx.Module.Compiler.Report.Error (234, loc,
                                "The type or namespace name `{0}' does not exist in the namespace `{1}'. Are you missing an assembly reference?",
                                name, GetSignatureForError ());
                }
@@ -339,7 +208,16 @@ namespace Mono.CSharp {
                        return ns;
                }
 
-               TypeExpr LookupType (CompilerContext ctx, string name, int arity, Location loc)
+               public IList<TypeSpec> GetAllTypes (string name)
+               {
+                       IList<TypeSpec> found;
+                       if (types == null || !types.TryGetValue (name, out found))
+                               return null;
+
+                       return found;
+               }
+
+               public TypeExpr LookupType (IMemberContext ctx, string name, int arity, Location loc)
                {
                        if (types == null)
                                return null;
@@ -361,36 +239,22 @@ namespace Mono.CSharp {
                                        }
 
                                        if (best.MemberDefinition.IsImported && ts.MemberDefinition.IsImported) {
-                                               ctx.Report.SymbolRelatedToPreviousError (best);
-                                               ctx.Report.SymbolRelatedToPreviousError (ts);
-                                               ctx.Report.Error (433, loc, "The imported type `{0}' is defined multiple times", ts.GetSignatureForError ());
+                                               ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (best);
+                                               ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (ts);
+                                               ctx.Module.Compiler.Report.Error (433, loc, "The imported type `{0}' is defined multiple times", ts.GetSignatureForError ());
                                                break;
                                        }
 
-                                       var pts = best as PredefinedTypeSpec;
-                                       if (pts == null)
-                                               pts = ts as PredefinedTypeSpec;
-
-                                       if (pts != null) {
-                                               ctx.Report.SymbolRelatedToPreviousError (best);
-                                               ctx.Report.SymbolRelatedToPreviousError (ts);
-                                               ctx.Report.Warning (1685, 1, loc,
-                                                       "The predefined type `{0}.{1}' is redefined in the source code. Ignoring the local type definition",
-                                                       pts.Namespace, pts.Name);
-                                               best = pts;
-                                               continue;
-                                       }
-
                                        if (best.MemberDefinition.IsImported)
                                                best = ts;
 
-                                       if ((best.Modifiers & Modifiers.INTERNAL) != 0 && !TypeManager.IsThisOrFriendAssembly (CodeGen.Assembly.Builder, best.MemberDefinition.Assembly))
+                                       if ((best.Modifiers & Modifiers.INTERNAL) != 0 && !best.MemberDefinition.IsInternalAsPublic (ctx.Module.DeclaringAssembly))
                                                continue;
 
                                        if (ts.MemberDefinition.IsImported)
-                                               ctx.Report.SymbolRelatedToPreviousError (ts);
+                                               ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (ts);
 
-                                       ctx.Report.Warning (436, 2, loc,
+                                       ctx.Module.Compiler.Report.Warning (436, 2, loc,
                                                "The type `{0}' conflicts with the imported type of same name'. Ignoring the imported type definition",
                                                best.GetSignatureForError ());
                                }
@@ -410,6 +274,9 @@ namespace Mono.CSharp {
                        if (best == null)
                                return null;
 
+                       if ((best.Modifiers & Modifiers.INTERNAL) != 0 && !best.MemberDefinition.IsInternalAsPublic (ctx.Module.DeclaringAssembly))
+                               return null;
+
                        te = new TypeExpression (best, Location.Null);
 
                        // TODO MemberCache: Cache more
@@ -450,12 +317,26 @@ namespace Mono.CSharp {
                        return null;
                }
 
-               public FullNamedExpression Lookup (CompilerContext ctx, string name, int arity, Location loc)
+               public FullNamedExpression LookupTypeOrNamespace (IMemberContext ctx, string name, int arity, Location loc)
                {
-                       if (arity == 0 && namespaces.ContainsKey (name))
-                               return namespaces [name];
+                       var texpr = LookupType (ctx, name, arity, loc);
 
-                       return LookupType (ctx, name, arity, loc);
+                       Namespace ns;
+                       if (arity == 0 && namespaces.TryGetValue (name, out ns)) {
+                               if (texpr == null)
+                                       return ns;
+
+                               ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (texpr.Type);
+                               // ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (ns.loc, "");
+                               ctx.Module.Compiler.Report.Warning (437, 2, loc,
+                                       "The type `{0}' conflicts with the imported namespace `{1}'. Using the definition found in the source file",
+                                       texpr.GetSignatureForError (), ns.GetSignatureForError ());
+
+                               if (texpr.Type.MemberDefinition.IsImported)
+                                       return ns;
+                       }
+
+                       return texpr;
                }
 
                //
@@ -479,15 +360,13 @@ namespace Mono.CSharp {
                /// 
                /// Looks for extension method in this namespace
                /// 
-               public List<MethodSpec> LookupExtensionMethod (TypeSpec extensionType, ClassOrStruct currentClass, string name, int arity)
+               public List<MethodSpec> LookupExtensionMethod (IMemberContext invocationContext, TypeSpec extensionType, string name, int arity)
                {
                        if (types == null)
                                return null;
 
                        List<MethodSpec> found = null;
 
-                       var invocation_type = currentClass == null ? InternalType.FakeInternalType : currentClass.CurrentType;
-
                        // TODO: Add per namespace flag when at least 1 type has extension
 
                        foreach (var tgroup in types.Values) {
@@ -495,7 +374,7 @@ namespace Mono.CSharp {
                                        if ((ts.Modifiers & Modifiers.METHOD_EXTENSION) == 0)
                                                continue;
 
-                                       var res = ts.MemberCache.FindExtensionMethods (invocation_type, extensionType, name, arity);
+                                       var res = ts.MemberCache.FindExtensionMethods (invocationContext, extensionType, name, arity);
                                        if (res == null)
                                                continue;
 
@@ -510,7 +389,7 @@ namespace Mono.CSharp {
                        return found;
                }
 
-               public void AddType (TypeSpec ts)
+               public void AddType (ModuleContainer module, TypeSpec ts)
                {
                        if (types == null) {
                                types = new Dictionary<string, IList<TypeSpec>> (64);
@@ -524,7 +403,7 @@ namespace Mono.CSharp {
                                if (existing.Count == 1) {
                                        found = existing[0];
                                        if (ts.Arity == found.Arity) {
-                                               better_type = IsImportedTypeOverride (ts, found);
+                                               better_type = IsImportedTypeOverride (module, ts, found);
                                                if (better_type == found)
                                                        return;
 
@@ -543,7 +422,7 @@ namespace Mono.CSharp {
                                                if (ts.Arity != found.Arity)
                                                        continue;
 
-                                               better_type = IsImportedTypeOverride (ts, found);
+                                               better_type = IsImportedTypeOverride (module, ts, found);
                                                if (better_type == found)
                                                        return;
 
@@ -566,10 +445,10 @@ namespace Mono.CSharp {
                // but one has better visibility (either public or internal with friend)
                // the less visible type is removed from the namespace cache
                //
-               public static TypeSpec IsImportedTypeOverride (TypeSpec ts, TypeSpec found)
+               public static TypeSpec IsImportedTypeOverride (ModuleContainer module, TypeSpec ts, TypeSpec found)
                {
-                       var ts_accessible = (ts.Modifiers & Modifiers.PUBLIC) != 0 || TypeManager.IsThisOrFriendAssembly (CodeGen.Assembly.Builder, ts.MemberDefinition.Assembly);
-                       var found_accessible = (found.Modifiers & Modifiers.PUBLIC) != 0 || TypeManager.IsThisOrFriendAssembly (CodeGen.Assembly.Builder, found.MemberDefinition.Assembly);
+                       var ts_accessible = (ts.Modifiers & Modifiers.PUBLIC) != 0 || ts.MemberDefinition.IsInternalAsPublic (module.DeclaringAssembly);
+                       var found_accessible = (found.Modifiers & Modifiers.PUBLIC) != 0 || found.MemberDefinition.IsInternalAsPublic (module.DeclaringAssembly);
 
                        if (ts_accessible && !found_accessible)
                                return ts;
@@ -584,14 +463,20 @@ namespace Mono.CSharp {
                public void RemoveDeclSpace (string name)
                {
                        types.Remove (name);
+                       cached_types.Remove (name);
+               }
+
+               public override FullNamedExpression ResolveAsTypeOrNamespace (IMemberContext mc)
+               {
+                       return this;
                }
 
-               public void ReplaceTypeWithPredefined (TypeSpec ts, PredefinedTypeSpec pts)
+               public void SetBuiltinType (BuiltinTypeSpec pts)
                {
-                       var found = types [ts.Name];
-                       cached_types.Remove (ts.Name);
+                       var found = types[pts.Name];
+                       cached_types.Remove (pts.Name);
                        if (found.Count == 1) {
-                               types[ts.Name][0] = pts;
+                               types[pts.Name][0] = pts;
                        } else {
                                throw new NotImplementedException ();
                        }
@@ -655,207 +540,103 @@ namespace Mono.CSharp {
        }
 
        //
-       // Namespace container as created by the parser
+       // Namespace block as created by the parser
        //
-       public class NamespaceEntry : IMemberContext {
-
-               public class UsingEntry {
-                       readonly MemberName name;
-                       Namespace resolved;
-                       
-                       public UsingEntry (MemberName name)
-                       {
-                               this.name = name;
-                       }
-
-                       public string GetSignatureForError ()
-                       {
-                               return name.GetSignatureForError ();
-                       }
-
-                       public Location Location {
-                               get { return name.Location; }
-                       }
-
-                       public MemberName MemberName {
-                               get { return name; }
-                       }
-                       
-                       public string Name {
-                               get { return GetSignatureForError (); }
-                       }
-
-                       public Namespace Resolve (IMemberContext rc)
-                       {
-                               if (resolved != null)
-                                       return resolved;
-
-                               FullNamedExpression fne = name.GetTypeExpression ().ResolveAsTypeStep (rc, false);
-                               if (fne == null)
-                                       return null;
-
-                               resolved = fne as Namespace;
-                               if (resolved == null) {
-                                       rc.Compiler.Report.SymbolRelatedToPreviousError (fne.Type);
-                                       rc.Compiler.Report.Error (138, Location,
-                                               "`{0}' is a type not a namespace. A using namespace directive can only be applied to namespaces",
-                                               GetSignatureForError ());
-                               }
-                               return resolved;
-                       }
-
-                       public override string ToString ()
-                       {
-                               return Name;
-                       }
-               }
-
-               public class UsingAliasEntry {
-                       public readonly string Alias;
-                       public Location Location;
-
-                       public UsingAliasEntry (string alias, Location loc)
-                       {
-                               this.Alias = alias;
-                               this.Location = loc;
-                       }
-
-                       public virtual FullNamedExpression Resolve (IMemberContext rc)
-                       {
-                               FullNamedExpression fne = GlobalRootNamespace.Instance.GetRootNamespace (Alias);
-                               if (fne == null) {
-                                       rc.Compiler.Report.Error (430, Location,
-                                               "The extern alias `{0}' was not specified in -reference option",
-                                               Alias);
-                               }
-
-                               return fne;
-                       }
-
-                       public override string ToString ()
-                       {
-                               return Alias;
-                       }
-                       
-               }
-
-               class LocalUsingAliasEntry : UsingAliasEntry {
-                       FullNamedExpression resolved;
-                       MemberName value;
-
-                       public LocalUsingAliasEntry (string alias, MemberName name, Location loc)
-                               : base (alias, loc)
-                       {
-                               this.value = name;
-                       }
-
-                       public override FullNamedExpression Resolve (IMemberContext rc)
-                       {
-                               if (resolved != null || value == null)
-                                       return resolved;
-
-                               if (rc == null)
-                                       return null;
-
-                               resolved = value.GetTypeExpression ().ResolveAsTypeStep (rc, false);
-                               if (resolved == null) {
-                                       value = null;
-                                       return null;
-                               }
-
-                               if (resolved is TypeExpr)
-                                       resolved = resolved.ResolveAsTypeTerminal (rc, false);
-
-                               return resolved;
-                       }
+       public class NamespaceContainer : IMemberContext, ITypesContainer
+       {
+               Namespace ns;
 
-                       public override string ToString ()
-                       {
-                               return String.Format ("{0} = {1}", Alias, value.GetSignatureForError ());
-                       }
-               }
+               readonly ModuleContainer module;
+               readonly NamespaceContainer parent;
+               readonly CompilationSourceFile file;
+               readonly Location loc;
 
-               Namespace ns;
-               NamespaceEntry parent, implicit_parent;
-               CompilationUnit file;
+               NamespaceContainer implicit_parent;
                int symfile_id;
 
                // Namespace using import block
-               List<UsingAliasEntry> using_aliases;
-               List<UsingEntry> using_clauses;
+               List<NamespaceUsingAlias> using_aliases;
+               List<NamespaceUsing> using_clauses;
                public bool DeclarationFound;
                // End
 
+               bool resolved;
+
                public readonly bool IsImplicit;
-               public readonly DeclSpace SlaveDeclSpace;
+               public readonly TypeContainer SlaveDeclSpace;
                static readonly Namespace [] empty_namespaces = new Namespace [0];
-               Namespace [] namespace_using_table;
-
-               static List<NamespaceEntry> entries = new List<NamespaceEntry> ();
+               static readonly string[] empty_using_list = new string[0];
 
-               public static void Reset ()
-               {
-                       entries = new List<NamespaceEntry> ();
-               }
+               Namespace [] namespace_using_table;
 
-               public NamespaceEntry (NamespaceEntry parent, CompilationUnit file, string name)
+               public NamespaceContainer (MemberName name, ModuleContainer module, NamespaceContainer parent, CompilationSourceFile sourceFile)
                {
+                       this.module = module;
                        this.parent = parent;
-                       this.file = file;
-                       entries.Add (this);
+                       this.file = sourceFile;
+                       this.loc = name == null ? Location.Null : name.Location;
 
                        if (parent != null)
-                               ns = parent.NS.GetNamespace (name, true);
+                               ns = parent.NS.GetNamespace (name.GetName (), true);
                        else if (name != null)
-                               ns = GlobalRootNamespace.Instance.GetNamespace (name, true);
+                               ns = module.GlobalRootNamespace.GetNamespace (name.GetName (), true);
                        else
-                               ns = GlobalRootNamespace.Instance;
-                       SlaveDeclSpace = new RootDeclSpace (this);
+                               ns = module.GlobalRootNamespace;
+
+                       SlaveDeclSpace = new RootDeclSpace (module, this);
                }
 
-               private NamespaceEntry (NamespaceEntry parent, CompilationUnit file, Namespace ns, bool slave)
+               private NamespaceContainer (ModuleContainer module, NamespaceContainer parent, CompilationSourceFile file, Namespace ns, bool slave)
                {
+                       this.module = module;
                        this.parent = parent;
                        this.file = file;
                        this.IsImplicit = true;
                        this.ns = ns;
-                       this.SlaveDeclSpace = slave ? new RootDeclSpace (this) : null;
+                       this.SlaveDeclSpace = slave ? new RootDeclSpace (module, this) : null;
                }
 
-               //
-               // Populates the Namespace with some using declarations, used by the
-               // eval mode. 
-               //
-               public void Populate (List<UsingAliasEntry> source_using_aliases, List<UsingEntry> source_using_clauses)
-               {
-                       foreach (UsingAliasEntry uae in source_using_aliases){
-                               if (using_aliases == null)
-                                       using_aliases = new List<UsingAliasEntry> ();
-                               
-                               using_aliases.Add (uae);
+               #region Properties
+
+               public Location Location {
+                       get {
+                               return loc;
                        }
+               }
 
-                       foreach (UsingEntry ue in source_using_clauses){
-                               if (using_clauses == null)
-                                       using_clauses = new List<UsingEntry> ();
-                               
-                               using_clauses.Add (ue);
+               public MemberName MemberName {
+                       get {
+                               return ns.MemberName;
+                       }
+               }
+
+               public CompilationSourceFile SourceFile {
+                       get {
+                               return file;
                        }
                }
 
+               public List<NamespaceUsing> Usings {
+                       get {
+                               return using_clauses;
+                       }
+               }
+
+               #endregion
+
                //
                // Extracts the using alises and using clauses into a couple of
                // arrays that might already have the same information;  Used by the
                // C# Eval mode.
                //
-               public void Extract (List<UsingAliasEntry> out_using_aliases, List<UsingEntry> out_using_clauses)
+               public void Extract (List<NamespaceUsingAlias> out_using_aliases, List<NamespaceUsing> out_using_clauses)
                {
                        if (using_aliases != null){
-                               foreach (UsingAliasEntry uae in using_aliases){
+                               foreach (NamespaceUsingAlias uae in using_aliases){
                                        bool replaced = false;
                                        
                                        for (int i = 0; i < out_using_aliases.Count; i++){
-                                               UsingAliasEntry out_uea = (UsingAliasEntry) out_using_aliases [i];
+                                               NamespaceUsingAlias out_uea = (NamespaceUsingAlias) out_using_aliases [i];
                                                
                                                if (out_uea.Alias == uae.Alias){
                                                        out_using_aliases [i] = uae;
@@ -869,10 +650,10 @@ namespace Mono.CSharp {
                        }
 
                        if (using_clauses != null){
-                               foreach (UsingEntry ue in using_clauses){
+                               foreach (NamespaceUsing ue in using_clauses){
                                        bool found = false;
                                        
-                                       foreach (UsingEntry out_ue in out_using_clauses)
+                                       foreach (NamespaceUsing out_ue in out_using_clauses)
                                                if (out_ue.Name == ue.Name){
                                                        found = true;
                                                        break;
@@ -893,11 +674,11 @@ namespace Mono.CSharp {
                // To implement these rules, the expressions in the using directives are resolved using 
                // the "doppelganger" (ghostly bodiless duplicate).
                //
-               NamespaceEntry doppelganger;
-               NamespaceEntry Doppelganger {
+               NamespaceContainer doppelganger;
+               NamespaceContainer Doppelganger {
                        get {
                                if (!IsImplicit && doppelganger == null) {
-                                       doppelganger = new NamespaceEntry (ImplicitParent, file, ns, true);
+                                       doppelganger = new NamespaceContainer (module, ImplicitParent, file, ns, true);
                                        doppelganger.using_aliases = using_aliases;
                                }
                                return doppelganger;
@@ -908,18 +689,18 @@ namespace Mono.CSharp {
                        get { return ns; }
                }
 
-               public NamespaceEntry Parent {
+               public NamespaceContainer Parent {
                        get { return parent; }
                }
 
-               public NamespaceEntry ImplicitParent {
+               public NamespaceContainer ImplicitParent {
                        get {
                                if (parent == null)
                                        return null;
                                if (implicit_parent == null) {
                                        implicit_parent = (parent.NS == ns.Parent)
                                                ? parent
-                                               : new NamespaceEntry (parent, file, ns.Parent, false);
+                                               : new NamespaceContainer (module, parent, file, ns.Parent, false);
                                }
                                return implicit_parent;
                        }
@@ -935,9 +716,9 @@ namespace Mono.CSharp {
                        }
 
                        if (using_clauses == null) {
-                               using_clauses = new List<UsingEntry> ();
+                               using_clauses = new List<NamespaceUsing> ();
                        } else {
-                               foreach (UsingEntry old_entry in using_clauses) {
+                               foreach (NamespaceUsing old_entry in using_clauses) {
                                        if (name.Equals (old_entry.MemberName)) {
                                                Compiler.Report.SymbolRelatedToPreviousError (old_entry.Location, old_entry.GetSignatureForError ());
                                                Compiler.Report.Warning (105, 3, loc, "The using directive for `{0}' appeared previously in this namespace", name.GetSignatureForError ());
@@ -946,29 +727,23 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       using_clauses.Add (new UsingEntry (name));
+                       using_clauses.Add (new NamespaceUsing (name));
                }
 
                public void AddUsingAlias (string alias, MemberName name, Location loc)
                {
-                       // TODO: This is parser bussines
                        if (DeclarationFound){
                                Compiler.Report.Error (1529, loc, "A using clause must precede all other namespace elements except extern alias declarations");
                        }
 
-                       if (RootContext.Version != LanguageVersion.ISO_1 && alias == "global")
-                               Compiler.Report.Warning (440, 2, loc, "An alias named `global' will not be used when resolving 'global::';" +
-                                       " the global namespace will be used instead");
-
                        AddUsingAlias (new LocalUsingAliasEntry (alias, name, loc));
                }
 
                public void AddUsingExternalAlias (string alias, Location loc, Report Report)
                {
-                       // TODO: Do this in parser
                        bool not_first = using_clauses != null || DeclarationFound;
                        if (using_aliases != null && !not_first) {
-                               foreach (UsingAliasEntry uae in using_aliases) {
+                               foreach (NamespaceUsingAlias uae in using_aliases) {
                                        if (uae is LocalUsingAliasEntry) {
                                                not_first = true;
                                                break;
@@ -984,15 +759,15 @@ namespace Mono.CSharp {
                                return;
                        }
 
-                       AddUsingAlias (new UsingAliasEntry (alias, loc));
+                       AddUsingAlias (new NamespaceUsingAlias (alias, loc));
                }
 
-               void AddUsingAlias (UsingAliasEntry uae)
+               void AddUsingAlias (NamespaceUsingAlias uae)
                {
                        if (using_aliases == null) {
-                               using_aliases = new List<UsingAliasEntry> ();
+                               using_aliases = new List<NamespaceUsingAlias> ();
                        } else {
-                               foreach (UsingAliasEntry entry in using_aliases) {
+                               foreach (NamespaceUsingAlias entry in using_aliases) {
                                        if (uae.Alias == entry.Alias) {
                                                Compiler.Report.SymbolRelatedToPreviousError (uae.Location, uae.Alias);
                                                Compiler.Report.Error (1537, entry.Location, "The using alias `{0}' appeared previously in this namespace",
@@ -1005,15 +780,15 @@ namespace Mono.CSharp {
                        using_aliases.Add (uae);
                }
 
-               ///
-               /// Does extension methods look up to find a method which matches name and extensionType.
-               /// Search starts from this namespace and continues hierarchically up to top level.
-               ///
-               public ExtensionMethodGroupExpr LookupExtensionMethod (TypeSpec extensionType, string name, int arity, Location loc)
+               //
+               // Does extension methods look up to find a method which matches name and extensionType.
+               // Search starts from this namespace and continues hierarchically up to top level.
+               //
+               public IList<MethodSpec> LookupExtensionMethod (TypeSpec extensionType, string name, int arity, ref NamespaceContainer scope)
                {
                        List<MethodSpec> candidates = null;
                        foreach (Namespace n in GetUsingTable ()) {
-                               var a = n.LookupExtensionMethod (extensionType, null, name, arity);
+                               var a = n.LookupExtensionMethod (this, extensionType, name, arity);
                                if (a == null)
                                        continue;
 
@@ -1023,8 +798,9 @@ namespace Mono.CSharp {
                                        candidates.AddRange (a);
                        }
 
+                       scope = parent;
                        if (candidates != null)
-                               return new ExtensionMethodGroupExpr (candidates, parent, extensionType, loc);
+                               return candidates;
 
                        if (parent == null)
                                return null;
@@ -1034,9 +810,9 @@ namespace Mono.CSharp {
                        //
                        Namespace parent_ns = ns.Parent;
                        do {
-                               candidates = parent_ns.LookupExtensionMethod (extensionType, null, name, arity);
+                               candidates = parent_ns.LookupExtensionMethod (this, extensionType, name, arity);
                                if (candidates != null)
-                                       return new ExtensionMethodGroupExpr (candidates, parent, extensionType, loc);
+                                       return candidates;
 
                                parent_ns = parent_ns.Parent;
                        } while (parent_ns != null);
@@ -1044,14 +820,14 @@ namespace Mono.CSharp {
                        //
                        // Continue in parent scope
                        //
-                       return parent.LookupExtensionMethod (extensionType, name, arity, loc);
+                       return parent.LookupExtensionMethod (extensionType, name, arity, ref scope);
                }
 
                public FullNamedExpression LookupNamespaceOrType (string name, int arity, Location loc, bool ignore_cs0104)
                {
                        // Precondition: Only simple names (no dots) will be looked up with this function.
                        FullNamedExpression resolved = null;
-                       for (NamespaceEntry curr_ns = this; curr_ns != null; curr_ns = curr_ns.ImplicitParent) {
+                       for (NamespaceContainer curr_ns = this; curr_ns != null; curr_ns = curr_ns.ImplicitParent) {
                                if ((resolved = curr_ns.Lookup (name, arity, loc, ignore_cs0104)) != null)
                                        break;
                        }
@@ -1063,7 +839,7 @@ namespace Mono.CSharp {
                {
                        IEnumerable<string> all = Enumerable.Empty<string> ();
                        
-                       for (NamespaceEntry curr_ns = this; curr_ns != null; curr_ns = curr_ns.ImplicitParent){
+                       for (NamespaceContainer curr_ns = this; curr_ns != null; curr_ns = curr_ns.ImplicitParent){
                                foreach (Namespace using_ns in GetUsingTable ()){
                                        if (prefix.StartsWith (using_ns.Name)){
                                                int ld = prefix.LastIndexOf ('.');
@@ -1083,13 +859,13 @@ namespace Mono.CSharp {
                // Looks-up a alias named @name in this and surrounding namespace declarations
                public FullNamedExpression LookupNamespaceAlias (string name)
                {
-                       for (NamespaceEntry n = this; n != null; n = n.ImplicitParent) {
+                       for (NamespaceContainer n = this; n != null; n = n.ImplicitParent) {
                                if (n.using_aliases == null)
                                        continue;
 
-                               foreach (UsingAliasEntry ue in n.using_aliases) {
+                               foreach (NamespaceUsingAlias ue in n.using_aliases) {
                                        if (ue.Alias == name)
-                                               return ue.Resolve (Doppelganger);
+                                               return ue.Resolve (Doppelganger ?? this, Doppelganger == null);
                                }
                        }
 
@@ -1101,13 +877,13 @@ namespace Mono.CSharp {
                        //
                        // Check whether it's in the namespace.
                        //
-                       FullNamedExpression fne = ns.Lookup (Compiler, name, arity, loc);
+                       FullNamedExpression fne = ns.LookupTypeOrNamespace (this, name, arity, loc);
 
                        //
                        // Check aliases. 
                        //
                        if (using_aliases != null && arity == 0) {
-                               foreach (UsingAliasEntry ue in using_aliases) {
+                               foreach (NamespaceUsingAlias ue in using_aliases) {
                                        if (ue.Alias == name) {
                                                if (fne != null) {
                                                        if (Doppelganger != null) {
@@ -1122,13 +898,13 @@ namespace Mono.CSharp {
                                                        }
                                                }
 
-                                               return ue.Resolve (Doppelganger);
+                                               return ue.Resolve (Doppelganger ?? this, Doppelganger == null);
                                        }
                                }
                        }
 
                        if (fne != null) {
-                               if (!((fne.Type.Modifiers & Modifiers.INTERNAL) != 0 && !TypeManager.IsThisOrFriendAssembly (CodeGen.Assembly.Builder, fne.Type.Assembly)))
+                               if (!((fne.Type.Modifiers & Modifiers.INTERNAL) != 0 && !fne.Type.MemberDefinition.IsInternalAsPublic (module.DeclaringAssembly)))
                                        return fne;
                        }
 
@@ -1140,7 +916,9 @@ namespace Mono.CSharp {
                        //
                        FullNamedExpression match = null;
                        foreach (Namespace using_ns in GetUsingTable ()) {
-                               fne = using_ns.Lookup (Compiler, name, arity, loc);
+                               // A using directive imports only types contained in the namespace, it
+                               // does not import any nested namespaces
+                               fne = using_ns.LookupType (this, name, arity, loc);
                                if (fne == null)
                                        continue;
 
@@ -1155,7 +933,7 @@ namespace Mono.CSharp {
                                if (texpr_fne != null && texpr_match == null) {
                                        match = fne;
                                        continue;
-                               } else if (texpr_fne == null && texpr_match != null) {
+                               } else if (texpr_fne == null) {
                                        continue;
                                }
 
@@ -1163,7 +941,7 @@ namespace Mono.CSharp {
                                        return match;
 
                                // It can be top level accessibility only
-                               var better = Namespace.IsImportedTypeOverride (texpr_match.Type, texpr_fne.Type);
+                               var better = Namespace.IsImportedTypeOverride (module, texpr_match.Type, texpr_fne.Type);
                                if (better == null) {
                                        Compiler.Report.SymbolRelatedToPreviousError (texpr_match.Type);
                                        Compiler.Report.SymbolRelatedToPreviousError (texpr_fne.Type);
@@ -1191,7 +969,7 @@ namespace Mono.CSharp {
 
                        var list = new List<Namespace> (using_clauses.Count);
 
-                       foreach (UsingEntry ue in using_clauses) {
+                       foreach (NamespaceUsing ue in using_clauses) {
                                Namespace using_ns = ue.Resolve (Doppelganger);
                                if (using_ns == null)
                                        continue;
@@ -1203,8 +981,6 @@ namespace Mono.CSharp {
                        return namespace_using_table;
                }
 
-               static readonly string [] empty_using_list = new string [0];
-
                public int SymbolFileID {
                        get {
                                if (symfile_id == 0 && file.SourceFileEntry != null) {
@@ -1214,7 +990,7 @@ namespace Mono.CSharp {
                                        if (using_clauses != null) {
                                                using_list = new string [using_clauses.Count];
                                                for (int i = 0; i < using_clauses.Count; i++)
-                                                       using_list [i] = ((UsingEntry) using_clauses [i]).MemberName.GetName ();
+                                                       using_list [i] = ((NamespaceUsing) using_clauses [i]).MemberName.GetName ();
                                        }
 
                                        symfile_id = SymbolWriter.DefineNamespace (ns.Name, file.CompileUnitEntry, using_list, parent_id);
@@ -1235,7 +1011,7 @@ namespace Mono.CSharp {
 
                public static void Error_GlobalNamespaceRedefined (Location loc, Report Report)
                {
-                       Report.Error (1681, loc, "You cannot redefine the global extern alias");
+                       Report.Error (1681, loc, "The global extern alias cannot be redefined");
                }
 
                public static void Error_NamespaceNotFound (Location loc, string name, Report Report)
@@ -1245,15 +1021,15 @@ namespace Mono.CSharp {
 
                        switch (name) {
                        case "Gtk": case "GtkSharp":
-                               MsgtryPkg ("gtk-sharp");
+                               MsgtryPkg ("gtk-sharp-2.0");
                                break;
 
                        case "Gdk": case "GdkSharp":
-                               MsgtryPkg ("gdk-sharp");
+                               MsgtryPkg ("gdk-sharp-2.0");
                                break;
 
                        case "Glade": case "GladeSharp":
-                               MsgtryPkg ("glade-sharp");
+                               MsgtryPkg ("glade-sharp-2.0");
                                break;
 
                        case "System.Drawing":
@@ -1270,27 +1046,25 @@ namespace Mono.CSharp {
                ///   Used to validate that all the using clauses are correct
                ///   after we are finished parsing all the files.  
                /// </summary>
-               void VerifyUsing ()
+               public void Resolve ()
                {
+                       if (resolved)
+                               return;
+
+                       resolved = true;
+
                        if (using_aliases != null) {
-                               foreach (UsingAliasEntry ue in using_aliases)
-                                       ue.Resolve (Doppelganger);
+                               foreach (NamespaceUsingAlias ue in using_aliases)
+                                       ue.Resolve (Doppelganger, Doppelganger == null);
                        }
 
                        if (using_clauses != null) {
-                               foreach (UsingEntry ue in using_clauses)
+                               foreach (NamespaceUsing ue in using_clauses)
                                        ue.Resolve (Doppelganger);
                        }
-               }
 
-               /// <summary>
-               ///   Used to validate that all the using clauses are correct
-               ///   after we are finished parsing all the files.  
-               /// </summary>
-               static public void VerifyAllUsing ()
-               {
-                       foreach (NamespaceEntry entry in entries)
-                               entry.VerifyUsing ();
+                       if (parent != null)
+                               parent.Resolve ();
                }
 
                public string GetSignatureForError ()
@@ -1298,15 +1072,10 @@ namespace Mono.CSharp {
                        return ns.GetSignatureForError ();
                }
 
-               public override string ToString ()
-               {
-                       return ns.ToString ();
-               }
-
                #region IMemberContext Members
 
-               public CompilerContext Compiler {
-                       get { return RootContext.ToplevelTypes.Compiler; }
+               CompilerContext Compiler {
+                       get { return module.Compiler; }
                }
 
                public TypeSpec CurrentType {
@@ -1321,8 +1090,9 @@ namespace Mono.CSharp {
                        get { return SlaveDeclSpace.CurrentTypeParameters; }
                }
 
+               // FIXME: It's false for expression types
                public bool HasUnresolvedConstraints {
-                       get { return false; }
+                       get { return true; }
                }
 
                public bool IsObsolete {
@@ -1337,6 +1107,116 @@ namespace Mono.CSharp {
                        get { return SlaveDeclSpace.IsStatic; }
                }
 
+               public ModuleContainer Module {
+                       get { return module; }
+               }
+
                #endregion
        }
+
+       public class NamespaceUsing
+       {
+               readonly MemberName name;
+               Namespace resolved;
+
+               public NamespaceUsing (MemberName name)
+               {
+                       this.name = name;
+               }
+
+               public string GetSignatureForError ()
+               {
+                       return name.GetSignatureForError ();
+               }
+
+               public Location Location
+               {
+                       get { return name.Location; }
+               }
+
+               public MemberName MemberName
+               {
+                       get { return name; }
+               }
+
+               public string Name
+               {
+                       get { return GetSignatureForError (); }
+               }
+
+               public Namespace Resolve (IMemberContext rc)
+               {
+                       if (resolved != null)
+                               return resolved;
+
+                       FullNamedExpression fne = name.GetTypeExpression ().ResolveAsTypeOrNamespace (rc);
+                       if (fne == null)
+                               return null;
+
+                       resolved = fne as Namespace;
+                       if (resolved == null) {
+                               rc.Module.Compiler.Report.SymbolRelatedToPreviousError (fne.Type);
+                               rc.Module.Compiler.Report.Error (138, Location,
+                                       "`{0}' is a type not a namespace. A using namespace directive can only be applied to namespaces",
+                                       GetSignatureForError ());
+                       }
+                       return resolved;
+               }
+       }
+
+       public class NamespaceUsingAlias
+       {
+               public readonly string Alias;
+               public Location Location;
+
+               public NamespaceUsingAlias (string alias, Location loc)
+               {
+                       this.Alias = alias;
+                       this.Location = loc;
+               }
+
+               public virtual FullNamedExpression Resolve (IMemberContext rc, bool local)
+               {
+                       FullNamedExpression fne = rc.Module.GetRootNamespace (Alias);
+                       if (fne == null) {
+                               rc.Module.Compiler.Report.Error (430, Location,
+                                       "The extern alias `{0}' was not specified in -reference option",
+                                       Alias);
+                       }
+
+                       return fne;
+               }
+       }
+
+       class LocalUsingAliasEntry : NamespaceUsingAlias
+       {
+               FullNamedExpression resolved;
+               MemberName value;
+
+               public LocalUsingAliasEntry (string alias, MemberName name, Location loc)
+                       : base (alias, loc)
+               {
+                       this.value = name;
+               }
+
+               public override FullNamedExpression Resolve (IMemberContext rc, bool local)
+               {
+                       if (resolved != null || value == null)
+                               return resolved;
+
+                       if (local)
+                               return null;
+
+                       resolved = value.GetTypeExpression ().ResolveAsTypeOrNamespace (rc);
+                       if (resolved == null) {
+                               value = null;
+                               return null;
+                       }
+
+                       if (resolved is TypeExpr)
+                               resolved = resolved.ResolveAsType (rc);
+
+                       return resolved;
+               }
+       }
 }