Add initial reflection dependant code
[mono.git] / mcs / mcs / driver.cs
index 46dfd3a740a2c0854b0636e2aee1c4078c9964fb..ff1c6bceef6d19f93a24ab249fc597064007f3ba 100644 (file)
 // Copyright 2004, 2005, 2006, 2007, 2008 Novell, Inc
 //
 
+using System;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using System.Globalization;
+using System.Diagnostics;
+
 namespace Mono.CSharp
 {
-       using System;
-       using System.Reflection;
-       using System.Reflection.Emit;
-       using System.Collections;
-       using System.Collections.Specialized;
-       using System.IO;
-       using System.Text;
-       using System.Globalization;
-       using System.Diagnostics;
-
        public enum Target {
                Library, Exe, Module, WinExe
        };
 
-#if GMCS_SOURCE
-       enum Platform {
+       public enum Platform {
                AnyCPU, X86, X64, IA64
-       };
-#endif
+       }
        
        /// <summary>
        ///    The compiler driver.
@@ -41,49 +38,42 @@ namespace Mono.CSharp
                //
                // Assemblies references to be linked.   Initialized with
                // mscorlib.dll here.
-               ArrayList references;
+               List<string> references;
 
                //
                // If any of these fail, we ignore the problem.  This is so
                // that we can list all the assemblies in Windows and not fail
                // if they are missing on Linux.
                //
-               ArrayList soft_references;
+               List<string> soft_references;
 
                // 
                // External aliases for assemblies.
                //
-               Hashtable external_aliases;
+               Dictionary<string, string> external_aliases;
 
                //
                // Modules to be linked
                //
-               ArrayList modules;
+               List<string> modules;
 
                // Lookup paths
-               static ArrayList link_paths;
+               List<string> link_paths;
 
                // Whether we want to only run the tokenizer
                bool tokenize;
                
                string first_source;
 
-               bool want_debugging_support;
                bool parse_only;
                bool timestamps;
+               internal int fatal_errors;
                
                //
                // Whether to load the initial config file (what CSC.RSP has by default)
                // 
                bool load_default_config = true;
 
-               //
-               // A list of resource files
-               //
-               Resources embedded_resources;
-               string win32ResourceFile;
-               string win32IconFile;
-
                //
                // Output file
                //
@@ -92,13 +82,16 @@ namespace Mono.CSharp
                //
                // Last time we took the time
                //
-               DateTime last_time, first_time;
+               Stopwatch stopwatch;
+               DateTime first_time;
 
                //
                // Encoding.
                //
                Encoding encoding;
 
+               internal readonly CompilerContext ctx;
+
                static readonly char[] argument_value_separator = new char [] { ';', ',' };
 
                static public void Reset ()
@@ -106,32 +99,36 @@ namespace Mono.CSharp
                        output_file = null;
                }
 
-               public Driver ()
+               private Driver (CompilerContext ctx)
                {
+                       this.ctx = ctx;
                        encoding = Encoding.Default;
                }
 
-               public static Driver Create (string [] args, bool require_files)
+               public static Driver Create (string[] args, bool require_files, ReportPrinter printer)
                {
-                       Driver d = new Driver ();
+                       Driver d = new Driver (new CompilerContext (new Report (printer)));
+
                        if (!d.ParseArguments (args, require_files))
                                return null;
 
                        return d;
                }
 
+               Report Report {
+                       get { return ctx.Report; }
+               }
+
                void ShowTime (string msg)
                {
                        if (!timestamps)
                                return;
 
-                       DateTime now = DateTime.Now;
-                       TimeSpan span = now - last_time;
-                       last_time = now;
+                       stopwatch.Stop ();
 
-                       Console.WriteLine (
-                               "[{0:00}:{1:000}] {2}",
-                               (int) span.TotalSeconds, span.Milliseconds, msg);
+                       Console.WriteLine ("{0,5}ms {1}", stopwatch.ElapsedMilliseconds, msg);
+
+                       stopwatch = Stopwatch.StartNew ();
                }
 
                void ShowTotalTime (string msg)
@@ -141,14 +138,13 @@ namespace Mono.CSharp
 
                        DateTime now = DateTime.Now;
                        TimeSpan span = now - first_time;
-                       last_time = now;
 
                        Console.WriteLine (
                                "[{0:00}:{1:000}] {2}",
                                (int) span.TotalSeconds, span.Milliseconds, msg);
                }              
               
