[asp.net] FormsAuthenticationTicket.FromByteArray stops early if it is passed a null...
[mono.git] / mcs / mcs / driver.cs
index dbc7302a2400467069aa954436872b03fc2d7614..ad0eae26bf0809e0cd02d225c7b41d5b33cb3536 100644 (file)
@@ -29,15 +29,8 @@ namespace Mono.CSharp
        {
                string first_source;
 
-               bool timestamps;
                internal int fatal_errors;
                
-               //
-               // Last time we took the time
-               //
-               Stopwatch stopwatch;
-               DateTime first_time;
-
                internal readonly CompilerContext ctx;
 
                static readonly char[] argument_value_separator = new char [] { ';', ',' };
@@ -47,11 +40,11 @@ namespace Mono.CSharp
                        this.ctx = ctx;
                }
 
-               public static Driver Create (string[] args, bool require_files, ReportPrinter printer)
+               public static Driver Create (string[] args, bool require_files, Func<string [], int, int> unknown_option_parser, ReportPrinter printer)
                {
                        Driver d = new Driver (new CompilerContext (new Report (printer)));
 
-                       if (!d.ParseArguments (args, require_files))
+                       if (!d.ParseArguments (args, require_files, unknown_option_parser))
                                return null;
 
                        return d;
@@ -60,32 +53,7 @@ namespace Mono.CSharp
                Report Report {
                        get { return ctx.Report; }
                }
-
-               void ShowTime (string msg)
-               {
-                       if (!timestamps)
-                               return;
-
-                       stopwatch.Stop ();
-
-                       Console.WriteLine ("{0,5}ms {1}", stopwatch.ElapsedMilliseconds, msg);
-
-                       stopwatch = Stopwatch.StartNew ();
-               }
-
-               void ShowTotalTime (string msg)
-               {
-                       if (!timestamps)
-                               return;
-
-                       DateTime now = DateTime.Now;
-                       TimeSpan span = now - first_time;
-
-                       Console.WriteLine (
-                               "[{0:00}:{1:000}] {2}",
-                               (int) span.TotalSeconds, span.Milliseconds, msg);
-               }              
-              
+       
                void tokenize_file (CompilationUnit file, CompilerContext ctx)
                {
                        Stream input;
@@ -152,6 +120,7 @@ namespace Mono.CSharp
                                "   --fatal[=COUNT]    Makes errors after COUNT fatal\n" +
                                "   --lint             Enhanced warnings\n" +
                                "   --parse            Only parses the source file\n" +
+                               "   --runtime:VERSION  Sets mscorlib.dll metadata version: v1, v2, v4\n" +
                                "   --stacktrace       Shows stack trace at error location\n" +
                                "   --timestamp        Displays time stamps of various compiler events\n" +
                                "   -v                 Verbose parsing (for debugging the parser)\n" + 
@@ -161,17 +130,18 @@ namespace Mono.CSharp
                static void Usage ()
                {
                        Console.WriteLine (
-                               "Mono C# compiler, Copyright 2001 - 2008 Novell, Inc.\n" +
+                               "Mono C# compiler, Copyright 2001 - 2011 Novell, Inc.\n" +
                                "mcs [options] source-files\n" +
                                "   --about              About the Mono C# compiler\n" +
                                "   -addmodule:M1[,Mn]   Adds the module to the generated assembly\n" + 
                                "   -checked[+|-]        Sets default aritmetic overflow context\n" +
-                               "   -codepage:ID         Sets code page to the one in ID (number, utf8, reset)\n" +
                                "   -clscheck[+|-]       Disables CLS Compliance verifications\n" +
+                               "   -codepage:ID         Sets code page to the one in ID (number, utf8, reset)\n" +
                                "   -define:S1[;S2]      Defines one or more conditional symbols (short: -d)\n" +
                                "   -debug[+|-], -g      Generate debugging information\n" + 
                                "   -delaysign[+|-]      Only insert the public key into the assembly (no signing)\n" +
                                "   -doc:FILE            Process documentation comments to XML file\n" + 
+                               "   -fullpaths           Any issued error or warning uses absolute file path\n" +
                                "   -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" +
@@ -183,21 +153,21 @@ namespace Mono.CSharp
                                "   -nowarn:W1[,Wn]      Suppress one or more compiler warnings\n" + 
                                "   -optimize[+|-]       Enables advanced compiler optimizations (short: -o)\n" + 
                                "   -out:FILE            Specifies output assembly name\n" +
-#if !SMCS_SOURCE
                                "   -pkg:P1[,Pn]         References packages P1..Pn\n" + 
-#endif
                                "   -platform:ARCH       Specifies the target platform of the output assembly\n" +
                                "                        ARCH can be one of: anycpu, x86, x64 or itanium\n" +
                                "   -recurse:SPEC        Recursively compiles files according to SPEC pattern\n" + 
                                "   -reference:A1[,An]   Imports metadata from the specified assembly (short: -r)\n" +
-                               "   -reference:ALIAS=A   Imports metadata using specified extern alias (short: -r)\n" +                         
+                               "   -reference:ALIAS=A   Imports metadata using specified extern alias (short: -r)\n" +
+                               "   -sdk:VERSION         Specifies SDK version of referenced assemlies\n" +
+                               "                        VERSION can be one of: 2 (default), 4\n" +
                                "   -target:KIND         Specifies the format of the output assembly (short: -t)\n" +
                                "                        KIND can be one of: exe, winexe, library, module\n" +
                                "   -unsafe[+|-]         Allows to compile code which uses unsafe keyword\n" +
                                "   -warnaserror[+|-]    Treats all warnings as errors\n" +
                                "   -warnaserror[+|-]:W1[,Wn] Treats one or more compiler warnings as errors\n" +
                                "   -warn:0-4            Sets warning level, the default is 4 (short -w:)\n" +
-                               "   -help2               Shows internal compiler options\n" + 
+                               "   -helpinternal        Shows internal and advanced compiler options\n" + 
                                "\n" +
                                "Resources:\n" +
                                "   -linkresource:FILE[,ID] Links FILE as a resource (short: -linkres)\n" +
@@ -216,7 +186,7 @@ namespace Mono.CSharp
                static void About ()
                {
                        Console.WriteLine (
-                               "The Mono C# compiler is Copyright 2001-2008, Novell, Inc.\n\n" +
+                               "The Mono C# compiler is Copyright 2001-2011, Novell, Inc.\n\n" +
                                "The compiler source code is released under the terms of the \n"+
                                "MIT X11 or GNU GPL licenses\n\n" +
 
@@ -231,7 +201,7 @@ namespace Mono.CSharp
                {
                        Location.InEmacs = Environment.GetEnvironmentVariable ("EMACS") == "t";
                        var crp = new ConsoleReportPrinter ();
-                       Driver d = Driver.Create (args, true, crp);
+                       Driver d = Driver.Create (args, true, null, crp);
                        if (d == null)
                                return 1;
 
@@ -338,7 +308,7 @@ namespace Mono.CSharp
                        Location.AddFile (Report, f);
                }
 
-               bool ParseArguments (string[] args, bool require_files)
+               bool ParseArguments (string[] args, bool require_files, Func<string [], int, int> unknown_option_parser)
                {
                        List<string> response_file_list = null;
                        bool parsing_options = true;
@@ -390,6 +360,14 @@ namespace Mono.CSharp
                                                if (CSCParseOption (csc_opt, ref args))
                                                        continue;
 
+                                               if (unknown_option_parser != null){
+                                                       var ret = unknown_option_parser (args, i);
+                                                       if (ret != -1){
+                                                               i = ret;
+                                                               return true;
+                                                       }
+                                               }
+                                               
                                                Error_WrongOption (arg);
                                                return false;
                                        }
@@ -506,7 +484,7 @@ namespace Mono.CSharp
 
                static void Version ()
                {
-                       string version = Assembly.GetExecutingAssembly ().GetName ().Version.ToString ();
+                       string version = System.Reflection.Assembly.GetExecutingAssembly ().GetName ().Version.ToString ();
                        Console.WriteLine ("Mono C# compiler version {0}", version);
                        Environment.Exit (0);
                }
@@ -692,7 +670,7 @@ namespace Mono.CSharp
                                }
                                Report.SetIgnoreWarning (warn);
                                return true;
-                               
+
                        case "--wlevel":
                                Report.Warning (-29, 1, "Compatibility: Use -warn:LEVEL instead of --wlevel LEVEL");
                                if ((i + 1) >= args.Length){
@@ -733,7 +711,7 @@ namespace Mono.CSharp
                                return true;
                                
                        case "--timestamp":
-                               timestamps = true;
+                               RootContext.Timestamps = true;
                                return true;
 
                        case "--debug": case "-g":
@@ -755,13 +733,32 @@ namespace Mono.CSharp
                                                fatal_errors = 1;
                                        return true;
                                }
+                               if (arg.StartsWith ("--runtime:", StringComparison.Ordinal)) {
+                                       string version = arg.Substring (10);
+
+                                       switch (version) {
+                                       case "v1":
+                                       case "V1":
+                                               RootContext.StdLibRuntimeVersion = RuntimeVersion.v1;
+                                               break;
+                                       case "v2":
+                                       case "V2":
+                                               RootContext.StdLibRuntimeVersion = RuntimeVersion.v2;
+                                               return true;
+                                       case "v4":
+                                       case "V4":
+                                               RootContext.StdLibRuntimeVersion = RuntimeVersion.v4;
+                                               return true;
+                                       }
+                                       return true;
+                               }
+
                                break;
                        }
 
                        return false;
                }
 
-#if !SMCS_SOURCE
                public static string GetPackageFlags (string packages, bool fatal, Report report)
                {
                        ProcessStartInfo pi = new ProcessStartInfo ();
@@ -798,7 +795,6 @@ namespace Mono.CSharp
 
                        return pkgout;
                }
-#endif
 
                //
                // This parses the -arg and /arg options to the compiler, even if the strings
@@ -900,7 +896,7 @@ namespace Mono.CSharp
                                //
                                Console.WriteLine ("To file bug reports, please visit: http://www.mono-project.com/Bugs");
                                return true;
-#if !SMCS_SOURCE
+
                        case "/pkg": {
                                string packages;
 
@@ -919,13 +915,13 @@ namespace Mono.CSharp
                                
                                return true;
                        }
-#endif
+
                        case "/linkres":
                        case "/linkresource":
                        case "/res":
                        case "/resource":
                                AssemblyResource res = null;                    
-                               string[] s = value.Split (argument_value_separator);
+                               string[] s = value.Split (argument_value_separator, StringSplitOptions.RemoveEmptyEntries);
                                switch (s.Length) {
                                case 1:
                                        if (s[0].Length == 0)
@@ -1110,18 +1106,21 @@ namespace Mono.CSharp
                                return true;
 
                        case "/warn":
+                               if (value.Length == 0) {
+                                       Error_RequiresArgument (option);
+                                       break;
+                               }
+
                                SetWarningLevel (value);
                                return true;
 
                        case "/nowarn": {
-                               string [] warns;
-
                                if (value.Length == 0){
-                                       Report.Error (5, "/nowarn requires an argument");
-                                       Environment.Exit (1);
+                                       Error_RequiresArgument (option);
+                                       break;
                                }
 
-                               warns = value.Split (argument_value_separator);
+                               var warns = value.Split (argument_value_separator);
                                foreach (string wc in warns){
                                        try {
                                                if (wc.Trim ().Length == 0)
@@ -1144,6 +1143,11 @@ namespace Mono.CSharp
                                return true;
 
                        case "/platform":
+                               if (value.Length == 0) {
+                                       Error_RequiresArgument (option);
+                                       break;
+                               }
+
                                switch (value.ToLower (CultureInfo.InvariantCulture)) {
                                case "anycpu":
                                        RootContext.Platform = Platform.AnyCPU;
@@ -1164,12 +1168,37 @@ namespace Mono.CSharp
 
                                return true;
 
+                       case "/sdk":
+                               if (value.Length == 0) {
+                                       Error_RequiresArgument (option);
+                                       break;
+                               }
+
+                               switch (value.ToLowerInvariant ()) {
+                                       case "2":
+                                               RootContext.SdkVersion = SdkVersion.v2;
+                                               break;
+                                       case "4":
+                                               RootContext.SdkVersion = SdkVersion.v4;
+                                               break;
+                                       default:
+                                               Report.Error (-26, "Invalid sdk version name");
+                                               break;
+                               }
+
+                               return true;
+
                                // We just ignore this.
                        case "/errorreport":
                        case "/filealign":
+                               if (value.Length == 0) {
+                                       Error_RequiresArgument (option);
+                                       break;
+                               }
+
                                return true;
                                
-                       case "/help2":
+                       case "/helpinternal":
                                OtherFlags ();
                                Environment.Exit(0);
                                return true;
@@ -1183,8 +1212,8 @@ namespace Mono.CSharp
                        case "/main":
                        case "/m":
                                if (value.Length == 0){
-                                       Report.Error (5, arg + " requires an argument");                                        
-                                       Environment.Exit (1);
+                                       Error_RequiresArgument (option);
+                                       break;
                                }
                                RootContext.MainClass = value;
                                return true;
@@ -1199,6 +1228,7 @@ namespace Mono.CSharp
                                return true;
 
                        case "/fullpaths":
+                               RootContext.ShowFullPaths = true;
                                return true;
 
                        case "/keyfile":
@@ -1209,11 +1239,13 @@ namespace Mono.CSharp
 
                                RootContext.StrongNameKeyFile = value;
                                return true;
+
                        case "/keycontainer":
-                               if (value == String.Empty) {
-                                       Report.Error (5, arg + " requires an argument");
-                                       Environment.Exit (1);
+                               if (value.Length == 0) {
+                                       Error_RequiresArgument (option);
+                                       break;
                                }
+
                                RootContext.StrongNameKeyContainer = value;
                                return true;
                        case "/delaysign+":
@@ -1225,6 +1257,11 @@ namespace Mono.CSharp
                                return true;
 
                        case "/langversion":
+                               if (value.Length == 0) {
+                                       Error_RequiresArgument (option);
+                                       break;
+                               }
+
                                switch (value.ToLowerInvariant ()) {
                                case "iso-1":
                                        RootContext.Version = LanguageVersion.ISO_1;
@@ -1248,6 +1285,11 @@ namespace Mono.CSharp
                                return true;
 
                        case "/codepage":
+                               if (value.Length == 0) {
+                                       Error_RequiresArgument (option);
+                                       break;
+                               }
+
                                switch (value) {
                                case "utf8":
                                        RootContext.Encoding = new UTF8Encoding();
@@ -1264,9 +1306,12 @@ namespace Mono.CSharp
                                        break;
                                }
                                return true;
+
+                       default:
+                               return false;
                        }
 
-                       return false;
+                       return true;
                }
 
                void Error_WrongOption (string option)
@@ -1279,6 +1324,11 @@ namespace Mono.CSharp
                        Report.Error (2005, "Missing file specification for `{0}' option", option);
                }
 
+               void Error_RequiresArgument (string option)
+               {
+                       Report.Error (2006, "Missing argument for `{0}' option", option);
+               }
+
                static string [] AddArgs (string [] args, string [] extra_args)
                {
                        string [] new_args;
@@ -1366,16 +1416,16 @@ namespace Mono.CSharp
                //
                public bool Compile ()
                {
+                       TimeReporter tr = new TimeReporter (RootContext.Timestamps);
+                       ctx.TimeReporter = tr;
+                       tr.StartTotal ();
+
                        var module = new ModuleContainer (ctx);
                        RootContext.ToplevelTypes = module;
 
-                       if (timestamps) {
-                               stopwatch = Stopwatch.StartNew ();
-                               first_time = DateTime.Now;
-                       }
-
+                       tr.Start (TimeReporter.TimerType.ParseTotal);
                        Parse (module);
-                       ShowTime ("Parsing source files");
+                       tr.Stop (TimeReporter.TimerType.ParseTotal);
 
                        if (Report.Errors > 0)
                                return false;
@@ -1409,13 +1459,36 @@ namespace Mono.CSharp
                                output_file_name = Path.GetFileName (output_file);
                        }
 
-                       //
-                       // Load assemblies required
-                       //
-                       if (timestamps)
-                               stopwatch = Stopwatch.StartNew ();
+#if STATIC
+                       var importer = new StaticImporter ();
+                       var references_loader = new StaticLoader (importer, ctx);
+
+                       tr.Start (TimeReporter.TimerType.AssemblyBuilderSetup);
+                       var assembly = new AssemblyDefinitionStatic (module, references_loader, output_file_name, output_file);
+                       assembly.Create (references_loader.Domain);
+                       tr.Stop (TimeReporter.TimerType.AssemblyBuilderSetup);
+
+                       // Create compiler types first even before any referenced
+                       // assembly is loaded to allow forward referenced types from
+                       // loaded assembly into compiled builder to be resolved
+                       // correctly
+                       tr.Start (TimeReporter.TimerType.CreateTypeTotal);
+                       module.CreateType ();
+                       importer.AddCompiledAssembly (assembly);
+                       tr.Stop (TimeReporter.TimerType.CreateTypeTotal);
+
+                       references_loader.LoadReferences (module);
+
+                       tr.Start (TimeReporter.TimerType.PredefinedTypesInit);
+                       if (!ctx.BuildinTypes.CheckDefinitions (module))
+                               return false;
 
-                       var assembly = module.MakeExecutable (output_file_name, output_file);
+                       tr.Stop (TimeReporter.TimerType.PredefinedTypesInit);
+
+                       references_loader.LoadModules (assembly, module.GlobalRootNamespace);
+#else
+                       var assembly = new AssemblyDefinitionDynamic (module, output_file_name, output_file);
+                       module.SetDeclaringAssembly (assembly);
 
                        var importer = new ReflectionImporter (ctx.BuildinTypes);
                        assembly.Importer = importer;
@@ -1423,27 +1496,24 @@ namespace Mono.CSharp
                        var loader = new DynamicLoader (importer, ctx);
                        loader.LoadReferences (module);
 
-                       ShowTime ("Imporing referenced assemblies");
-
                        if (!ctx.BuildinTypes.CheckDefinitions (module))
                                return false;
 
-                       ShowTime ("Initializing predefined types");
-
                        if (!assembly.Create (AppDomain.CurrentDomain, AssemblyBuilderAccess.Save))
                                return false;
 
-                       loader.LoadModules (assembly);
+                       module.CreateType ();
 
+                       loader.LoadModules (assembly, module.GlobalRootNamespace);
+#endif
+                       tr.Start (TimeReporter.TimerType.ModuleDefinitionTotal);
                        module.Define ();
-
-                       ShowTime ("Types definition");
+                       tr.Stop (TimeReporter.TimerType.ModuleDefinitionTotal);
 
                        if (Report.Errors > 0)
                                return false;
 
-                       if (Report.Errors == 0 &&
-                               RootContext.Documentation != null &&
+                       if (RootContext.Documentation != null &&
                                !RootContext.Documentation.OutputDocComment (
                                        output_file, Report))
                                return false;
@@ -1451,7 +1521,9 @@ namespace Mono.CSharp
                        //
                        // Verify using aliases now
                        //
+                       tr.Start (TimeReporter.TimerType.UsingVerification);
                        NamespaceEntry.VerifyAllUsing ();
+                       tr.Stop (TimeReporter.TimerType.UsingVerification);
                        
                        if (Report.Errors > 0){
                                return false;
@@ -1461,44 +1533,34 @@ namespace Mono.CSharp
                        
                        if (Report.Errors > 0)
                                return false;
-                       
-                       //
-                       // The code generator
-                       //
-                       if (timestamps)
-                               stopwatch = Stopwatch.StartNew ();
 
-                       assembly.Emit ();
 
-                       ShowTime ("Resolving and emitting members blocks");
+                       tr.Start (TimeReporter.TimerType.EmitTotal);
+                       assembly.Emit ();
+                       tr.Stop (TimeReporter.TimerType.EmitTotal);
 
                        if (Report.Errors > 0){
                                return false;
                        }
 
+                       tr.Start (TimeReporter.TimerType.CloseTypes);
                        module.CloseType ();
+                       tr.Stop (TimeReporter.TimerType.CloseTypes);
 
-                       ShowTime ("Closing types");
-
-                       if (timestamps)
-                               stopwatch = Stopwatch.StartNew ();
-
+                       tr.Start (TimeReporter.TimerType.Resouces);
                        assembly.EmbedResources ();
-                       ShowTime ("Embedding resources");
+                       tr.Stop (TimeReporter.TimerType.Resouces);
 
                        if (Report.Errors > 0)
                                return false;
 
-                       if (timestamps)
-                               stopwatch = Stopwatch.StartNew ();
-                       
                        assembly.Save ();
 
-                       ShowTime ("Saving output assembly");
-
-                       ShowTotalTime ("Total");
-
-                       Timer.ShowTimers ();
+#if STATIC
+                       references_loader.Dispose ();
+#endif
+                       tr.StopTotal ();
+                       tr.ShowStats ();
 
                        return (Report.Errors == 0);
                }
@@ -1512,7 +1574,7 @@ namespace Mono.CSharp
                {
                        try {
                                StreamReportPrinter srp = new StreamReportPrinter (error);
-                               Driver d = Driver.Create (args, true, srp);
+                               Driver d = Driver.Create (args, true, null, srp);
                                if (d == null)
                                        return false;
 
@@ -1542,7 +1604,7 @@ namespace Mono.CSharp
                {
                        CSharpParser.yacc_verbose_flag = 0;
                        Location.Reset ();
-
+                       
                        if (!full_flag)
                                return;