Merge branch 'bugfix-main-thread-root'
[mono.git] / mcs / mcs / namespace.cs
index f2b9404a8bfe207ec09b77a18520fcef3d7a447f..c30f09a0cd4586dfb640c2a4033fe3474fd9ec69 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 {
-                                       ctx.MetaImporter.ImportAssembly (a, this);
-                               } 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;
                        }
                }
 
@@ -83,87 +57,19 @@ namespace Mono.CSharp {
                }
        }
 
-       public class GlobalRootNamespace : RootNamespace {
-               Module [] modules;
-               Dictionary<string, RootNamespace> root_namespaces;
-
-               // TODO: Breaks dynamic/eval
-               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>
@@ -255,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);
+                       FullNamedExpression retval = Lookup (ctx, name, -System.Math.Max (1, arity), loc);
                        if (retval != null) {
-                               Error_TypeArgumentsCannotBeUsed (ctx.Compiler.Report, loc, retval.Type, arity);
+                               Error_TypeArgumentsCannotBeUsed (ctx.Module.Compiler.Report, loc, retval.Type, arity);
                                return;
                        }
 
                        Namespace ns;
                        if (arity > 0 && namespaces.TryGetValue (name, out ns)) {
-                               ns.Error_TypeArgumentsCannotBeUsed (ctx.Compiler.Report, loc, null, arity);
+                               ns.Error_TypeArgumentsCannotBeUsed (ctx.Module.Compiler.Report, loc, null, arity);
                                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 ());
                }
@@ -302,7 +208,7 @@ namespace Mono.CSharp {
                        return ns;
                }
 