-               void tokenize_file (CompilationUnit file)
+               void tokenize_file (CompilationUnit file, CompilerContext ctx)
                {
                        Stream input;
 
@@ -161,7 +157,7 @@ namespace Mono.CSharp
 
                        using (input){
                                SeekableStreamReader reader = new SeekableStreamReader (input, encoding);
-                               Tokenizer lexer = new Tokenizer (reader, file);
+                               Tokenizer lexer = new Tokenizer (reader, file, ctx);
                                int token, tokens = 0, errors = 0;
 
                                while ((token = lexer.token ()) != Token.EOF){
@@ -175,7 +171,7 @@ namespace Mono.CSharp
                        return;
                }
 
-               void Parse (CompilationUnit file)
+               void Parse (CompilationUnit file, ModuleContainer module)
                {
                        Stream input;
 
@@ -186,42 +182,36 @@ namespace Mono.CSharp
                                return;
                        }
 
-                       SeekableStreamReader reader = new SeekableStreamReader (input, encoding);
-
                        // Check 'MZ' header
-                       if (reader.Read () == 77 && reader.Read () == 90) {
+                       if (input.ReadByte () == 77 && input.ReadByte () == 90) {
                                Report.Error (2015, "Source file `{0}' is a binary file and not a text file", file.Name);
                                input.Close ();
                                return;
                        }
 
-                       reader.Position = 0;
-                       Parse (reader, file);
+                       input.Position = 0;
+                       SeekableStreamReader reader = new SeekableStreamReader (input, encoding);
+
+                       Parse (reader, file, module);
+                       reader.Dispose ();
                        input.Close ();
                }       
                
-               void Parse (SeekableStreamReader reader, CompilationUnit file)
+               void Parse (SeekableStreamReader reader, CompilationUnit file, ModuleContainer module)
                {
-                       CSharpParser parser = new CSharpParser (reader, file);
-                       parser.ErrorOutput = Report.Stderr;
-                       try {
-                               parser.parse ();
-                       } catch (Exception ex) {
-                               Report.Error(589, parser.Lexer.Location,
-                                       "Compilation aborted in file `{0}', {1}", file.Name, ex);
-                       }
+                       CSharpParser parser = new CSharpParser (reader, file, module);
+                       parser.parse ();
                }
 
                static void OtherFlags ()
                {
                        Console.WriteLine (
                                "Other flags in the compiler\n" +
-                               "   --fatal            Makes errors fatal\n" +
+                               "   --fatal[=COUNT]    Makes errors after COUNT fatal\n" +
+                               "   --lint             Enhanced warnings\n" +
                                "   --parse            Only parses the source file\n" +
-                               "   --typetest         Tests the tokenizer's built-in type parser\n" +
                                "   --stacktrace       Shows stack trace at error location\n" +
                                "   --timestamp        Displays time stamps of various compiler events\n" +
-                               "   --expect-error X   Expect that error X will be encountered\n" +
                                "   -v                 Verbose parsing (for debugging the parser)\n" + 
                                "   --mcs-debug X      Sets MCS debugging level to X\n");
                }
@@ -243,7 +233,7 @@ namespace Mono.CSharp
                                "   -help                Lists all compiler options (short: -?)\n" + 
                                "   -keycontainer:NAME   The key pair container used to sign the output assembly\n" +
                                "   -keyfile:FILE        The key file used to strongname the ouput assembly\n" +
-                               "   -langversion:TEXT    Specifies language version: ISO-1, ISO-2, Default, or Future\n" + 
+                               "   -langversion:TEXT    Specifies language version: ISO-1, ISO-2, 3, Default, or Future\n" + 
                                "   -lib:PATH1[,PATHn]   Specifies the location of referenced assemblies\n" +
                                "   -main:CLASS          Specifies the class with the Main method (short: -m)\n" +
                                "   -noconfig            Disables implicitly referenced assemblies\n" +
@@ -276,7 +266,7 @@ namespace Mono.CSharp
                                "Options can be of the form -option or /option");
                }
 
-               static void TargetUsage ()
+               void TargetUsage ()
                {
                        Report.Error (2019, "Invalid target type for -target. Valid options are `exe', `winexe', `library' or `module'");
                }
@@ -298,14 +288,16 @@ namespace Mono.CSharp
                public static int Main (string[] args)
                {
                        Location.InEmacs = Environment.GetEnvironmentVariable ("EMACS") == "t";
-
-                       Driver d = Driver.Create (args, true);
+                       var crp = new ConsoleReportPrinter ();
+                       Driver d = Driver.Create (args, true, crp);
                        if (d == null)
                                return 1;
 
-                       if (d.Compile () && Report.Errors == 0) {
-                               if (Report.Warnings > 0) {
-                                       Console.WriteLine ("Compilation succeeded - {0} warning(s)", Report.Warnings);
+                       crp.Fatal = d.fatal_errors;
+
+                       if (d.Compile () && d.Report.Errors == 0) {
+                               if (d.Report.Warnings > 0) {
+                                       Console.WriteLine ("Compilation succeeded - {0} warning(s)", d.Report.Warnings);
                                }
                                Environment.Exit (0);
                                return 0;
@@ -313,38 +305,34 @@ namespace Mono.CSharp
                        
                        
                        Console.WriteLine("Compilation failed: {0} error(s), {1} warnings",
-                               Report.Errors, Report.Warnings);
+                               d.Report.Errors, d.Report.Warnings);
                        Environment.Exit (1);
                        return 1;
                }
 
-               static public void LoadAssembly (string assembly, bool soft)
-               {
-                       LoadAssembly (assembly, null, soft);
-               }
-
-               static void Error6 (string name, string log)
+               void Error6 (string name, string log)
                {
                        if (log != null && log.Length > 0)
                                Report.ExtraInformation (Location.Null, "Log:\n" + log + "\n(log related to previous ");
                        Report.Error (6, "cannot find metadata file `{0}'", name);
                }
 
-               static void Error9 (string type, string filename, string log)
+               void Error9 (string type, string filename, string log)
                {
                        if (log != null && log.Length > 0)
                                Report.ExtraInformation (Location.Null, "Log:\n" + log + "\n(log related to previous ");
                        Report.Error (9, "file `{0}' has invalid `{1}' metadata", filename, type);
                }
 
-               static void BadAssembly (string filename, string log)
+               void BadAssembly (string filename, string log)
                {
-                       MethodInfo adder_method = AssemblyClass.AddModule_Method;
+/*
+                       MethodInfo adder_method = null; // AssemblyDefinition.AddModule_Method;
 
                        if (adder_method != null) {
                                AssemblyName an = new AssemblyName ();
                                an.Name = ".temp";
-                               AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly (an, AssemblyBuilderAccess.Run);
+                               var ab = AppDomain.CurrentDomain.DefineDynamicAssembly (an, AssemblyBuilderAccess.Run);
                                try {
                                        object m = null;
                                        try {
@@ -366,10 +354,11 @@ namespace Mono.CSharp
                                        // swallow exception
                                }
                        }
+*/
                        Error9 ("assembly", filename, log);
                }
 
-               static public void LoadAssembly (string assembly, string alias, bool soft)
+               public Assembly LoadAssemblyFile (string assembly, bool soft)
                {
                        Assembly a = null;
                        string total_log = "";
@@ -399,22 +388,15 @@ namespace Mono.CSharp
                                                        break;
                                                } catch (FileNotFoundException ff) {
                                                        if (soft)
-                                                               return;
+                                                               return a;
                                                        total_log += ff.FusionLog;
                                                }
                                        }
                                        if (err) {
                                                Error6 (assembly, total_log);
-                                               return;
+                                               return a;
                                        }
                                }
