*** Merged revisions from mcs: 52039
authorRaja R Harinath <harinath@hurrynot.org>
Fri, 28 Oct 2005 09:47:29 +0000 (09:47 -0000)
committerRaja R Harinath <harinath@hurrynot.org>
Fri, 28 Oct 2005 09:47:29 +0000 (09:47 -0000)
svn path=/trunk/mcs/; revision=52309

14 files changed:
mcs/errors/known-issues-gmcs
mcs/errors/known-issues-mcs
mcs/gmcs/ChangeLog
mcs/gmcs/cs-parser.jay
mcs/gmcs/delegate.cs
mcs/gmcs/doc.cs
mcs/gmcs/driver.cs
mcs/gmcs/ecore.cs
mcs/gmcs/expression.cs
mcs/gmcs/namespace.cs
mcs/gmcs/symbolwriter.cs
mcs/gmcs/typemanager.cs
mcs/tests/known-issues-gmcs
mcs/tests/known-issues-mcs

index febc7d5967cecf3d28850c4f138aa56178bc0ce7..11715739970910196b6fd10c44edfc80bb05b123 100644 (file)
@@ -33,6 +33,7 @@ cs1013.cs # new in GMCS; grammar issue
 cs1041.cs # new in GMCS; grammar issue
 cs1058.cs NO ERROR
 cs1501-5.cs
+cs1502-5.cs NO ERROR
 cs1507.cs
 cs1508-2.cs NO ERROR
 cs1508.cs NO ERROR
@@ -49,12 +50,3 @@ cs1666.cs NO ERROR
 cs1706.cs
 cs1718.cs NO ERROR
 cs1906.cs NO ERROR
-cs0430.cs IGNORE
-cs0439.cs IGNORE
-cs0439-2.cs IGNORE
-cs1502-5.cs NO ERROR
-cs1537-2.cs IGNORE
-cs1537-3.cs IGNORE
-cs1680.cs IGNORE
-cs1679.cs IGNORE
-cs1681.cs IGNORE
index 69e3d312461aead75b72649f6c1063edb8ddf28b..3f7d757ab5960ecfb5c039e5c57150d9ea3e3975 100644 (file)
 # csXXXX.cs NO ERROR   : error test case doesn't report any error. An exception is considered
 #                        as NO ERROR and CS5001 is automatically ignored.
 
-cs0229.cs NO ERROR
 cs0229-2.cs
+cs0229.cs NO ERROR
 cs0525.cs
 cs0526.cs
 cs0547.cs
-cs0548.cs
 cs0548-4.cs
+cs0548.cs
 cs0560.cs
 cs0567.cs
 cs0612-2.cs NO ERROR
 cs0619-42.cs
 cs1501-5.cs
+cs1507.cs
+cs1508-2.cs NO ERROR
+cs1508.cs NO ERROR
 cs1513.cs
 cs1518.cs
 cs1525.cs
 cs1528.cs
+cs1566.cs
 cs1586.cs
 cs1641.cs
 cs1666.cs NO ERROR
+cs1906.cs NO ERROR
index f8c98866c710be32f08b4f96386d2877b6c84acb..df92c0a96580e1bfc78f2e5b8e4c2cb43b0386e0 100644 (file)
@@ -1,3 +1,23 @@
+2005-10-19  Carlos Alberto Cortez <calberto.cortez@gmail.com>
+
+       Add support for extern alias qualifiers.
+       * typemanager.cs: Move some LookupTypeReflection code
+       to namespace.cs, to have cleaner code. Added some methods
+       to help us keep track of the extern aliased references.
+       * driver.cs: Add suport for extern alias assemblies on command
+       line and check for their warnings/errors. Also keep track of the
+       extern aliased assemblies.
+       * namespace.cs: Move the global functionality of Namespace
+       to GlobalRootNamespace/RootNamespace. Now the global namespace
+       is GlobalRootNamespace.Globa. Also the code moved from 
+       typemanager.cs lives in GlobalRootNames.cs/RootNamespace.cs. 
+       Finally added LocalAliasEntry (AliasEntry before) and
+       ExternAliasEntry, to handle alias statements.
+       * cs-parser.jay: Add support in the grammar for extern alias
+       statement.
+       * doc.cs, delegate.cs, expression.cs ecore.cs, symbolwriter.cs: 
+       Update callings to Namespace (now in GlobalRootNamespace).
+
 2005-10-25  Martin Baulig  <martin@ximian.com>
 
        * convert.cs (ImplicitTypeParameterConversion): Make base
index 5de4a7a30a17fa680508f1b097cacbeafb303d04..125e65d57e580dac4396a9131bdc8c9a8c23962d 100644 (file)
@@ -315,10 +315,31 @@ outer_declarations
         ;
  
 outer_declaration
-        : using_directive
+       : extern_alias_directive
+        | using_directive 
         | namespace_member_declaration
         ;
-  
+
+extern_alias_directives
+       : extern_alias_directive
+       | extern_alias_directives extern_alias_directive;
+
+extern_alias_directive
+       : EXTERN IDENTIFIER IDENTIFIER SEMICOLON
+         {
+               LocatedToken lt = (LocatedToken) $2;
+               string s = lt.Value;
+               if (s != "alias"){
+                       Report.Error (1003, lt.Location, "'alias' expected");
+               } else if (RootContext.Version == LanguageVersion.ISO_1) {
+                       Report.FeatureIsNotStandardized (lt.Location, "external alias");
+               } else {
+                       lt = (LocatedToken) $3; 
+                       current_namespace.UsingExternalAlias (lt.Value, lt.Location);
+               }
+         }
+       ;
 using_directives
        : using_directive 
        | using_directives using_directive