-               public TypeExpr LookupType (CompilerContext ctx, string name, int arity, bool silent, Location loc)
+               public TypeExpr LookupType (IMemberContext ctx, string name, int arity, bool silent, Location loc)
                {
                        if (types == null)
                                return null;
@@ -323,16 +229,16 @@ namespace Mono.CSharp {
                                                continue;
                                        }
 
-                                       var pts = best as PredefinedTypeSpec;
+                                       var pts = best as BuildinTypeSpec;
                                        if (pts == null)
-                                               pts = ts as PredefinedTypeSpec;
+                                               pts = ts as BuildinTypeSpec;
 
                                        if (pts != null) {
-                                               ctx.Report.SymbolRelatedToPreviousError (best);
-                                               ctx.Report.SymbolRelatedToPreviousError (ts);
+                                               ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (best);
+                                               ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (ts);
 
                                                // TODO: This should use different warning number but we want to be csc compatible
-                                               ctx.Report.Warning (1685, 1, loc,
+                                               ctx.Module.Compiler.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;
@@ -340,14 +246,14 @@ namespace Mono.CSharp {
                                        }
 
                                        if (best.MemberDefinition.IsImported && ts.MemberDefinition.IsImported) {
-                                               ctx.Report.SymbolRelatedToPreviousError (best);
-                                               ctx.Report.SymbolRelatedToPreviousError (ts);
+                                               ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (best);
+                                               ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (ts);
                                                if (silent) {
-                                                       ctx.Report.Warning (1685, 1, loc,
+                                                       ctx.Module.Compiler.Report.Warning (1685, 1, loc,
                                                                "The predefined type `{0}' is defined in multiple assemblies. Using definition from `{1}'",
-                                                               ts.GetSignatureForError (), best.Assembly.GetName ().Name);
+                                                               ts.GetSignatureForError (), best.MemberDefinition.DeclaringAssembly.Name);
                                                } else {
-                                                       ctx.Report.Error (433, loc, "The imported type `{0}' is defined multiple times", ts.GetSignatureForError ());
+                                                       ctx.Module.Compiler.Report.Error (433, loc, "The imported type `{0}' is defined multiple times", ts.GetSignatureForError ());
                                                }
 
                                                break;
@@ -356,16 +262,16 @@ namespace Mono.CSharp {
                                        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 (RootContext.ToplevelTypes.DeclaringAssembly))
                                                continue;
 
                                        if (silent)
                                                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 ());
                                }
@@ -385,6 +291,9 @@ namespace Mono.CSharp {
                        if (best == null)
                                return null;
 
+                       if ((best.Modifiers & Modifiers.INTERNAL) != 0 && !best.MemberDefinition.IsInternalAsPublic (RootContext.ToplevelTypes.DeclaringAssembly))
+                               return null;
+
                        te = new TypeExpression (best, Location.Null);
 
                        // TODO MemberCache: Cache more
@@ -425,7 +334,7 @@ namespace Mono.CSharp {
                        return null;
                }
 
-               public FullNamedExpression Lookup (CompilerContext ctx, string name, int arity, Location loc)
+               public FullNamedExpression Lookup (IMemberContext ctx, string name, int arity, Location loc)
                {
                        if (arity == 0 && namespaces.ContainsKey (name))
                                return namespaces [name];
@@ -454,15 +363,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 (TypeSpec extensionType, TypeContainer invocationContext, 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) {
@@ -470,7 +377,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;
 
@@ -543,8 +450,8 @@ namespace Mono.CSharp {
                //
                public static TypeSpec IsImportedTypeOverride (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 (RootContext.ToplevelTypes.DeclaringAssembly);
+                       var found_accessible = (found.Modifiers & Modifiers.PUBLIC) != 0 || found.MemberDefinition.IsInternalAsPublic (RootContext.ToplevelTypes.DeclaringAssembly);
 
                        if (ts_accessible && !found_accessible)
                                return ts;
@@ -561,7 +468,7 @@ namespace Mono.CSharp {
                        types.Remove (name);
                }
 
-               public void ReplaceTypeWithPredefined (TypeSpec ts, PredefinedTypeSpec pts)
+               public void ReplaceTypeWithPredefined (TypeSpec ts, BuildinTypeSpec pts)
                {
                        var found = types [ts.Name];
                        cached_types.Remove (ts.Name);
@@ -671,8 +578,8 @@ namespace Mono.CSharp {
 
                                resolved = fne as Namespace;
                                if (resolved == null) {
-                                       rc.Compiler.Report.SymbolRelatedToPreviousError (fne.Type);
-                                       rc.Compiler.Report.Error (138, Location,
+                                       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 ());
                                }
@@ -695,11 +602,11 @@ namespace Mono.CSharp {
                                this.Location = loc;
                        }
 
-                       public virtual FullNamedExpression Resolve (IMemberContext rc)
+                       public virtual FullNamedExpression Resolve (IMemberContext rc, bool local)
                        {
-                               FullNamedExpression fne = GlobalRootNamespace.Instance.GetRootNamespace (Alias);
+                               FullNamedExpression fne = rc.Module.GetRootNamespace (Alias);
                                if (fne == null) {
-                                       rc.Compiler.Report.Error (430, Location,
+                                       rc.Module.Compiler.Report.Error (430, Location,
                                                "The extern alias `{0}' was not specified in -reference option",
                                                Alias);
                                }
@@ -724,12 +631,12 @@ namespace Mono.CSharp {
                                this.value = name;
                        }
 
-                       public override FullNamedExpression Resolve (IMemberContext rc)
+                       public override FullNamedExpression Resolve (IMemberContext rc, bool local)
                        {
                                if (resolved != null || value == null)
                                        return resolved;
 
-                               if (rc == null)
+                               if (local)
                                        return null;
 
                                resolved = value.GetTypeExpression ().ResolveAsTypeStep (rc, false);
@@ -765,6 +672,7 @@ namespace Mono.CSharp {
                public readonly DeclSpace SlaveDeclSpace;
                static readonly Namespace [] empty_namespaces = new Namespace [0];
                Namespace [] namespace_using_table;
+               ModuleContainer ctx;
 
                static List<NamespaceEntry> entries = new List<NamespaceEntry> ();
 
@@ -773,8 +681,9 @@ namespace Mono.CSharp {
                        entries = new List<NamespaceEntry> ();
                }
 
-               public NamespaceEntry (NamespaceEntry parent, CompilationUnit file, string name)
+               public NamespaceEntry (ModuleContainer ctx, NamespaceEntry parent, CompilationUnit file, string name)
                {
+                       this.ctx = ctx;
                        this.parent = parent;
                        this.file = file;
                        entries.Add (this);
@@ -782,14 +691,16 @@ namespace Mono.CSharp {
                        if (parent != null)
                                ns = parent.NS.GetNamespace (name, true);
                        else if (name != null)
-                               ns = GlobalRootNamespace.Instance.GetNamespace (name, true);
+                               ns = ctx.GlobalRootNamespace.GetNamespace (name, true);
                        else
-                               ns = GlobalRootNamespace.Instance;
+                               ns = ctx.GlobalRootNamespace;
+
                        SlaveDeclSpace = new RootDeclSpace (this);
                }
 
-               private NamespaceEntry (NamespaceEntry parent, CompilationUnit file, Namespace ns, bool slave)
+               private NamespaceEntry (ModuleContainer ctx, NamespaceEntry parent, CompilationUnit file, Namespace ns, bool slave)
                {
+                       this.ctx = ctx;
                        this.parent = parent;
                        this.file = file;
                        this.IsImplicit = true;
@@ -797,24 +708,9 @@ namespace Mono.CSharp {
                        this.SlaveDeclSpace = slave ? new RootDeclSpace (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);
-                       }
-
-                       foreach (UsingEntry ue in source_using_clauses){
-                               if (using_clauses == null)
-                                       using_clauses = new List<UsingEntry> ();
-                               
-                               using_clauses.Add (ue);
+               public List<UsingEntry> Usings {
+                       get {
+                               return using_clauses;
                        }
                }
 
@@ -872,7 +768,7 @@ namespace Mono.CSharp {
                NamespaceEntry Doppelganger {
                        get {
                                if (!IsImplicit && doppelganger == null) {
-                                       doppelganger = new NamespaceEntry (ImplicitParent, file, ns, true);
+                                       doppelganger = new NamespaceEntry (ctx, ImplicitParent, file, ns, true);
                                        doppelganger.using_aliases = using_aliases;
                                }
                                return doppelganger;
@@ -894,7 +790,7 @@ namespace Mono.CSharp {
                                if (implicit_parent == null) {
                                        implicit_parent = (parent.NS == ns.Parent)
                                                ? parent
-                                               : new NamespaceEntry (parent, file, ns.Parent, false);
+                                               : new NamespaceEntry (ctx, parent, file, ns.Parent, false);
                                }
                                return implicit_parent;
                        }
@@ -988,7 +884,7 @@ namespace Mono.CSharp {
                {
                        List<MethodSpec> candidates = null;
                        foreach (Namespace n in GetUsingTable ()) {
-                               var a = n.LookupExtensionMethod (extensionType, null, name, arity);
+                               var a = n.LookupExtensionMethod (extensionType, RootContext.ToplevelTypes, name, arity);
                                if (a == null)
                                        continue;
 
@@ -1010,7 +906,7 @@ namespace Mono.CSharp {
                        //
                        Namespace parent_ns = ns.Parent;
                        do {
-                               candidates = parent_ns.LookupExtensionMethod (extensionType, null, name, arity);
+                               candidates = parent_ns.LookupExtensionMethod (extensionType, RootContext.ToplevelTypes, name, arity);
                                if (candidates != null)
                                        return candidates;
 
@@ -1065,7 +961,7 @@ namespace Mono.CSharp {
 
                                foreach (UsingAliasEntry ue in n.using_aliases) {
                                        if (ue.Alias == name)
-                                               return ue.Resolve (Doppelganger);
+                                               return ue.Resolve (Doppelganger ?? this, Doppelganger == null);
                                }
                        }
 
@@ -1077,7 +973,7 @@ namespace Mono.CSharp {
                        //
                        // Check whether it's in the namespace.
                        //
-                       FullNamedExpression fne = ns.Lookup (Compiler, name, arity, loc);
+                       FullNamedExpression fne = ns.Lookup (this, name, arity, loc);
 
                        //
                        // Check aliases. 
@@ -1098,13 +994,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 (RootContext.ToplevelTypes.DeclaringAssembly)))
                                        return fne;
                        }
 
@@ -1118,7 +1014,7 @@ namespace Mono.CSharp {
                        foreach (Namespace using_ns in GetUsingTable ()) {
                                // A using directive imports only types contained in the namespace, it
                                // does not import any nested namespaces
-                               fne = using_ns.LookupType (Compiler, name, arity, false, loc);
+                               fne = using_ns.LookupType (this, name, arity, false, loc);
                                if (fne == null)
                                        continue;
 
@@ -1213,7 +1109,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)
@@ -1252,7 +1148,7 @@ namespace Mono.CSharp {
                {
                        if (using_aliases != null) {
                                foreach (UsingAliasEntry ue in using_aliases)
-                                       ue.Resolve (Doppelganger);
+                                       ue.Resolve (Doppelganger, Doppelganger == null);
                        }
 
                        if (using_clauses != null) {
@@ -1284,7 +1180,7 @@ namespace Mono.CSharp {
                #region IMemberContext Members
 
                public CompilerContext Compiler {
-                       get { return RootContext.ToplevelTypes.Compiler; }
+                       get { return ctx.Compiler; }
                }
 
                public TypeSpec CurrentType {
@@ -1316,6 +1212,10 @@ namespace Mono.CSharp {
                        get { return SlaveDeclSpace.IsStatic; }
                }
 
+               public ModuleContainer Module {
+                       get { return ctx; }
+               }
+
                #endregion
        }
 }