-
-                               // Extern aliased refs require special handling
-                               if (alias == null)
-                                       GlobalRootNamespace.Instance.AddAssemblyReference (a);
-                               else
-                                       GlobalRootNamespace.Instance.DefineRootNamespace (alias, a);
-
                        } catch (BadImageFormatException f) {
                                // .NET 2.0 throws this if we try to load a module without an assembly manifest ...
                                BadAssembly (f.FileName, f.FusionLog);
@@ -422,16 +404,17 @@ namespace Mono.CSharp
                                // ... while .NET 1.1 throws this
                                BadAssembly (f.FileName, f.FusionLog);
                        }
+
+                       return a;
                }
 
-               static public void LoadModule (string module)
+               void LoadModule (AssemblyDefinition assembly, string module)
                {
-                       Module m = null;
                        string total_log = "";
 
                        try {
                                try {
-                                       m = CodeGen.Assembly.AddModule (module);
+                                       assembly.AddModule (module);
                                } catch (FileNotFoundException) {
                                        bool err = true;
                                        foreach (string dir in link_paths) {
@@ -440,7 +423,7 @@ namespace Mono.CSharp
                                                        full_path += ".netmodule";
 
                                                try {
-                                                       m = CodeGen.Assembly.AddModule (full_path);
+                                                       assembly.AddModule (full_path);
                                                        err = false;
                                                        break;
                                                } catch (FileNotFoundException ff) {
@@ -452,9 +435,6 @@ namespace Mono.CSharp
                                                return;
                                        }
                                }
-
-                               GlobalRootNamespace.Instance.AddModuleReference (m);
-
                        } catch (BadImageFormatException f) {
                                Error9 ("module", f.FileName, f.FusionLog);
                        } catch (FileLoadException f) {
@@ -465,33 +445,71 @@ namespace Mono.CSharp
                /// <summary>
                ///   Loads all assemblies referenced on the command line
                /// </summary>
-               public void LoadReferences ()
+               public void LoadReferences (ModuleContainer module, MetadataImporter importer)
                {
                        link_paths.Add (GetSystemDir ());
                        link_paths.Add (Directory.GetCurrentDirectory ());
+                       Assembly a;
+                       var loaded = new List<Tuple<RootNamespace, Assembly>> ();
 
                        //
                        // Load Core Library for default compilation
                        //
-                       if (RootContext.StdLib)
-                               LoadAssembly ("mscorlib", false);
+                       if (RootContext.StdLib) {
+                               a = LoadAssemblyFile ("mscorlib", false);
+                               if (a != null)
+                                       loaded.Add (Tuple.Create (module.GlobalRootNamespace, a));
+                       }
 
-                       foreach (string r in soft_references)
-                               LoadAssembly (r, true);
+                       foreach (string r in soft_references) {
+                               a = LoadAssemblyFile (r, true);
+                               if (a != null)
+                                       loaded.Add (Tuple.Create (module.GlobalRootNamespace, a));
+                       }
 
-                       foreach (string r in references)
-                               LoadAssembly (r, false);
+                       foreach (string r in references) {
+                               a = LoadAssemblyFile (r, false);
+                               if (a == null)
+                                       continue;
 
-                       foreach (DictionaryEntry entry in external_aliases)
-                               LoadAssembly ((string) entry.Value, (string) entry.Key, false);
-                               
-                       GlobalRootNamespace.Instance.ComputeNamespaces ();
+                               var key = Tuple.Create (module.GlobalRootNamespace, a);
+                               if (loaded.Contains (key))
+                                       continue;
+
+                               loaded.Add (key);
+                       }
+
+                       foreach (var entry in external_aliases) {
+                               a = LoadAssemblyFile (entry.Value, false);
+                               if (a == null)
+                                       continue;
+
+                               var key = Tuple.Create (module.CreateRootNamespace (entry.Key), a);
+                               if (loaded.Contains (key))
+                                       continue;
+
+                               loaded.Add (key);
+                       }
+
+                       foreach (var entry in loaded) {
+                               importer.ImportAssembly (entry.Item2, entry.Item1);
+                       }
+               }
+
+               void LoadModules (AssemblyDefinition assembly)
+               {
+                       if (modules.Count == 0)
+                               return;
+
+                       foreach (var module in modules) {
+                               LoadModule (assembly, module);
+                       }
                }
 
                static string [] LoadArgs (string file)
                {
                        StreamReader f;
-                       ArrayList args = new ArrayList ();
+                       var args = new List<string> ();
                        string line;
                        try {
                                f = new StreamReader (file);
@@ -531,10 +549,7 @@ namespace Mono.CSharp
                                }
                        }
 
-                       string [] ret_value = new string [args.Count];
-                       args.CopyTo (ret_value, 0);
-
-                       return ret_value;
+                       return args.ToArray ();
                }
 
                //
@@ -582,18 +597,18 @@ namespace Mono.CSharp
                        if (first_source == null)
                                first_source = f;
 
-                       Location.AddFile (f);
+                       Location.AddFile (Report, f);
                }
 
                bool ParseArguments (string[] args, bool require_files)
                {
-                       references = new ArrayList ();
-                       external_aliases = new Hashtable ();
-                       soft_references = new ArrayList ();
-                       modules = new ArrayList (2);
-                       link_paths = new ArrayList ();
+                       references = new List<string> ();
+                       external_aliases = new Dictionary<string, string> ();
+                       soft_references = new List<string> ();
+                       modules = new List<string> (2);
+                       link_paths = new List<string> ();
 
-                       ArrayList response_file_list = null;
+                       List<string> response_file_list = null;
                        bool parsing_options = true;
 
                        for (int i = 0; i < args.Length; i++) {
@@ -606,7 +621,7 @@ namespace Mono.CSharp
                                        string response_file = arg.Substring (1);
 
                                        if (response_file_list == null)
-                                               response_file_list = new ArrayList ();
+                                               response_file_list = new List<string> ();
 
                                        if (response_file_list.Contains (response_file)) {
                                                Report.Error (
@@ -678,7 +693,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) {
+                       if (first_source == null && RootContext.Resources == null) {
                                Report.Error (2008, "No files to compile were specified");
                                return false;
                        }
@@ -686,16 +701,16 @@ namespace Mono.CSharp
                        return true;
                }
 
-               public void Parse ()
+               public void Parse (ModuleContainer module)
                {
                        Location.Initialize ();
 
-                       ArrayList cu = Location.SourceFiles;
+                       var cu = Location.SourceFiles;
                        for (int i = 0; i < cu.Count; ++i) {
                                if (tokenize) {
-                                       tokenize_file ((CompilationUnit) cu [i]);
+                                       tokenize_file (cu [i], ctx);
                                } else {
-                                       Parse ((CompilationUnit) cu [i]);
+                                       Parse (cu [i], module);
                                }
                        }
                }
@@ -788,6 +803,8 @@ namespace Mono.CSharp
 
                        if (RootContext.Version > LanguageVersion.ISO_2)
                                soft_references.Add ("System.Core");
+                       if (RootContext.Version > LanguageVersion.V_3)
+                               soft_references.Add ("Microsoft.CSharp");
                }
 
                public static string OutputFile
@@ -800,7 +817,7 @@ namespace Mono.CSharp
                        }
                }
 
-               static void SetWarningLevel (string s)
+               void SetWarningLevel (string s)
                {
                        int level = -1;
 
@@ -891,7 +908,7 @@ namespace Mono.CSharp
                                return true;
                                
                        case "--stacktrace":
-                               Report.Stacktrace = true;
+                               Report.Printer.Stacktrace = true;
                                return true;
                                
                        case "--linkresource":
@@ -902,10 +919,8 @@ namespace Mono.CSharp
                                        Report.Error (5, "Missing argument to --linkres"); 
                                        Environment.Exit (1);
                                }
-                               if (embedded_resources == null)
-                                       embedded_resources = new Resources ();
-                               
-                               embedded_resources.Add (false, args [++i], args [i]);
+
+                               AddResource (new AssemblyResource (args[++i], args[i]));
                                return true;
                                
                        case "--resource":
@@ -916,10 +931,8 @@ namespace Mono.CSharp
                                        Report.Error (5, "Missing argument to --resource"); 
                                        Environment.Exit (1);
                                }