@@ -343,6 +364,7 @@ using_alias_directive
          {
                LocatedToken lt = (LocatedToken) $2;
                current_namespace.UsingAlias (lt.Value, (MemberName) $4, (Location) $1);
+               current_namespace.UsingFound = true;
          }
        | USING error {
                CheckIdentifierToken (yyToken, GetLocation ($2));
@@ -353,6 +375,7 @@ using_namespace_directive
        : USING namespace_name SEMICOLON 
          {
                current_namespace.Using ((MemberName) $2, (Location) $1);
+               current_namespace.UsingFound = true;
           }
        ;
 
@@ -409,6 +432,7 @@ namespace_body
                if (RootContext.Documentation != null)
                        Lexer.doc_state = XmlCommentState.Allowed;
          }
+         opt_extern_alias_directives
          opt_using_directives
          opt_namespace_member_declarations
          CLOSE_BRACE
@@ -419,6 +443,11 @@ opt_using_directives
        | using_directives
        ;
 
+opt_extern_alias_directives
+       : /* empty */
+       | extern_alias_directives
+       ;
+
 opt_namespace_member_declarations
        : /* empty */
        | namespace_member_declarations
index cc37542b1c56c8e567141823ffb1997312d4517c..7a863c0ad9c8be351531f6f4573daa163e221ab5 100644 (file)
@@ -88,7 +88,7 @@ namespace Mono.CSharp {
                        }
                        
                        if (TypeManager.multicast_delegate_type == null && !RootContext.StdLib) {
-                               Namespace system = Namespace.LookupNamespace ("System", true);
+                               Namespace system = RootNamespace.Global.GetNamespace ("System", true);
                                TypeExpr expr = system.Lookup (this, "MulticastDelegate", Location) as TypeExpr;
                                TypeManager.multicast_delegate_type = expr.ResolveType (ec);
                        }
@@ -282,7 +282,7 @@ namespace Mono.CSharp {
                        }
                        if (Parameters.ArrayParameter != null){
                                if (TypeManager.param_array_type == null && !RootContext.StdLib) {
-                                       Namespace system = Namespace.LookupNamespace ("System", true);
+                                       Namespace system = RootNamespace.Global.GetNamespace ("System", true);
                                        TypeExpr expr = system.Lookup (this, "ParamArrayAttribute", Location) as TypeExpr;
                                        TypeManager.param_array_type = expr.ResolveType (ec);
                                }
index dd9bf36120bf9ea8f1e65728afa22bc5a2bac99c..01f31c356e35f1063334abb37e31eb05bfda1549 100644 (file)
@@ -590,7 +590,7 @@ namespace Mono.CSharp {
                        }
 
                        // don't use identifier here. System[] is not alloed.
-                       if (Namespace.IsNamespace (name)) {
+                       if (GlobalRootNamespace.IsNamespace (name)) {
                                xref.SetAttribute ("cref", "N:" + name);
                                return; // a namespace
                        }
index 63d95d355c1fca7c30265f44e6ea8c372a90ff5b..c9b125789ae2d4f6da0ece548d269629f919cb94 100644 (file)
@@ -43,6 +43,11 @@ namespace Mono.CSharp
                //
                static ArrayList soft_references;
 
+               // 
+               // External aliases for assemblies.
+               //
+               static Hashtable external_aliases;
+
                //
                // Modules to be linked
                //
@@ -305,6 +310,11 @@ namespace Mono.CSharp
                }
 
                static public void LoadAssembly (string assembly, bool soft)
+               {
+                       LoadAssembly (assembly, null, soft);
+               }
+
+               static public void LoadAssembly (string assembly, string alias, bool soft)
                {
                        Assembly a;
                        string total_log = "";
@@ -320,7 +330,11 @@ namespace Mono.CSharp
                                                ass = assembly.Substring (0, assembly.Length - 4);
                                        a = Assembly.Load (ass);
                                }
-                               TypeManager.AddAssembly (a);
+                               // Extern aliased refs require special handling
+                               if (alias == null)
+                                       TypeManager.AddAssembly (a);
+                               else
+                                       TypeManager.AddExternAlias (alias, a);
 
                        } catch (FileNotFoundException){
                                foreach (string dir in link_paths){
@@ -330,7 +344,10 @@ namespace Mono.CSharp
 
                                        try {
                                                a = Assembly.LoadFrom (full_path);
-                                               TypeManager.AddAssembly (a);
+                                               if (alias == null)
+                                                       TypeManager.AddAssembly (a);
+                                               else
+                                                       TypeManager.AddExternAlias (alias, a);
                                                return;
                                        } catch (FileNotFoundException ff) {
                                                total_log += ff.FusionLog;
@@ -406,6 +423,9 @@ namespace Mono.CSharp
 
                        foreach (string r in soft_references)
                                LoadAssembly (r, true);
+
+                       foreach (DictionaryEntry entry in external_aliases)
+                               LoadAssembly ((string) entry.Value, (string) entry.Key, false);
                        
                        return;
                }
@@ -801,7 +821,16 @@ namespace Mono.CSharp
                                        Environment.Exit (1);
                                }
                                
-                               references.Add (args [++i]);
+                               string val = args [++i];
+                               int idx = val.IndexOf ('=');
+                               if (idx > -1) {
+                                       string alias = val.Substring (0, idx);
+                                       string assembly = val.Substring (idx + 1);
+                                       AddExternAlias (alias, assembly);
+                                       return true;
+                               }
+
+                               references.Add (val);
                                return true;
                                
                        case "-L":
@@ -1093,7 +1122,16 @@ namespace Mono.CSharp
 
                                string [] refs = value.Split (new char [] { ';', ',' });
                                foreach (string r in refs){
-                                       references.Add (r);
+                                       string val = r;
+                                       int index = val.IndexOf ("=");
+                                       if (index > -1) {
+                                               string alias = r.Substring (0, index);
+                                               string assembly = r.Substring (index + 1);
+                                               AddExternAlias (alias, assembly);
+                                               return true;
+                                       }
+                                       
+                                       references.Add (val);
                                }
                                return true;
                        }
