2006-07-16 Marek Safar <marek.safar@seznam.cz>
[mono.git] / mcs / gmcs / driver.cs
index 5b341b3e7af1dbe3ad7c3d2f0c618c2924f83541..4c2f0387f8c78bf4c4439815859d4e9ee146b526 100644 (file)
@@ -15,11 +15,11 @@ namespace Mono.CSharp
        using System.Reflection;
        using System.Reflection.Emit;
        using System.Collections;
-       using System.Diagnostics;
+       using System.Collections.Specialized;
        using System.IO;
        using System.Text;
        using System.Globalization;
-       using System.Xml;
+       using System.Diagnostics;
 
        public enum Target {
                Library, Exe, Module, WinExe
@@ -43,6 +43,11 @@ namespace Mono.CSharp
                //
                static ArrayList soft_references;
 
+               // 
+               // External aliases for assemblies.
+               //
+               static Hashtable external_aliases;
+
                //
                // Modules to be linked
                //
@@ -71,8 +76,7 @@ namespace Mono.CSharp
                //
                // A list of resource files
                //
-               static ArrayList resources;
-               static ArrayList embedded_resources;
+               static Resources embedded_resources;
                static string win32ResourceFile;
                static string win32IconFile;
                
@@ -94,7 +98,6 @@ namespace Mono.CSharp
                //
                // Encoding.
                //
-               static Encoding defaultEncoding;
                static Encoding encoding;
 
                static public void Reset ()
@@ -105,11 +108,11 @@ namespace Mono.CSharp
                        pause = false;
                        show_counters = false;
                        load_default_config = true;
-                       resources = embedded_resources = null;
+                       embedded_resources = null;
                        win32ResourceFile = win32IconFile = null;
                        defines = null;
                        output_file = null;
-                       encoding = defaultEncoding = null;
+                       encoding = null;
                        first_source = null;
                }
 
@@ -193,7 +196,6 @@ namespace Mono.CSharp
                        reader.Position = 0;
                        parser = new CSharpParser (reader, file, defines);
                        parser.ErrorOutput = Report.Stderr;
-#if FIXME
                        try {
                                parser.parse ();
                        } catch (Exception ex) {
@@ -201,13 +203,6 @@ namespace Mono.CSharp
                        } finally {
                                input.Close ();
                        }
-#else
-                       try {
-                               parser.parse ();
-                       } finally {
-                               input.Close ();
-                       }
-#endif
                }
                
                static void OtherFlags ()
@@ -287,9 +282,11 @@ namespace Mono.CSharp
 
                public static int counter1, counter2;
                