-                               if (embedded_resources == null)
-                                       embedded_resources = new Resources ();
-                               
-                               embedded_resources.Add (true, args [++i], args [i]);
+
+                               AddResource (new AssemblyResource (args[++i], args[i], true));
                                return true;
                                
                        case "--target":
@@ -981,16 +994,16 @@ namespace Mono.CSharp
                                }
                                link_paths.Add (args [++i]);
                                return true;
+
+                       case "--lint":
+                               RootContext.EnhancedWarnings = true;
+                               return true;
                                
                        case "--nostdlib":
                                Report.Warning (-29, 1, "Compatibility: Use -nostdlib instead of --nostdlib");
                                RootContext.StdLib = false;
                                return true;
                                
-                       case "--fatal":
-                               Report.Fatal = true;
-                               return true;
-                               
                        case "--nowarn":
                                Report.Warning (-29, 1, "Compatibility: Use -nowarn instead of --nowarn");
                                if ((i + 1) >= args.Length){
@@ -1049,25 +1062,35 @@ namespace Mono.CSharp
                                
                        case "--timestamp":
                                timestamps = true;
-                               last_time = first_time = DateTime.Now;
                                return true;
 
                        case "--debug": case "-g":
                                Report.Warning (-29, 1, "Compatibility: Use -debug option instead of -g or --debug");
-                               want_debugging_support = true;
+                               RootContext.GenerateDebugInfo = true;
                                return true;
                                
                        case "--noconfig":
                                Report.Warning (-29, 1, "Compatibility: Use -noconfig option instead of --noconfig");
                                load_default_config = false;
                                return true;
+
+                       default:
+                               if (arg.StartsWith ("--fatal")){
+                                       if (arg.StartsWith ("--fatal=")){
+                                               if (!Int32.TryParse (arg.Substring (8), out fatal_errors))
+                                                       fatal_errors = 1;
+                                       } else
+                                               fatal_errors = 1;
+                                       return true;
+                               }
+                               break;
                        }
 
                        return false;
                }
 
 #if !SMCS_SOURCE