@@ -1352,6 +1390,44 @@ namespace Mono.CSharp
 
                        return new_args;
                }
+
+               static void AddExternAlias (string identifier, string assembly)
+               {
+                       if (assembly.Length == 0) {
+                               Report.Error (1680, "Invalid reference alias '" + identifier + "='. Missing filename");
+                               return;
+                       }
+
+                       if (!IsExternAliasValid (identifier)) {
+                               Report.Error (1679, "Invalid extern alias for /reference. Alias '" + identifier + "' is not a valid identifier");
+                               return;
+                       }
+                       
+                       // Could here hashtable throw an exception?
+                       external_aliases [identifier] = assembly;
+               }
+               
+               static bool IsExternAliasValid (string identifier)
+               {
+                       if (identifier.Length == 0)
+                               return false;
+                       if (identifier [0] != '_' && !Char.IsLetter (identifier [0]))
+                               return false;
+
+                       for (int i = 1; i < identifier.Length; i++) {
+                               char c = identifier [i];
+                               if (Char.IsLetter (c) || Char.IsDigit (c))
+                                       continue;
+
+                               UnicodeCategory category = Char.GetUnicodeCategory (c);
+                               if (category != UnicodeCategory.Format || category != UnicodeCategory.NonSpacingMark ||
+                                               category != UnicodeCategory.SpacingCombiningMark ||
+                                               category != UnicodeCategory.ConnectorPunctuation)
+                                       return false;
+                       }
+                       
+                       return true;
+               }
                
                /// <summary>
                ///    Parses the arguments, and drives the compilation
@@ -1378,6 +1454,7 @@ namespace Mono.CSharp
                        encoding = default_encoding;
 
                        references = new ArrayList ();
+                       external_aliases = new Hashtable ();
                        soft_references = new ArrayList ();
                        modules = new ArrayList ();
                        link_paths = new ArrayList ();
@@ -1612,7 +1689,7 @@ namespace Mono.CSharp
                        //
                        // Verify using aliases now
                        //
-                       Namespace.VerifyUsing ();
+                       GlobalRootNamespace.VerifyUsingForAll ();
                        
                        if (Report.Errors > 0){
                                return false;
@@ -1825,7 +1902,7 @@ namespace Mono.CSharp
                        Report.Reset ();
                        TypeManager.Reset ();
                        TypeHandle.Reset ();
-                       Namespace.Reset ();
+                       GlobalRootNamespace.Reset ();
                        CodeGen.Reset ();
                }
        }
index 7cf339bd1f7fa331f5f85aa5c0bf8c47cf54d4a1..c705aa1ca144d8a065203bdb27f8336be7dab477 100644 (file)
@@ -2406,7 +2406,7 @@ namespace Mono.CSharp {
                                lookup_name = name.Substring (0, pos);
                        }
 