-       public static int Main (string[] args)
+               public static int Main (string[] args)
                {
                        RootContext.Version = LanguageVersion.Default;
+                       Location.InEmacs = Environment.GetEnvironmentVariable ("EMACS") == "t";
+
                        bool ok = MainDriver (args);
                        
                        if (ok && Report.Errors == 0) {
@@ -311,6 +308,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 = "";
@@ -326,7 +328,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)
+                                       RootNamespace.Global.AddAssemblyReference (a);
+                               else
+                                       RootNamespace.DefineRootNamespace (alias, a);
 
                        } catch (FileNotFoundException){
                                foreach (string dir in link_paths){
@@ -336,7 +342,10 @@ namespace Mono.CSharp
 
                                        try {
                                                a = Assembly.LoadFrom (full_path);
-                                               TypeManager.AddAssembly (a);
+                                               if (alias == null)
+                                                       RootNamespace.Global.AddAssemblyReference (a);
+                                               else
+                                                       RootNamespace.DefineRootNamespace (alias, a);
                                                return;
                                        } catch (FileNotFoundException ff) {
                                                total_log += ff.FusionLog;
@@ -368,7 +377,7 @@ namespace Mono.CSharp
                                catch (TargetInvocationException ex) {
                                        throw ex.InnerException;
                                }
-                               TypeManager.AddModule (m);
+                               RootNamespace.Global.AddModuleReference (m);
 
                        } 
                        catch (FileNotFoundException){
@@ -384,7 +393,7 @@ namespace Mono.CSharp
                                                catch (TargetInvocationException ex) {
                                                        throw ex.InnerException;
                                                }
-                                               TypeManager.AddModule (m);
+                                               RootNamespace.Global.AddModuleReference (m);
                                                return;
                                        } catch (FileNotFoundException ff) {
                                                total_log += ff.FusionLog;
@@ -412,6 +421,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;
                }
@@ -672,7 +684,7 @@ namespace Mono.CSharp
                                return true;
                                
                        case "--main": case "-m":
-                               Report.Warning (-29, "Compatibility: Use -main:CLASS instead of --main CLASS or -m CLASS");
+                               Report.Warning (-29, 1, "Compatibility: Use -main:CLASS instead of --main CLASS or -m CLASS");
                                if ((i + 1) >= args.Length){
                                        Usage ();
                                        Environment.Exit (1);
@@ -681,7 +693,7 @@ namespace Mono.CSharp
                                return true;
                                
                        case "--unsafe":
-                               Report.Warning (-29, "Compatibility: Use -unsafe instead of --unsafe");
+                               Report.Warning (-29, 1, "Compatibility: Use -unsafe instead of --unsafe");
                                RootContext.Unsafe = true;
                                return true;
                                
@@ -692,7 +704,7 @@ namespace Mono.CSharp
                                return true;
                                
                        case "--define":
-                               Report.Warning (-29, "Compatibility: Use -d:SYMBOL instead of --define SYMBOL");
+                               Report.Warning (-29, 1, "Compatibility: Use -d:SYMBOL instead of --define SYMBOL");
                                if ((i + 1) >= args.Length){
                                        Usage ();
                                        Environment.Exit (1);
@@ -723,7 +735,7 @@ namespace Mono.CSharp
                                
                        case "-o": 
                        case "--output":
-                               Report.Warning (-29, "Compatibility: Use -out:FILE instead of --output FILE or -o FILE");
+                               Report.Warning (-29, 1, "Compatibility: Use -out:FILE instead of --output FILE or -o FILE");
                                if ((i + 1) >= args.Length){
                                        Usage ();
                                        Environment.Exit (1);
@@ -732,7 +744,7 @@ namespace Mono.CSharp
                                return true;
 
                        case "--checked":
-                               Report.Warning (-29, "Compatibility: Use -checked instead of --checked");
+                               Report.Warning (-29, 1, "Compatibility: Use -checked instead of --checked");
                                RootContext.Checked = true;
                                return true;
                                
@@ -742,34 +754,34 @@ namespace Mono.CSharp
                                
                        case "--linkresource":
                        case "--linkres":
-                               Report.Warning (-29, "Compatibility: Use -linkres:VALUE instead of --linkres VALUE");
+                               Report.Warning (-29, 1, "Compatibility: Use -linkres:VALUE instead of --linkres VALUE");
                                if ((i + 1) >= args.Length){
                                        Usage ();
                                        Report.Error (5, "Missing argument to --linkres"); 
                                        Environment.Exit (1);
                                }
-                               if (resources == null)
-                                       resources = new ArrayList ();
+                               if (embedded_resources == null)
+                                       embedded_resources = new Resources ();
                                
-                               resources.Add (args [++i]);
+                               embedded_resources.Add (false, args [++i], args [i]);
                                return true;
                                
                        case "--resource":
                        case "--res":
-                               Report.Warning (-29, "Compatibility: Use -res:VALUE instead of --res VALUE");
+                               Report.Warning (-29, 1, "Compatibility: Use -res:VALUE instead of --res VALUE");
                                if ((i + 1) >= args.Length){
                                        Usage ();
                                        Report.Error (5, "Missing argument to --resource"); 
                                        Environment.Exit (1);
                                }
                                if (embedded_resources == null)
-                                       embedded_resources = new ArrayList ();
+                                       embedded_resources = new Resources ();
                                
-                               embedded_resources.Add (args [++i]);
+                               embedded_resources.Add (true, args [++i], args [i]);
                                return true;
                                
                        case "--target":
-                               Report.Warning (-29, "Compatibility: Use -target:KIND instead of --target KIND");
+                               Report.Warning (-29, 1, "Compatibility: Use -target:KIND instead of --target KIND");
                                if ((i + 1) >= args.Length){
                                        Environment.Exit (1);
                                        return true;
@@ -801,17 +813,26 @@ namespace Mono.CSharp
                                return true;
                                
                        case "-r":
-                               Report.Warning (-29, "Compatibility: Use -r:LIBRARY instead of -r library");
+                               Report.Warning (-29, 1, "Compatibility: Use -r:LIBRARY instead of -r library");
                                if ((i + 1) >= args.Length){
                                        Usage ();
                                        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":
-                               Report.Warning (-29, "Compatibility: Use -lib:ARG instead of --L arg");
+                               Report.Warning (-29, 1, "Compatibility: Use -lib:ARG instead of --L arg");
                                if ((i + 1) >= args.Length){
                                        Usage ();       
                                        Environment.Exit (1);
@@ -820,7 +841,7 @@ namespace Mono.CSharp
                                return true;
                                
                        case "--nostdlib":
-                               Report.Warning (-29, "Compatibility: Use -nostdlib instead of --nostdlib");
+                               Report.Warning (-29, 1, "Compatibility: Use -nostdlib instead of --nostdlib");
                                RootContext.StdLib = false;
                                return true;
                                
@@ -829,12 +850,16 @@ namespace Mono.CSharp
                                return true;
                                
                        case "--werror":
-                               Report.Warning (-29, "Compatibility: Use -warnaserror: option instead of --werror");
+                               Report.Warning (-29, 1, "Compatibility: Use -warnaserror: option instead of --werror");
                                Report.WarningsAreErrors = true;
                                return true;
+
+                       case "--broken-cycles":
+                               RootContext.BrokenCircularDeps = true;
+                               return true;
                                
                        case "--nowarn":
-                               Report.Warning (-29, "Compatibility: Use -nowarn instead of --nowarn");
+                               Report.Warning (-29, 1, "Compatibility: Use -nowarn instead of --nowarn");
                                if ((i + 1) >= args.Length){
                                        Usage ();
                                        Environment.Exit (1);
@@ -851,7 +876,7 @@ namespace Mono.CSharp
                                return true;
                                
                        case "--wlevel":
-                               Report.Warning (-29, "Compatibility: Use -warn:LEVEL instead of --wlevel LEVEL");
+                               Report.Warning (-29, 1, "Compatibility: Use -warn:LEVEL instead of --wlevel LEVEL");
                                if ((i + 1) >= args.Length){
                                        Report.Error (
                                                1900,
@@ -881,7 +906,7 @@ namespace Mono.CSharp
                                return true;
                                
                        case "--recurse":
-                               Report.Warning (-29, "Compatibility: Use -recurse:PATTERN option instead --recurse PATTERN");
+                               Report.Warning (-29, 1, "Compatibility: Use -recurse:PATTERN option instead --recurse PATTERN");
                                if ((i + 1) >= args.Length){
                                        Report.Error (5, "--recurse requires an argument");
                                        Environment.Exit (1);
@@ -899,12 +924,12 @@ namespace Mono.CSharp
                                return true;
                                
                        case "--debug": case "-g":
-                               Report.Warning (-29, "Compatibility: Use -debug option instead of -g or --debug");
+                               Report.Warning (-29, 1, "Compatibility: Use -debug option instead of -g or --debug");
                                want_debugging_support = true;
                                return true;
                                
                        case "--noconfig":
-                               Report.Warning (-29, "Compatibility: Use -noconfig option instead of --noconfig");
+                               Report.Warning (-29, 1, "Compatibility: Use -noconfig option instead of --noconfig");
                                load_default_config = false;
                                return true;
                        }
@@ -962,7 +987,7 @@ namespace Mono.CSharp
                                return true;
 
                        case "/out":
-                               if (value == ""){
+                               if (value.Length == 0){
                                        Usage ();
                                        Environment.Exit (1);
                                }
@@ -988,7 +1013,7 @@ namespace Mono.CSharp
                        case "/define": {
                                string [] defs;
 
-                               if (value == ""){
+                               if (value.Length == 0){
                                        Usage ();
                                        Environment.Exit (1);
                                }
@@ -1007,22 +1032,10 @@ namespace Mono.CSharp
                                Console.WriteLine ("To file bug reports, please visit: http://www.mono-project.com/Bugs");
                                return true;
 
-                       case "/linkres":
-                       case "/linkresource":
-                               if (value == ""){
-                                       Report.Error (5, arg + " requires an argument");
-                                       Environment.Exit (1);
-                               }
-                               if (resources == null)
-                                       resources = new ArrayList ();
-                               
-                               resources.Add (value);
-                               return true;
-                               
                        case "/pkg": {
                                string packages;
 
-                               if (value == ""){
+                               if (value.Length == 0){
                                        Usage ();
                                        Environment.Exit (1);
                                }
@@ -1042,7 +1055,7 @@ namespace Mono.CSharp
                                }
 
                                if (p.StandardOutput == null){
-                                       Report.Warning (-27, "Specified package did not return any information");
+                                       Report.Warning (-27, 1, "Specified package did not return any information");
                                        return true;
                                }
                                string pkgout = p.StandardOutput.ReadToEnd ();
@@ -1062,28 +1075,40 @@ namespace Mono.CSharp
                                return true;
                        }
                                
+                       case "/linkres":
+                       case "/linkresource":
                        case "/res":
                        case "/resource":
-                               if (value == ""){
-                                       Report.Error (5, "-resource requires an argument");
-                                       Environment.Exit (1);
-                               }
                                if (embedded_resources == null)
-                                       embedded_resources = new ArrayList ();
-                               
-                               if (embedded_resources.Contains (value)) {
-                                       Report.Error (1508, String.Format ("The resource identifier `{0}' has already been used in this assembly.", value));
-                               }
-                               else if (value.IndexOf (',') != -1 && embedded_resources.Contains (value.Split (',')[1])) {
-                                       Report.Error (1508, String.Format ("The resource identifier `{0}' has already been used in this assembly.", value));
-                               }
-                               else {
-                               embedded_resources.Add (value);
+                                       embedded_resources = new Resources ();
+
+                               bool embeded = arg.StartsWith ("/r");
+                               string[] s = value.Split (',');
+                               switch (s.Length) {
+                                       case 1:
+                                               if (s[0].Length == 0)
+                                                       goto default;
+                                               embedded_resources.Add (embeded, s [0], Path.GetFileName (s[0]));
+                                               break;
+                                       case 2:
+                                               embedded_resources.Add (embeded, s [0], s [1]);
+                                               break;
+                                       case 3:
+                                               if (s [2] != "public" && s [2] != "private") {
+                                                       Report.Error (1906, "Invalid resource visibility option `{0}'. Use either `public' or `private' instead", s [2]);
+                                                       return true;
+                                               }
+                                               embedded_resources.Add (embeded, s [0], s [1], s [2] == "private");
+                                               break;
+                                       default:
+                                               Report.Error (-2005, "Wrong number of arguments for option `{0}'", option);
+                                               break;
                                }
+
                                return true;
                                
                        case "/recurse":
-                               if (value == ""){
+                               if (value.Length == 0){
                                        Report.Error (5, "-recurse requires an argument");
                                        Environment.Exit (1);
                                }
@@ -1092,19 +1117,28 @@ namespace Mono.CSharp
 
                        case "/r":
                        case "/reference": {
-                               if (value == ""){
+                               if (value.Length == 0){
                                        Report.Error (5, "-reference requires an argument");
                                        Environment.Exit (1);
                                }
 
                                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;
                        }
                        case "/addmodule": {
-                               if (value == ""){
+                               if (value.Length == 0){
                                        Report.Error (5, arg + " requires an argument");
                                        Environment.Exit (1);
                                }
@@ -1116,7 +1150,7 @@ namespace Mono.CSharp
                                return true;
                        }
                        case "/win32res": {
-                               if (value == "") {
+                               if (value.Length == 0) {
                                        Report.Error (5, arg + " requires an argument");
                                        Environment.Exit (1);
                                }
@@ -1125,7 +1159,7 @@ namespace Mono.CSharp
                                return true;
                        }
                        case "/win32icon": {
-                               if (value == "") {
+                               if (value.Length == 0) {
                                        Report.Error (5, arg + " requires an argument");
                                        Environment.Exit (1);
                                }
@@ -1134,7 +1168,7 @@ namespace Mono.CSharp
                                return true;
                        }
                        case "/doc": {
-                               if (value == ""){
+                               if (value.Length == 0){
                                        Report.Error (2006, arg + " requires an argument");
                                        Environment.Exit (1);
                                }
@@ -1144,7 +1178,7 @@ namespace Mono.CSharp
                        case "/lib": {
                                string [] libdirs;
                                
-                               if (value == ""){
+                               if (value.Length == 0){
                                        Report.Error (5, "/lib requires an argument");
                                        Environment.Exit (1);
                                }
@@ -1206,7 +1240,7 @@ namespace Mono.CSharp
                        case "/nowarn": {
                                string [] warns;
 
-                               if (value == ""){
+                               if (value.Length == 0){
                                        Report.Error (5, "/nowarn requires an argument");
                                        Environment.Exit (1);
                                }
@@ -1248,7 +1282,7 @@ namespace Mono.CSharp
 
                        case "/main":
                        case "/m":
-                               if (value == ""){
+                               if (value.Length == 0){
                                        Report.Error (5, arg + " requires an argument");                                        
                                        Environment.Exit (1);
                                }
@@ -1313,7 +1347,7 @@ namespace Mono.CSharp
                                        encoding = new UTF8Encoding();
                                        break;
                                case "reset":
-                                       encoding = defaultEncoding;
+                                       encoding = Encoding.Default;
                                        break;
                                default:
                                        try {
@@ -1326,11 +1360,15 @@ namespace Mono.CSharp
                                }
                                return true;
                        }
-                       //Report.Error (2007, String.Format ("Unrecognized command-line option: `{0}'", option));
-                       //Environment.Exit (1);
+
                        return false;
                }
                
+               static void Error_WrongOption (string option)
+               {
+                       Report.Error (2007, "Unrecognized command-line option: `{0}'", option);
+               }
+
                static string [] AddArgs (string [] args, string [] extra_args)
                {
                        string [] new_args;
@@ -1354,6 +1392,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
@@ -1370,16 +1446,10 @@ namespace Mono.CSharp
                        int i;
                        bool parsing_options = true;
 
-                       try {
-                               // Latin1
-                               defaultEncoding = Encoding.GetEncoding (28591);
-                       } catch (Exception) {
-                               // iso-8859-1
-                               defaultEncoding = Encoding.GetEncoding (1252);
-                       }
-                       encoding = defaultEncoding;
+                       encoding = Encoding.Default;
 
                        references = new ArrayList ();
+                       external_aliases = new Hashtable ();
                        soft_references = new ArrayList ();
                        modules = new ArrayList ();
                        link_paths = new ArrayList ();
@@ -1397,7 +1467,7 @@ namespace Mono.CSharp
 
                        for (i = 0; i < args.Length; i++){
                                string arg = args [i];
-                               if (arg == "")
+                               if (arg.Length == 0)
                                        continue;
 
                                if (arg.StartsWith ("@")){
@@ -1441,10 +1511,19 @@ namespace Mono.CSharp
                                                string csc_opt = "/" + arg.Substring (1);
                                                if (CSCParseOption (csc_opt, ref args, ref i))
                                                        continue;
+
+                                               Error_WrongOption (arg);
+                                               return false;
                                        } else {
-                                               if (arg.StartsWith ("/")){
+                                               if (arg [0] == '/'){
                                                        if (CSCParseOption (arg, ref args, ref i))
                                                                continue;
+
+                                                       // Need to skip `/home/test.cs' however /test.cs is considered as error
+                                                       if (arg.Length < 2 || arg.IndexOf ('/', 2) == -1) {
+                                                               Error_WrongOption (arg);
+                                                               return false;
+                                                       }
                                                }
                                        }
                                }
@@ -1467,7 +1546,7 @@ namespace Mono.CSharp
                        //
                        // If we are an exe, require a source file for the entry point
                        //
-                       if (RootContext.Target == Target.Exe || RootContext.Target == Target.WinExe){
+                       if (RootContext.Target == Target.Exe || RootContext.Target == Target.WinExe || RootContext.Target == Target.Module){
                        if (first_source == null){
                                Report.Error (2008, "No files to compile were specified");
                                return false;
@@ -1478,7 +1557,7 @@ namespace Mono.CSharp
                        //
                        // If there is nothing to put in the assembly, and we are not a library
                        //
-                       if (first_source == null && embedded_resources == null && resources == null){
+                       if (first_source == null && embedded_resources == null){
                                        Report.Error (2008, "No files to compile were specified");
                                        return false;
                        }
@@ -1522,13 +1601,21 @@ namespace Mono.CSharp
                        // Quick hack
                        //
                        if (output_file == null){
+                               if (first_source == null){
+                                       Report.Error (1562, "If no source files are specified you must specify the output file with -out:");
+                                       return false;
+                               }
+                                       
                                int pos = first_source.LastIndexOf ('.');
 
                                if (pos > 0)
-                                       output_file = first_source.Substring (0, pos) + RootContext.TargetExt;
+                                       output_file = first_source.Substring (0, pos);
                                else
-                                       output_file = first_source + RootContext.TargetExt;
+                                       output_file = first_source;
                        }
+                       
+                       if (!Path.HasExtension (output_file))
+                               output_file += RootContext.TargetExt;
 
                        if (!CodeGen.Init (output_file, output_file, want_debugging_support))
                                return false;
@@ -1544,7 +1631,7 @@ namespace Mono.CSharp
                                set_method.Invoke (CodeGen.Assembly.Builder, BindingFlags.Default, null, new object[]{true}, null);
                        }
 
-                       TypeManager.AddModule (CodeGen.Module.Builder);
+                       RootNamespace.Global.AddModuleReference (CodeGen.Module.Builder);
 
                        if (modules.Count > 0) {
                                MethodInfo adder_method = typeof (AssemblyBuilder).GetMethod ("AddModule", BindingFlags.Instance|BindingFlags.NonPublic);
@@ -1556,8 +1643,6 @@ namespace Mono.CSharp
                                foreach (string module in modules)
                                        LoadModule (adder_method, module);
                        }
-
-                       TypeManager.ComputeNamespaces ();
                        
                        //
                        // Before emitting, we need to get the core
@@ -1597,7 +1682,8 @@ namespace Mono.CSharp
 
                        RootContext.DefineTypes ();
                        
-                       if (RootContext.Documentation != null &&
+                       if (Report.Errors == 0 &&
+                               RootContext.Documentation != null &&
                                !RootContext.Documentation.OutputDocComment (
                                        output_file))
                                return false;
@@ -1605,14 +1691,15 @@ namespace Mono.CSharp
                        //
                        // Verify using aliases now
                        //
-                       Namespace.VerifyUsing ();
+                       NamespaceEntry.VerifyAllUsing ();
                        
                        if (Report.Errors > 0){
                                return false;
                        }
+
+                       CodeGen.Assembly.Resolve ();
                        
                        if (RootContext.VerifyClsCompliance) {
-                               CodeGen.Assembly.ResolveClsCompliance ();
                                if (CodeGen.Assembly.IsClsCompliant) {
                                AttributeTester.VerifyModulesClsCompliance ();
                                TypeManager.LoadAllImportedTypes ();
@@ -1657,7 +1744,7 @@ namespace Mono.CSharp
 
                                if (ep == null) {
                                        if (RootContext.MainClass != null) {
-                                               DeclSpace main_cont = RootContext.Tree.GetDecl (MemberName.FromDotted (RootContext.MainClass, Location.Null));
+                                               DeclSpace main_cont = RootContext.Tree.Types.GetDefinition (RootContext.MainClass) as DeclSpace;
                                                if (main_cont == null) {
                                                        Report.Error (1555, "Could not find `{0}' specified for Main method", RootContext.MainClass); 
                                                        return false;
@@ -1683,56 +1770,13 @@ namespace Mono.CSharp
                                Report.Error (2017, "Cannot specify -main if building a module or library");
                        }
 
-                       //
-                       // Add the resources
-                       //
-                       if (resources != null){
-                               foreach (string spec in resources){
-                                       string file, res;
-                                       int cp;
-                                       
-                                       cp = spec.IndexOf (',');
-                                       if (cp != -1){
-                                               file = spec.Substring (0, cp);
-                                               res = spec.Substring (cp + 1);
-                                       } else
-                                               file = res = spec;
-
-                                       CodeGen.Assembly.Builder.AddResourceFile (res, file);
-                               }
-                       }
-                       
                        if (embedded_resources != null){
-                               object[] margs = new object [2];
-                               Type[] argst = new Type [2];
-                               argst [0] = argst [1] = typeof (string);
-
-                               MethodInfo embed_res = typeof (AssemblyBuilder).GetMethod (
-                                       "EmbedResourceFile", BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic,
-                                       null, CallingConventions.Any, argst, null);
-                               
-                               if (embed_res == null) {
-                                       Report.RuntimeMissingSupport (Location.Null, "Resource embedding");
-                               } else {
-                                       foreach (string spec in embedded_resources) {
-                                               int cp;
-
-                                               cp = spec.IndexOf (',');
-                                               if (cp != -1){
-                                                       margs [0] = spec.Substring (cp + 1);
-                                                       margs [1] = spec.Substring (0, cp);
-                                               } else {
-                                                       margs [1] = spec;
-                                                       margs [0] = Path.GetFileName (spec);
-                                               }
-
-                                               if (File.Exists ((string) margs [1]))
-                                                       embed_res.Invoke (CodeGen.Assembly.Builder, margs);
-                                               else {
-                                                       Report.Error (1566, "Can not find the resource " + margs [1]);
-                                               }
-                                       }
+                               if (RootContext.Target == Target.Module) {
+                                       Report.Error (1507, "Cannot link resource file when building a module");
+                                       return false;
                                }
+
+                               embedded_resources.Emit ();
                        }
 
                        //
@@ -1746,14 +1790,14 @@ namespace Mono.CSharp
                                        CodeGen.Assembly.Builder.DefineUnmanagedResource (win32ResourceFile);
                                }
                                catch (ArgumentException) {
-                                       Report.Warning (0, new Location (-1), "Cannot embed win32 resources on this runtime: try the Mono runtime instead.");
+                                       Report.RuntimeMissingSupport (Location.Null, "resource embeding");
                                }
                        }
 
                        if (win32IconFile != null) {
                                MethodInfo define_icon = typeof (AssemblyBuilder).GetMethod ("DefineIconResource", BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic);
                                if (define_icon == null) {
-                                       Report.Warning (0, new Location (-1), "Cannot embed icon resource on this runtime: try the Mono runtime instead.");
+                                       Report.RuntimeMissingSupport (Location.Null, "resource embeding");
                                }
                                define_icon.Invoke (CodeGen.Assembly.Builder, new object [] { win32IconFile });
                        }
@@ -1794,6 +1838,113 @@ namespace Mono.CSharp
                }
        }
 
+       class Resources
+       {
+               interface IResource
+               {
+                       void Emit ();
+                       string FileName { get; }
+               }
+
+               class EmbededResource : IResource
+               {
+                       static MethodInfo embed_res;
+
+                       static EmbededResource () {
+                               Type[] argst = new Type [] { 
+                                                                                          typeof (string), typeof (string), typeof (ResourceAttributes)
+                                                                                  };
+
+                               embed_res = typeof (AssemblyBuilder).GetMethod (
+                                       "EmbedResourceFile", BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic,
+                                       null, CallingConventions.Any, argst, null);
+                               
+                               if (embed_res == null) {
+                                       Report.RuntimeMissingSupport (Location.Null, "Resource embedding");
+                               }
+                       }
+
+                       readonly object[] args;
+
+                       public EmbededResource (string name, string file, bool isPrivate)
+                       {
+                               args = new object [3];
+                               args [0] = name;
+                               args [1] = file;
+                               args [2] = isPrivate ? ResourceAttributes.Private : ResourceAttributes.Public;
+                       }
+
+                       public void Emit()
+                       {
+                               embed_res.Invoke (CodeGen.Assembly.Builder, args);
+                       }
+
+                       public string FileName {
+                               get {
+                                       return (string)args [1];
+                               }
+                       }
+               }
+
+               class LinkedResource : IResource
+               {
+                       readonly string file;
+                       readonly string name;
+                       readonly ResourceAttributes attribute;
+
+                       public LinkedResource (string name, string file, bool isPrivate)
+                       {
+                               this.name = name;
+                               this.file = file;
+                               this.attribute = isPrivate ? ResourceAttributes.Private : ResourceAttributes.Public;
+                       }
+
+                       public void Emit ()
+                       {
+                               CodeGen.Assembly.Builder.AddResourceFile (name, Path.GetFileName(file), attribute);
+                       }
+
+                       public string FileName {
+                               get {
+                                       return file;
+                               }
+                       }
+               }
+
+
+               IDictionary embedded_resources = new HybridDictionary ();
+
+               public void Add (bool embeded, string file, string name)
+               {
+                       Add (embeded, file, name, false);
+               }
+
+               public void Add (bool embeded, string file, string name, bool isPrivate)
+               {
+                       if (embedded_resources.Contains (name)) {
+                               Report.Error (1508, "The resource identifier `{0}' has already been used in this assembly", name);
+                               return;
+                       }
+                       IResource r = embeded ? 
+                               (IResource) new EmbededResource (name, file, isPrivate) : 
+                               new LinkedResource (name, file, isPrivate);
+
+                       embedded_resources.Add (name, r);
+               }
+
+               public void Emit ()
+               {
+                       foreach (IResource r in embedded_resources.Values) {
+                               if (!File.Exists (r.FileName)) {
+                                       Report.Error (1566, "Error reading resource file `{0}'", r.FileName);
+                                       continue;
+                               }
+                               
+                               r.Emit ();
+                       }
+               }
+       }
+
        //
        // This is the only public entry point
        //
@@ -1809,6 +1960,12 @@ namespace Mono.CSharp
                                Reset ();
                        }
                }
+
+               public static int[] AllWarningNumbers {
+                       get {
+                               return Report.AllWarnings;
+                       }
+               }
                
                static void Reset ()
                {
@@ -1818,8 +1975,11 @@ namespace Mono.CSharp
                        Report.Reset ();
                        TypeManager.Reset ();
                        TypeHandle.Reset ();
-                       Namespace.Reset ();
+                       RootNamespace.Reset ();
+                       NamespaceEntry.Reset ();
                        CodeGen.Reset ();
+                       Attribute.Reset ();
+                       AttributeTester.Reset ();
                }
        }
 }