-               public static string GetPackageFlags (string packages, bool fatal)
+               public static string GetPackageFlags (string packages, bool fatal, Report report)
                {
                        ProcessStartInfo pi = new ProcessStartInfo ();
                        pi.FileName = "pkg-config";
@@ -1078,7 +1101,7 @@ namespace Mono.CSharp
                        try {
                                p = Process.Start (pi);
                        } catch (Exception e) {
-                               Report.Error (-27, "Couldn't run pkg-config: " + e.Message);
+                               report.Error (-27, "Couldn't run pkg-config: " + e.Message);
                                if (fatal)
                                        Environment.Exit (1);
                                p.Close ();
@@ -1086,14 +1109,14 @@ namespace Mono.CSharp
                        }
                        
                        if (p.StandardOutput == null){
-                               Report.Warning (-27, 1, "Specified package did not return any information");
+                               report.Warning (-27, 1, "Specified package did not return any information");
                                p.Close ();
                                return null;
                        }
                        string pkgout = p.StandardOutput.ReadToEnd ();
                        p.WaitForExit ();
                        if (p.ExitCode != 0) {
-                               Report.Error (-27, "Error running pkg-config. Check the above output.");
+                               report.Error (-27, "Error running pkg-config. Check the above output.");
                                if (fatal)
                                        Environment.Exit (1);
                                p.Close ();
@@ -1174,6 +1197,7 @@ namespace Mono.CSharp
                                RootContext.Optimize = false;
                                return true;
 
+                       // TODO: Not supported by csc 3.5+
                        case "/incremental":
                        case "/incremental+":
                        case "/incremental-":
@@ -1188,11 +1212,12 @@ namespace Mono.CSharp
                                }
 
                                foreach (string d in value.Split (argument_value_separator)) {
-                                       if (!Tokenizer.IsValidIdentifier (d)) {
-                                               Report.Warning (2029, 1, "Invalid conditional define symbol `{0}'", d);
+                                       string conditional = d.Trim ();
+                                       if (!Tokenizer.IsValidIdentifier (conditional)) {
+                                               Report.Warning (2029, 1, "Invalid conditional define symbol `{0}'", conditional);
                                                continue;
                                        }
-                                       RootContext.AddConditional (d);
+                                       RootContext.AddConditional (conditional);
                                }
                                return true;
                        }
@@ -1212,7 +1237,7 @@ namespace Mono.CSharp
                                        Environment.Exit (1);
                                }
                                packages = String.Join (" ", value.Split (new Char [] { ';', ',', '\n', '\r'}));
-                               string pkgout = GetPackageFlags (packages, true);
+                               string pkgout = GetPackageFlags (packages, true, Report);
                                
                                if (pkgout != null){
                                        string [] xargs = pkgout.Trim (new Char [] {' ', '\n', '\r', '\t'}).
@@ -1227,32 +1252,34 @@ namespace Mono.CSharp
                        case "/linkresource":
                        case "/res":
                        case "/resource":
-                               if (embedded_resources == null)
-                                       embedded_resources = new Resources ();
-
-                               bool embeded = arg [1] == 'r' || arg [1] == 'R';
+                               AssemblyResource res = null;                    
                                string[] s = value.Split (argument_value_separator);
                                switch (s.Length) {
                                case 1:
                                        if (s[0].Length == 0)
                                                goto default;
-                                       embedded_resources.Add (embeded, s [0], Path.GetFileName (s[0]));
+                                       res = new AssemblyResource (s [0], Path.GetFileName (s[0]));
                                        break;
                                case 2:
-                                       embedded_resources.Add (embeded, s [0], s [1]);
+                                       res = new AssemblyResource (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");
+                                       res = new AssemblyResource (s[0], s[1], s[2] == "private");
                                        break;
                                default:
                                        Report.Error (-2005, "Wrong number of arguments for option `{0}'", option);
                                        break;
                                }
 
+                               if (res != null) {
+                                       res.IsEmbeded = arg [1] == 'r' || arg [1] == 'R';
+                                       AddResource (res);
+                               }
+
                                return true;
                                
                        case "/recurse":
@@ -1304,10 +1331,10 @@ namespace Mono.CSharp
                                        Environment.Exit (1);
                                }
                                
-                               if (win32IconFile != null)
+                               if (RootContext.Win32IconFile != null)
                                        Report.Error (1565, "Cannot specify the `win32res' and the `win32ico' compiler option at the same time");
 
-                               win32ResourceFile = value;
+                               RootContext.Win32ResourceFile = value;
                                return true;
                        }
                        case "/win32icon": {
@@ -1316,10 +1343,10 @@ namespace Mono.CSharp
                                        Environment.Exit (1);
                                }
 
-                               if (win32ResourceFile != null)
+                               if (RootContext.Win32ResourceFile != null)
                                        Report.Error (1565, "Cannot specify the `win32res' and the `win32ico' compiler option at the same time");
 
-                               win32IconFile = value;
+                               RootContext.Win32IconFile = value;
                                return true;
                        }
                        case "/doc": {
@@ -1345,17 +1372,17 @@ namespace Mono.CSharp
                        }
 
                        case "/debug-":
-                               want_debugging_support = false;
+                               RootContext.GenerateDebugInfo = false;
                                return true;
                                
                        case "/debug":
                                if (value == "full" || value == "")
-                                       want_debugging_support = true;
+                                       RootContext.GenerateDebugInfo = true;
 
                                return true;
                                
                        case "/debug+":