-                       FullNamedExpression resolved = Namespace.Root.Lookup (ec.DeclSpace, lookup_name, Location.Null);
+                       FullNamedExpression resolved = RootNamespace.Global.Lookup (ec.DeclSpace, lookup_name, Location.Null);
 
                        if (resolved != null && rest != null) {
                                // Now handle the rest of the the name.
index dad971332431f25d5370495b330041392c1775b0..3e95a228617a45cf4cf967456efbcbb3148454e3 100644 (file)
@@ -7090,7 +7090,7 @@ namespace Mono.CSharp {
                public override FullNamedExpression ResolveAsTypeStep (EmitContext ec, bool silent)
                {
                        if (alias == "global")
-                               return new MemberAccess (Namespace.Root, identifier, loc).ResolveAsTypeStep (ec, silent);
+                               return new MemberAccess (RootNamespace.Global, identifier, loc).ResolveAsTypeStep (ec, silent);
 
                        int errors = Report.Errors;
                        FullNamedExpression fne = ec.DeclSpace.NamespaceEntry.LookupAlias (alias);
@@ -7111,7 +7111,7 @@ namespace Mono.CSharp {
                {
                        FullNamedExpression fne;
                        if (alias == "global") {
-                               fne = Namespace.Root;
+                               fne = RootNamespace.Global;
                        } else {
                                int errors = Report.Errors;
                                fne = ec.DeclSpace.NamespaceEntry.LookupAlias (alias);
index 72c853919bed8e10990f025db57bacdb7a631e7d..7e019c181b0528962c2d818b6564fedd2566cfb6 100644 (file)
@@ -9,9 +9,256 @@
 using System;
 using System.Collections;
 using System.Collections.Specialized;
+using System.Reflection;
 
 namespace Mono.CSharp {
 
+       public class RootNamespace : Namespace
+       {
+               static MethodInfo get_namespaces_method;
+
+               Assembly referenced_assembly;
+               Hashtable cached_namespaces;
+               
+               static RootNamespace ()
+               {
+                       get_namespaces_method = typeof (Assembly).GetMethod ("GetNamespaces", BindingFlags.Instance | BindingFlags.NonPublic);
+               }
+
+               //
+               // We access GlobalRoot here to beautify the code
+               //
+               public static GlobalRootNamespace Global {
+                       get {
+                               return GlobalRootNamespace.GlobalRoot;
+                       }
+               }
+
+               public RootNamespace (Assembly assembly) : base (null, String.Empty)
+               {
+                       this.referenced_assembly = assembly;
+                       this.cached_namespaces = new Hashtable ();
+                       this.cached_namespaces.Add ("", null);
+
+                       if (this.referenced_assembly != null)
+                               ComputeNamespacesForAssembly (this.referenced_assembly);
+               }
+
+               public virtual Type LookupTypeReflection (string name, Location loc)
+               {
+                       return GetTypeInAssembly (referenced_assembly, name);
+               }
+
+               public virtual void RegisterNamespace (Namespace ns)
+               {
+                       // Do nothing.
+               }
+               
+               protected void ComputeNamespacesForAssembly (Assembly assembly)
+               {
+                       if (get_namespaces_method != null) {
+                               string [] namespaces = (string []) get_namespaces_method.Invoke (assembly, null);
+                               foreach (string ns in namespaces) {
+                                       if (ns.Length == 0)
+                                               continue;
+
+                                       // Method from parent class Namespace
+                                       GetNamespace (ns, true);
+                               }
+                       } else {
+                               //cached_namespaces.Add ("", null);
+                               foreach (Type t in assembly.GetExportedTypes ()) {
+                                       string ns = t.Namespace;
+                                       if (ns == null || cached_namespaces.Contains (ns))
+                                               continue;
+
+                                       // Method from parent class Namespace
+                                       GetNamespace (ns, true);
+                                       cached_namespaces.Add (ns, null);
+                               }
+                       }
+               }
+               
+               protected Type GetTypeInAssembly (Assembly assembly, string name)
+               {
+                       Type t = assembly.GetType (name);
+                       if (t == null)
+                               return null;
+
+                       if (t.IsPointer)
+                               throw new InternalErrorException ("Use GetPointerType() to get a pointer");
+                       
+                       TypeAttributes ta = t.Attributes & TypeAttributes.VisibilityMask;
+                       if (ta != TypeAttributes.NotPublic && ta != TypeAttributes.NestedPrivate &&
+                                       ta != TypeAttributes.NestedAssembly && ta != TypeAttributes.NestedFamANDAssem)
+                               return t;
+
+                       return null;
+               }
+
+               protected Hashtable CachedNamespaces {
+                       get {
+                               return cached_namespaces;
+                       }
+               }
+
+       }
+
+       public class GlobalRootNamespace : RootNamespace
+       {
+               static ArrayList all_namespaces;
+               static Hashtable namespaces_map;
+               static Hashtable root_namespaces;
+               internal static GlobalRootNamespace GlobalRoot;
+               
+               Assembly [] assemblies;
+               Module [] modules;
+               
+               public static void Reset ()
+               {
+                       all_namespaces = new ArrayList ();
+                       namespaces_map = new Hashtable ();
+                       root_namespaces = new Hashtable ();
+                       GlobalRoot = new GlobalRootNamespace ();
+               }
+               
+               static GlobalRootNamespace ()
+               {
+                       Reset ();
+               }
+
+               public GlobalRootNamespace () : base (null)
+               {
+                       assemblies = new Assembly [0];
+                       modules = new Module [0];
+               }
+
+               public void AddAssemblyReference (Assembly assembly)
+               {
+                       Assembly [] tmp = new Assembly [assemblies.Length + 1];
+                       Array.Copy (assemblies, 0, tmp, 0, assemblies.Length);
+                       tmp [assemblies.Length] = assembly;
+
+                       assemblies = tmp;
+                       ComputeNamespacesForAssembly (assembly);
+               }
+
+               public void AddModuleReference (Module module)
+               {
+                       Module [] tmp = new Module [modules.Length + 1];
+                       Array.Copy (modules, 0, tmp, 0, modules.Length);
+                       tmp [modules.Length] = module;
+
+                       modules = tmp;
+                       
+                       if (module != CodeGen.Module.Builder)
+                               ComputeNamespacesForModule (module);
+               }
+
+               void ComputeNamespacesForModule (Module module)
+               {
+                       foreach (Type t in module.GetTypes ()) {
+                               string ns = t.Namespace;
+                               if (ns == null || CachedNamespaces.Contains (ns))
+                                       continue;
+
+                               GetNamespace (ns, true);
+                               CachedNamespaces.Add (ns, null);
+                       }
+               }
+
+               public override Type LookupTypeReflection (string name, Location loc)
+               {
+                       Type found_type = null;
+               
+                       foreach (Assembly a in assemblies) {
+                               Type t = GetTypeInAssembly (a, name);
+                               if (t == null)
+                                       continue;
+                                       
+                               if (found_type == null) {
+                                       found_type = t;
+                                       continue;
+                               }
+
+                               Report.SymbolRelatedToPreviousError (found_type);
+                               Report.SymbolRelatedToPreviousError (t);
+                               Report.Error (433, loc, "The imported type `{0}' is defined multiple times", name);
+                                       
+                               return found_type;
+                       }
+
+                       foreach (Module module in modules) {
+                               Type t = module.GetType (name);
+                               if (t == null)
+                                       continue;
+
+                               if (found_type == null) {
+                                       found_type = t;
+                                       continue;
+                               }
+                                       
+                               Report.SymbolRelatedToPreviousError (t);
+                               Report.SymbolRelatedToPreviousError (found_type);
+                               Report.Warning (436, 2, loc, "Ignoring imported type `{0}' since the current assembly already has a declaration with the same name",
+                                                       TypeManager.CSharpName (t));
+                               return t;
+                       }
+
+                       return found_type;
+               }
+
+               public override void RegisterNamespace (Namespace child)
+               {
+                       all_namespaces.Add (child);
+                       if (namespaces_map.Contains (child.Name))
+                               return;
+                       namespaces_map [child.Name] = true;
+               }
+               
+               public static RootNamespace DefineRootNamespace (string name, Assembly assembly)
+               {
+                       RootNamespace retval = (RootNamespace) root_namespaces [name];
+                       if (retval != null)
+                               return retval;
+
+                       retval = new RootNamespace (assembly);
+                       return retval;
+               }
+               
+               public static bool IsNamespace (string name)
+               {
+                       return namespaces_map [name] != null;
+               }
+
+               public static ArrayList UserDefinedNamespaces {
+                       get { return all_namespaces; }
+               }
+
+               public static void VerifyUsingForAll ()
+               {
+                       foreach (Namespace ns in all_namespaces)
+                               ns.VerifyUsing ();
+               }
+               
+               public static void DefineNamespacesForAll (SymbolWriter symwriter)
+               {
+                       foreach (Namespace ns in all_namespaces)
+                               ns.DefineNamespaces (symwriter);
+               }
+
+               public override string ToString ()
+               {
+                       return "Namespace (<root>)";
+               }
+
+               public override string GetSignatureForError ()
+               {
+                       return "global::";
+               }
+
+       }
+
        /// <summary>
        ///   Keeps track of the namespaces defined in the C# code.
        ///
@@ -19,8 +266,6 @@ namespace Mono.CSharp {
        ///   compiler parse/intermediate tree during name resolution.
        /// </summary>
        public class Namespace : FullNamedExpression {
-               static ArrayList all_namespaces;
-               static Hashtable namespaces_map;
                
                Namespace parent;
                string fullname;
@@ -28,24 +273,10 @@ namespace Mono.CSharp {
                Hashtable namespaces;
                IDictionary declspaces;
                Hashtable cached_types;
+               RootNamespace root;
 
                public readonly MemberName MemberName;
 
-               public static Namespace Root;
-
-               static Namespace ()
-               {
-                       Reset ();
-               }
-
-               public static void Reset ()
-               {
-                       all_namespaces = new ArrayList ();
-                       namespaces_map = new Hashtable ();
-
-                       Root = new Namespace (null, "");
-               }
-
                /// <summary>
                ///   Constructor Takes the current namespace and the
                ///   name.  This is bootstrapped with parent == null
@@ -60,6 +291,14 @@ namespace Mono.CSharp {
 
                        this.parent = parent;
 
+                       if (parent != null)
+                               this.root = parent.root;
+                       else
+                               this.root = this as RootNamespace;
+
+                       if (this.root == null)
+                               throw new InternalErrorException ("Root namespaces must be created using RootNamespace");
+                       
                        string pname = parent != null ? parent.Name : "";
                                
                        if (pname == "")
@@ -82,10 +321,7 @@ namespace Mono.CSharp {
                        namespaces = new Hashtable ();
                        cached_types = new Hashtable ();
 
-                       all_namespaces.Add (this);
-                       if (namespaces_map.Contains (fullname))
-                               return;
-                       namespaces_map [fullname] = true;
+                       root.RegisterNamespace (this);
                }
 
                public override Expression DoResolve (EmitContext ec)
@@ -98,14 +334,9 @@ namespace Mono.CSharp {
                        throw new InternalErrorException ("Expression tree referenced namespace " + fullname + " during Emit ()");
                }
 
-               public static bool IsNamespace (string name)
-               {
-                       return namespaces_map [name] != null;
-               }
-
                public override string GetSignatureForError ()
                {
-                       return Name.Length == 0 ? "::global" : Name;
+                       return Name;
                }
                
                public Namespace GetNamespace (string name, bool create)
@@ -134,11 +365,6 @@ namespace Mono.CSharp {
                        return ns;
                }
 
-               public static Namespace LookupNamespace (string name, bool create)
-               {
-                       return Root.GetNamespace (name, create);
-               }
-
                TypeExpr LookupType (string name, Location loc)
                {
                        if (cached_types.Contains (name))
@@ -162,7 +388,7 @@ namespace Mono.CSharp {
                                }
                        }
                        string lookup = t != null ? t.FullName : (fullname == "" ? name : fullname + "." + name);
-                       Type rt = TypeManager.LookupTypeReflection (lookup, loc);
+                       Type rt = root.LookupTypeReflection (lookup, loc);
                        if (t == null)
                                t = rt;
 
@@ -196,8 +422,20 @@ namespace Mono.CSharp {
                        declspaces.Add (name, ds);
                }
 
-               static public ArrayList UserDefinedNamespaces {
-                       get { return all_namespaces; }
+               /// <summary>
+               ///   Used to validate that all the using clauses are correct
+               ///   after we are finished parsing all the files.  
+               /// </summary>
+               public void VerifyUsing ()
+               {
+                       foreach (NamespaceEntry entry in entries)
+                               entry.VerifyUsing ();
+               }
+
+               public void DefineNamespaces (SymbolWriter symwriter)
+               {
+                       foreach (NamespaceEntry entry in entries)
+                               entry.DefineNamespace (symwriter);
                }
 
                /// <summary>
@@ -219,32 +457,9 @@ namespace Mono.CSharp {
                        get { return parent; }
                }
 
-               public static void DefineNamespaces (SymbolWriter symwriter)
-               {
-                       foreach (Namespace ns in all_namespaces) {
-                               foreach (NamespaceEntry entry in ns.entries)
-                                       entry.DefineNamespace (symwriter);
-                       }
-               }
-
-               /// <summary>
-               ///   Used to validate that all the using clauses are correct
-               ///   after we are finished parsing all the files.  
-               /// </summary>
-               public static void VerifyUsing ()
-               {
-                       foreach (Namespace ns in all_namespaces) {
-                               foreach (NamespaceEntry entry in ns.entries)
-                                       entry.VerifyUsing ();
-                       }
-               }
-
                public override string ToString ()
                {
-                       if (this == Root)
-                               return "Namespace (<root>)";
-                       else
-                               return String.Format ("Namespace ({0})", Name);
+                       return String.Format ("Namespace ({0})", Name);
                }
        }
 
@@ -257,6 +472,7 @@ namespace Mono.CSharp {
                Hashtable aliases;
                ArrayList using_clauses;
                public bool DeclarationFound = false;
+               public bool UsingFound = false;
 
                //
                // This class holds the location where a using definition is
@@ -305,23 +521,34 @@ namespace Mono.CSharp {
                        }
                }
 
-               public class AliasEntry {
+               public abstract class AliasEntry {
                        public readonly string Name;
-                       public readonly Expression Alias;
                        public readonly NamespaceEntry NamespaceEntry;
                        public readonly Location Location;
                        
-                       public AliasEntry (NamespaceEntry entry, string name, MemberName alias, Location loc)
+                       protected AliasEntry (NamespaceEntry entry, string name, Location loc)
                        {
                                Name = name;
-                               Alias = alias.GetTypeExpression ();
                                NamespaceEntry = entry;
                                Location = loc;
                        }
+                       
+                       protected FullNamedExpression resolved;
 
-                       FullNamedExpression resolved;
+                       public abstract FullNamedExpression Resolve ();
+               }
+
+               public class LocalAliasEntry : AliasEntry
+               {
+                       public readonly Expression Alias;
+                       
+                       public LocalAliasEntry (NamespaceEntry entry, string name, MemberName alias, Location loc) :
+                               base (entry, name, loc)
+                       {
+                               Alias = alias.GetTypeExpression ();
+                       }
 
-                       public FullNamedExpression Resolve ()
+                       public override FullNamedExpression Resolve ()
                        {
                                if (resolved != null)
                                        return resolved;
@@ -335,6 +562,28 @@ namespace Mono.CSharp {
                        }
                }
 
+               public class ExternAliasEntry : AliasEntry 
+               {
+                       public ExternAliasEntry (NamespaceEntry entry, string name, Location loc) :
+                               base (entry, name, loc)
+                       {
+                       }
+
+                       public override FullNamedExpression Resolve ()
+                       {
+                               if (resolved != null)
+                                       return resolved;
+
+                               resolved = TypeManager.ComputeNamespacesForAlias (Name);
+                               if (resolved == null) {
+                                       Report.Error (430, Location, "The extern alias '" + Name +
+                                                                       "' was not specified in a /reference option");
+                               }
+                               
+                               return resolved;
+                       }
+               }
+
                public NamespaceEntry (NamespaceEntry parent, SourceFile file, string name, Location loc)
                {
                        this.parent = parent;
@@ -345,9 +594,10 @@ namespace Mono.CSharp {
                        if (parent != null)
                                ns = parent.NS.GetNamespace (name, true);
                        else if (name != null)
-                               ns = Namespace.LookupNamespace (name, true);
+                               ns = RootNamespace.Global.GetNamespace (name, true);
                        else
-                               ns = Namespace.Root;
+                               ns = RootNamespace.Global;
+                       
                        ns.AddNamespaceEntry (this);
                }
 
@@ -457,7 +707,33 @@ namespace Mono.CSharp {
                                Report.Warning (440, loc, "An alias named `global' will not be used when resolving 'global::';" +
                                        " the global namespace will be used instead");
 
-                       aliases [name] = new AliasEntry (Doppelganger, name, alias, loc);
+                       aliases [name] = new LocalAliasEntry (Doppelganger, name, alias, loc);
+               }
+
+               public void UsingExternalAlias (string name, Location loc)
+               {
+                       if (UsingFound || DeclarationFound) {
+                               Report.Error (439, loc, "An extern alias declaration must precede all other elements");
+                               return;
+                       }
+                       
+                       if (aliases == null)
+                               aliases = new Hashtable ();
+                       
+                       if (aliases.Contains (name)) {
+                               AliasEntry ae = (AliasEntry) aliases [name];
+                               Report.SymbolRelatedToPreviousError (ae.Location, ae.Name);
+                               Report.Error (1537, loc, "The using alias `" + name +
+                                             "' appeared previously in this namespace");
+                               return;
+                       }
+
+                       if (name == "global") {
+                               Report.Error (1681, loc, "You cannot redefine the global extern alias");
+                               return;
+                       }
+
+                       aliases [name] = new ExternAliasEntry (Doppelganger, name, loc);
                }
 
                public FullNamedExpression LookupNamespaceOrType (DeclSpace ds, string name, Location loc, bool ignore_cs0104)
@@ -642,25 +918,22 @@ namespace Mono.CSharp {
                                foreach (DictionaryEntry de in aliases) {
                                        AliasEntry alias = (AliasEntry) de.Value;
                                        if (alias.Resolve () == null)
-                                               Error_NamespaceNotFound (alias.Location, alias.Alias.ToString ());
+                                               if (alias is LocalAliasEntry) {
+                                                       LocalAliasEntry local = alias as LocalAliasEntry;
+                                                       Error_NamespaceNotFound (local.Location, local.Alias.ToString ());
+                                               }
                                }
                        }
                }
 
                public string GetSignatureForError ()
                {
-                       if (NS == Namespace.Root)
-                               return "::global";
-                       else
-                               return ns.Name;
+                       return ns.GetSignatureForError ();
                }
 
                public override string ToString ()
                {
-                       if (NS == Namespace.Root)
-                               return "NamespaceEntry (<root>)";
-                       else
-                               return String.Format ("NamespaceEntry ({0},{1},{2})", ns.Name, IsImplicit, ID);
+                       return ns.ToString ();
                }
        }
 }
index 529716d76f90003c8ee62dd7563d0565c41815b2..0a7a99e1b892915333cd93089087c245290287f4 100644 (file)
@@ -51,7 +51,7 @@ namespace Mono.CSharp {
                                typeof (GetGuidFunc), mi);
 
                        Location.DefineSymbolDocuments (this);
-                       Namespace.DefineNamespaces (this);
+                       GlobalRootNamespace.DefineNamespacesForAll (this);
 
                        return true;
                }
index 8b714f83fedc9757201af887bbcf9442a451c134..19b0ad1b2dcbed9d2b6c23a0e4f56a03651b20c1 100644 (file)
@@ -212,6 +212,8 @@ public partial class TypeManager {
        // </remarks>
        static Assembly [] assemblies;
 
+       static Hashtable external_aliases;
+
        // <remarks>
        //  Keeps a list of modules. We used this to do lookups
        //  on the module using GetType -- needed for arrays
@@ -275,6 +277,7 @@ public partial class TypeManager {
                // Lets get everything clean so that we can collect before generating code
                assemblies = null;
                modules = null;
+               external_aliases = null;
                builder_to_declspace = null;
                builder_to_member_cache = null;
                builder_to_ifaces = null;
@@ -378,6 +381,7 @@ public partial class TypeManager {
                assemblies = new Assembly [0];
                modules = null;
                
+               external_aliases = new Hashtable ();
                builder_to_declspace = new PtrHashtable ();
                builder_to_member_cache = new PtrHashtable ();
                builder_to_method = new PtrHashtable ();
@@ -512,11 +516,22 @@ public partial class TypeManager {
                assemblies = n;
        }
 
+       public static void AddExternAlias (string alias, Assembly a)
+       {
+               // Keep the new as the chosen one
+               external_aliases [alias] = a;
+       }
+
         public static Assembly [] GetAssemblies ()
         {
                 return assemblies;
         }
 
+       public static Assembly GetExternAlias (string alias)
+       {
+               return (Assembly) external_aliases [alias];
+       }
+
        /// <summary>
        ///  Registers a module builder to lookup types from
        /// </summary>
@@ -629,110 +644,26 @@ public partial class TypeManager {
                return (Type) ret;
        }
 
-       public static Type LookupTypeReflection (string name, Location loc)
-       {
-               Type found_type = null;
-
-               foreach (Assembly a in assemblies) {
-                       Type t = a.GetType (name);
-                       if (t == null)
-                               continue;
-
-                       if (t.IsPointer)
-                               throw new InternalErrorException ("Use GetPointerType() to get a pointer");
-
-                       TypeAttributes ta = t.Attributes & TypeAttributes.VisibilityMask;
-                       if (ta != TypeAttributes.NotPublic && ta != TypeAttributes.NestedPrivate &&
-                               ta != TypeAttributes.NestedAssembly && ta != TypeAttributes.NestedFamANDAssem) {
-                               if (found_type == null) {
-                                       found_type = t;
-                                       continue;
-                               }
-
-                               Report.SymbolRelatedToPreviousError (found_type);
-                               Report.SymbolRelatedToPreviousError (t);
-                               Report.Error (433, loc, "The imported type `{0}' is defined multiple times", name);
-                               return found_type;
-                       }
-               }
-
-               foreach (Module mb in modules) {
-                       Type t = mb.GetType (name);
-                       if (t == null)
-                               continue;
-                       
-                       if (found_type == null) {
-                               found_type = t;
-                               continue;
-                       }
-
-                       Report.SymbolRelatedToPreviousError (t);
-                       Report.SymbolRelatedToPreviousError (found_type);
-                       Report.Warning (436, 2, loc, "Ignoring imported type `{0}' since the current assembly already has a declaration with the same name",
-                               TypeManager.CSharpName (t));
-                       return t;
-               }
-
-               return found_type;
-       }
-
        /// <summary>
        ///   Computes the namespaces that we import from the assemblies we reference.
        /// </summary>
        public static void ComputeNamespaces ()
        {
-               MethodInfo assembly_get_namespaces = typeof (Assembly).GetMethod ("GetNamespaces", BindingFlags.Instance|BindingFlags.NonPublic);
-
-               Hashtable cache = null;
-
-               //
-               // First add the assembly namespaces
-               //
-               if (assembly_get_namespaces != null){
-                       int count = assemblies.Length;
-
-                       for (int i = 0; i < count; i++){
-                               Assembly a = assemblies [i];
-                               string [] namespaces = (string []) assembly_get_namespaces.Invoke (a, null);
-                               foreach (string ns in namespaces){
-                                       if (ns.Length == 0)
-                                               continue;
-                                       Namespace.LookupNamespace (ns, true);
-                               }
-                       }
-               } else {
-                       cache = new Hashtable ();
-                       cache.Add ("", null);
-                       foreach (Assembly a in assemblies) {
-                               foreach (Type t in a.GetExportedTypes ()) {
-                                       string ns = t.Namespace;
-                                       if (ns == null || cache.Contains (ns))
-                                               continue;
+               foreach (Assembly assembly in assemblies)
+                       RootNamespace.Global.AddAssemblyReference (assembly);
+               
+               foreach (Module m in modules)
+                       RootNamespace.Global.AddModuleReference (m);
 
-                                       Namespace.LookupNamespace (ns, true);
-                                       cache.Add (ns, null);
-                               }
-                       }
-               }
+       }
 
-               //
-               // Then add module namespaces
-               //
-               foreach (Module m in modules) {
-                       if (m == CodeGen.Module.Builder)
-                               continue;
-                       if (cache == null) {
-                               cache = new Hashtable ();
-                               cache.Add ("", null);
-                       }
-                       foreach (Type t in m.GetTypes ()) {
-                               string ns = t.Namespace;
-                               if (ns == null || cache.Contains (ns))
-                                       continue;
-                               Namespace.LookupNamespace (ns, true);
-                               cache.Add (ns, null);
-                       }
-               }
+       public static Namespace ComputeNamespacesForAlias (string name)
+       {
+               Assembly assembly = (Assembly) external_aliases [name];
+               if (assembly == null)
+                       return null;
+               
+               return GlobalRootNamespace.DefineRootNamespace (name, assembly);
        }
 
        /// <summary>
@@ -751,7 +682,7 @@ public partial class TypeManager {
 
        public static bool NamespaceClash (string name, Location loc)
        {
-               if (Namespace.LookupNamespace (name, false) == null)
+               if (RootNamespace.Global.GetNamespace (name, false) == null)
                        return false;
 
                Report.Error (519, loc, String.Format ("`{0}' clashes with a predefined namespace", name));
@@ -943,7 +874,7 @@ public partial class TypeManager {
        /// </summary>
        static Type CoreLookupType (string ns_name, string name)
        {
-               Namespace ns = Namespace.LookupNamespace (ns_name, true);
+               Namespace ns = RootNamespace.Global.GetNamespace (ns_name, true);
                FullNamedExpression fne = ns.Lookup (RootContext.Tree.Types, name, Location.Null);
                Type t = fne == null ? null : fne.Type;
                if (t == null)
index 4e703802bc1faffebe2cdec8025f10258db88398..a9c4ccf628cf914f644747cbbf17a0e6e796abe9 100644 (file)
@@ -4,23 +4,10 @@
 # csXXXX.cs            : test case causes error
 # csXXXX.cs IGNORE     : adds test to ignore list
 
-gtest-187.cs IGNORE
-test-442.cs IGNORE     # Causes runtime to crash
-
+gtest-214.cs
+test-442.cs IGNORE             # Causes runtime to crash
+test-464.cs
 test-50.cs IGNORE      # Windows-only test
 test-67.cs IGNORE      # Windows-only test
 test-anon-27.cs
 test-xml-027.cs
-
-gtest-214.cs
-test-270.cs IGNORE
-
-test-externalias-01.cs IGNORE
-test-externalias-02.cs IGNORE
-test-externalias-03.cs IGNORE
-test-externalias-04.cs IGNORE
-test-externalias-05.cs IGNORE
-test-externalias-06.cs IGNORE
-test-externalias-07.cs IGNORE
-test-externalias-08.cs IGNORE
-test-464.cs
\ No newline at end of file
index 573d961f6d2f6183adbf19d6bbbe2bb8096b2b50..81a2c5b51d3e217bb7759703b4cce381fefbe9bc 100644 (file)
@@ -9,4 +9,4 @@ test-67.cs IGNORE       # Windows-only test
 
 test-anon-27.cs
 test-xml-027.cs
-test-270.cs IGNORE
+test-464.cs