-                               want_debugging_support = true;
+                               RootContext.GenerateDebugInfo = true;
                                return true;
 
                        case "/checked":
@@ -1438,7 +1465,6 @@ namespace Mono.CSharp
                                return true;
 
                        case "/platform":
-#if GMCS_SOURCE
                                switch (value.ToLower (CultureInfo.InvariantCulture)) {
                                case "anycpu":
                                        RootContext.Platform = Platform.AnyCPU;
@@ -1456,7 +1482,7 @@ namespace Mono.CSharp
                                        Report.Error (1672, "Invalid platform type for -platform. Valid options are `anycpu', `x86', `x64' or `itanium'");
                                        break;
                                }
-#endif
+
                                return true;
 
                                // We just ignore this.
@@ -1511,6 +1537,7 @@ namespace Mono.CSharp
                                RootContext.StrongNameKeyContainer = value;
                                return true;
                        case "/delaysign+":
+                       case "/delaysign":
                                RootContext.StrongNameDelaySign = true;
                                return true;
                        case "/delaysign-":
@@ -1521,13 +1548,10 @@ namespace Mono.CSharp
                                switch (value.ToLower (CultureInfo.InvariantCulture)) {
                                case "iso-1":
                                        RootContext.Version = LanguageVersion.ISO_1;
-                                       return true;
-                                       
+                                       return true;    
                                case "default":
                                        RootContext.Version = LanguageVersion.Default;
-#if GMCS_SOURCE                                        
                                        RootContext.AddConditional ("__V2__");
-#endif
                                        return true;
                                case "iso-2":
                                        RootContext.Version = LanguageVersion.ISO_2;
@@ -1566,7 +1590,7 @@ namespace Mono.CSharp
                        return false;
                }
 
-               static void Error_WrongOption (string option)
+               void Error_WrongOption (string option)
                {
                        Report.Error (2007, "Unrecognized command-line option: `{0}'", option);
                }
@@ -1610,6 +1634,22 @@ namespace Mono.CSharp
                        // Could here hashtable throw an exception?
                        external_aliases [identifier] = assembly;
                }
+
+               void AddResource (AssemblyResource res)
+               {
+                       if (RootContext.Resources == null) {
+                               RootContext.Resources = new List<AssemblyResource> ();
+                               RootContext.Resources.Add (res);
+                               return;
+                       }
+
+                       if (RootContext.Resources.Contains (res)) {
+                               ctx.Report.Error (1508, "The resource identifier `{0}' has already been used in this assembly", res.Name);
+                               return;
+                       }
+
+                       RootContext.Resources.Add (res);
+               }
                
                static bool IsExternAliasValid (string identifier)
                {
@@ -1638,10 +1678,19 @@ namespace Mono.CSharp
                //
                public bool Compile ()
                {
-                       // TODO: Should be passed to parser as an argument
-                       RootContext.ToplevelTypes = new ModuleContainer (RootContext.Unsafe);
+                       var module = new ModuleContainer (ctx);
+                       RootContext.ToplevelTypes = module;
+
+                       var ctypes = TypeManager.InitCoreTypes ();
+
+                       if (timestamps) {
+                               stopwatch = Stopwatch.StartNew ();
+                               first_time = DateTime.Now;
+                       }
+
+                       Parse (module);
+                       ShowTime ("Parsing source files");
 
-                       Parse ();
                        if (Report.Errors > 0)
                                return false;
 
@@ -1670,65 +1719,44 @@ namespace Mono.CSharp
                                        output_file = first_source + RootContext.TargetExt;
                        }
 
-                       if (!CodeGen.Init (output_file, output_file, want_debugging_support))
-                               return false;
-
-                       if (RootContext.Target == Target.Module) {
-                               PropertyInfo module_only = typeof (AssemblyBuilder).GetProperty ("IsModuleOnly", BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic);
-                               if (module_only == null) {
-                                       Report.RuntimeMissingSupport (Location.Null, "/target:module");
-                                       Environment.Exit (1);
-                               }
-
-                               MethodInfo set_method = module_only.GetSetMethod (true);
-                               set_method.Invoke (CodeGen.Assembly.Builder, BindingFlags.Default, null, new object[]{true}, null);
-                       }
-
-                       GlobalRootNamespace.Instance.AddModuleReference (RootContext.ToplevelTypes.Builder);
-
                        //
                        // Load assemblies required
                        //
                        if (timestamps)
-                               ShowTime ("Loading references");
+                               stopwatch = Stopwatch.StartNew ();
 
-                       LoadReferences ();
-                       
-                       if (modules.Count > 0) {
-                               foreach (string module in modules)
-                                       LoadModule (module);
-                       }
-                       
-                       if (timestamps)
-                               ShowTime ("References loaded");
+                       var assembly = module.MakeExecutable (output_file, output_file);
+
+                       var importer = new ReflectionImporter ();
+                       assembly.Importer = importer;
+
+                       LoadReferences (module, importer);
+               
+                       ShowTime ("Imporing referenced assemblies");
                        
-                       if (!TypeManager.InitCoreTypes () || Report.Errors > 0)
+                       if (!TypeManager.InitCoreTypes (module, ctypes))
                                return false;
 
-                       TypeManager.InitOptionalCoreTypes ();
+                       TypeManager.InitOptionalCoreTypes (ctx);
 
-                       if (timestamps)
-                               ShowTime ("   Core Types done");
+                       ShowTime ("Initializing predefined types");
 
-                       //
-                       // The second pass of the compiler
-                       //
-                       if (timestamps)
-                               ShowTime ("Resolving tree");
-                       RootContext.ResolveTree ();
+                       if (!assembly.Create (AppDomain.CurrentDomain, AssemblyBuilderAccess.Save))
+                               return false;
+
+                       LoadModules (assembly);
+
+                       module.Define ();
+
+                       ShowTime ("Types definition");
 
                        if (Report.Errors > 0)
                                return false;
-                       if (timestamps)
-                               ShowTime ("Populate tree");
-                       if (!RootContext.StdLib)
-                               RootContext.BootCorlib_PopulateCoreTypes ();
-                       RootContext.PopulateTypes ();
 
                        if (Report.Errors == 0 &&
                                RootContext.Documentation != null &&
                                !RootContext.Documentation.OutputDocComment (
-                                       output_file))
+                                       output_file, Report))
                                return false;
 
                        //
@@ -1740,14 +1768,8 @@ namespace Mono.CSharp
                                return false;
                        }
 
-                       CodeGen.Assembly.Resolve ();
+                       assembly.Resolve ();
                        
-                       if (RootContext.VerifyClsCompliance) {
-                               if (CodeGen.Assembly.IsClsCompliant) {
-                                       AttributeTester.VerifyModulesClsCompliance ();
-                                       TypeManager.LoadAllImportedTypes ();
-                               }
-                       }
                        if (Report.Errors > 0)
                                return false;
                        
@@ -1755,260 +1777,76 @@ namespace Mono.CSharp
                        // The code generator
                        //
                        if (timestamps)
-                               ShowTime ("Emitting code");
-                       ShowTotalTime ("Total so far");
-                       RootContext.EmitCode ();
-                       if (timestamps)
-                               ShowTime ("   done");
+                               stopwatch = Stopwatch.StartNew ();
 
-                       if (Report.Errors > 0){
-                               return false;
-                       }
+                       assembly.Emit ();
 
-                       if (timestamps)
-                               ShowTime ("Closing types");
-
-                       RootContext.CloseTypes ();
+                       ShowTime ("Resolving and emitting members blocks");
 
-                       PEFileKinds k = PEFileKinds.ConsoleApplication;
-
-                       switch (RootContext.Target) {
-                       case Target.Library:
-                       case Target.Module:
-                               k = PEFileKinds.Dll; break;
-                       case Target.Exe:
-                               k = PEFileKinds.ConsoleApplication; break;
-                       case Target.WinExe:
-                               k = PEFileKinds.WindowApplication; break;
+                       if (Report.Errors > 0){
+                               return false;
                        }
 
-                       if (RootContext.NeedsEntryPoint) {
-                               Method ep = RootContext.EntryPoint;
+                       module.CloseType ();
 
-                               if (ep == null) {
-                                       if (RootContext.MainClass != null) {
-                                               DeclSpace main_cont = RootContext.ToplevelTypes.GetDefinition (RootContext.MainClass) as DeclSpace;
-                                               if (main_cont == null) {
-                                                       Report.Error (1555, "Could not find `{0}' specified for Main method", RootContext.MainClass); 
-                                                       return false;
-                                               }
+                       ShowTime ("Closing types");
 
-                                               if (!(main_cont is ClassOrStruct)) {
-                                                       Report.Error (1556, "`{0}' specified for Main method must be a valid class or struct", RootContext.MainClass);
-                                                       return false;
-                                               }
-
-                                               Report.Error (1558, main_cont.Location, "`{0}' does not have a suitable static Main method", main_cont.GetSignatureForError ());
-                                               return false;
-                                       }
-
-                                       if (Report.Errors == 0)
-                                               Report.Error (5001, "Program `{0}' does not contain a static `Main' method suitable for an entry point",
-                                                       output_file);
-                                       return false;
-                               }
+                       if (timestamps)
+                               stopwatch = Stopwatch.StartNew ();
 
-                               CodeGen.Assembly.Builder.SetEntryPoint (ep.MethodBuilder, k);
-                       } else if (RootContext.MainClass != null) {
-                               Report.Error (2017, "Cannot specify -main if building a module or library");
-                       }
+                       assembly.EmbedResources ();
+                       ShowTime ("Embedding resources");
 
-                       if (embedded_resources != null){
-                               if (RootContext.Target == Target.Module) {
-                                       Report.Error (1507, "Cannot link resource file when building a module");
-                                       return false;
-                               }
-
-                               embedded_resources.Emit ();
-                       }
+                       if (Report.Errors > 0)
+                               return false;
 
-                       //
-                       // Add Win32 resources
-                       //
+                       if (timestamps)
+                               stopwatch = Stopwatch.StartNew ();
+                       
+                       assembly.Save ();
 
-                       if (win32ResourceFile != null) {
-                               try {
-                                       CodeGen.Assembly.Builder.DefineUnmanagedResource (win32ResourceFile);
-                               } catch (ArgumentException) {
-                                       Report.RuntimeMissingSupport (Location.Null, "resource embeding");
-                               }
-                       } else {
-                               CodeGen.Assembly.Builder.DefineVersionInfoResource ();
-                       }
+                       ShowTime ("Saving output assembly");
 
-                       if (win32IconFile != null) {
-                               MethodInfo define_icon = typeof (AssemblyBuilder).GetMethod ("DefineIconResource", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
-                               if (define_icon == null) {
-                                       Report.RuntimeMissingSupport (Location.Null, "resource embeding");
-                               } else {
-                                       define_icon.Invoke (CodeGen.Assembly.Builder, new object [] { win32IconFile });
-                               }
+                       if (RootContext.GenerateDebugInfo) {
+                               SymbolWriter.WriteSymbolFile ();
+                               ShowTime ("Saving debug symbols");
                        }
 
-                       if (Report.Errors > 0)
-                               return false;
-                       
-                       CodeGen.Save (output_file, want_debugging_support);
-                       if (timestamps) {
-                               ShowTime ("Saved output");
-                               ShowTotalTime ("Total");
-                       }
+                       ShowTotalTime ("Total");
 
                        Timer.ShowTimers ();
-                       
-                       if (Report.ExpectedError != 0) {
-                               if (Report.Errors == 0) {
-                                       Console.WriteLine ("Failed to report expected error " + Report.ExpectedError + ".\n" +
-                                               "No other errors reported.");
-                                       
-                                       Environment.Exit (2);
-                               } else {
-                                       Console.WriteLine ("Failed to report expected error " + Report.ExpectedError + ".\n" +
-                                               "However, other errors were reported.");
-                                       
-                                       Environment.Exit (1);
-                               }
-                               
-                               
-                               return false;
-                       }
 
-#if DEBUGME
-                       Console.WriteLine ("Size of strings held: " + DeclSpace.length);
-                       Console.WriteLine ("Size of strings short: " + DeclSpace.small);
-#endif
                        return (Report.Errors == 0);
                }
        }
 
-       class Resources
+       public class AssemblyResource : IEquatable<AssemblyResource>
        {
-               interface IResource
+               public AssemblyResource (string fileName, string name)
+                       : this (fileName, name, false)
                {
-                       void Emit ();
-                       string FileName { get; }
                }
 
-               class EmbededResource : IResource
+               public AssemblyResource (string fileName, string name, bool isPrivate)
                {
-#if GMCS_SOURCE
-                       string name;
-                       string file;
-                       ResourceAttributes attributes;
-
-                       public EmbededResource (string name, string file, bool isPrivate)
-                       {
-                               this.name = name;
-                               this.file = file;
-                               this.attributes = isPrivate ? ResourceAttributes.Private : ResourceAttributes.Public;
-                       }
-
-                       public void Emit ()
-                       {
-                               RootContext.ToplevelTypes.Builder.DefineManifestResource (
-                                       name, new FileStream (file, FileMode.Open, FileAccess.Read), attributes);
-                       }
-
-                       public string FileName {
-                               get { return file; }
-                       }
-#else
-                       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];
-                               }
-                       }
-#endif
-               }
-
-               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;
-                               }
-                       }
+                       FileName = fileName;
+                       Name = name;
+                       Attributes = isPrivate ? ResourceAttributes.Private : ResourceAttributes.Public;
                }
 
+               public ResourceAttributes Attributes { get; private set; }
+               public string Name { get; private set; }
+               public string FileName { get; private set; }
+               public bool IsEmbeded { get; set; }
 
-               IDictionary embedded_resources = new HybridDictionary ();
-
-               public void Add (bool embeded, string file, string name)
-               {
-                       Add (embeded, file, name, false);
-               }
+               #region IEquatable<AssemblyResource> Members
 
-               public void Add (bool embeded, string file, string name, bool isPrivate)
+               public bool Equals (AssemblyResource other)
                {
-                       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);
+                       return Name == other.Name;
                }
 
-               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 ();
-                       }
-               }
+               #endregion
        }
 
        //
@@ -2017,16 +1855,14 @@ namespace Mono.CSharp
        public class CompilerCallableEntryPoint : MarshalByRefObject {
                public static bool InvokeCompiler (string [] args, TextWriter error)
                {
-                       Report.Stderr = error;
                        try {
-                               Driver d = Driver.Create (args, true);
+                               StreamReportPrinter srp = new StreamReportPrinter (error);
+                               Driver d = Driver.Create (args, true, srp);
                                if (d == null)
                                        return false;
 
-                               return d.Compile () && Report.Errors == 0;
-                       }
-                       finally {
-                               Report.Stderr = Console.Error;
+                               return d.Compile () && srp.ErrorsCount == 0;
+                       } finally {
                                Reset ();
                        }
                }
@@ -2050,20 +1886,28 @@ namespace Mono.CSharp
                public static void Reset (bool full_flag)
                {
                        Driver.Reset ();
-                       RootContext.Reset (full_flag);
+                       CSharpParser.yacc_verbose_flag = 0;
                        Location.Reset ();
-                       Report.Reset ();
-                       TypeManager.Reset ();
-                       PredefinedAttributes.Reset ();
-                       TypeHandle.Reset ();
 
-                       if (full_flag)
-                               GlobalRootNamespace.Reset ();
+                       if (!full_flag)
+                               return;
+
+                       RootContext.Reset (full_flag);
+                       TypeManager.Reset ();
+                       ArrayContainer.Reset ();
+                       ReferenceContainer.Reset ();
+                       PointerContainer.Reset ();
+                       Parameter.Reset ();
+
+                       Unary.Reset ();
+                       UnaryMutator.Reset ();
+                       Binary.Reset ();
+                       ConstantFold.Reset ();
+                       CastFromDecimal.Reset ();
+                       StringConcat.Reset ();
                        
                        NamespaceEntry.Reset ();
-                       CodeGen.Reset ();
                        Attribute.Reset ();
-                       AttributeTester.Reset ();
                        AnonymousTypeClass.Reset ();
                        AnonymousMethodBody.Reset ();
                        AnonymousMethodStorey.Reset ();
@@ -2073,6 +1917,5 @@ namespace Mono.CSharp
                        Convert.Reset ();
                        TypeInfo.Reset ();
                }
-
        }
 }