Switch to compiler-tester
[mono.git] / mcs / gmcs / driver.cs
index 4d74fe1cddae5ed9814fb48b9de6ac95a1f6eb9c..d50bf534c9576b5457475aa5d73c6b534cd4f749 100644 (file)
@@ -68,8 +68,6 @@ namespace Mono.CSharp
                // 
                static bool load_default_config = true;
 
-               static Hashtable response_file_list;
-
                //
                // A list of resource files
                //
@@ -103,6 +101,24 @@ namespace Mono.CSharp
                //
                static bool using_default_encoder = true;
 
+
+               static public void Reset ()
+               {
+                       want_debugging_support = false;
+                       parse_only = false;
+                       timestamps = false;
+                       pause = false;
+                       show_counters = false;
+                       load_default_config = true;
+                       resources = embedded_resources = null;
+                       win32ResourceFile = win32IconFile = null;
+                       defines = null;
+                       output_file = null;
+                       encoding = null;
+                       using_default_encoder = true;
+                       first_source = null;
+               }
+
                public static void ShowTime (string msg)
                {
                        if (!timestamps)
@@ -174,6 +190,7 @@ namespace Mono.CSharp
                        SeekableStreamReader reader = new SeekableStreamReader (input, encoding, using_default_encoder);
                                
                        parser = new CSharpParser (reader, file, defines);
+                       parser.ErrorOutput = Report.Stderr;
                        try {
                                parser.parse ();
                        } catch (Exception ex) {
@@ -191,6 +208,7 @@ namespace Mono.CSharp
                                "   --parse            Only parses the source file\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" +
                                "   -2                 Enables experimental C# features\n" +
                                "   -v                 Verbose parsing (for debugging the parser)\n" + 
                                "   --mcs-debug X      Sets MCS debugging level to X\n");
@@ -204,26 +222,23 @@ namespace Mono.CSharp
                                "   --about            About the Mono C# compiler\n" +
                                "   -addmodule:MODULE  Adds the module to the generated assembly\n" + 
                                "   -checked[+|-]      Set default context to checked\n" +
-                               "   -codepage:ID       Sets code page to the one in ID\n" +
-                               "                      (number, `utf8' or `reset')\n" +
+                               "   -codepage:ID       Sets code page to the one in ID (number, utf8, reset)\n" +
                                "   -clscheck[+|-]     Disables CLS Compliance verifications" + Environment.NewLine +
                                "   -define:S1[;S2]    Defines one or more symbols (short: /d:)\n" +
-                               "   -debug[+|-]        Generate debugging information\n" + 
+                               "   -debug[+|-], -g    Generate debugging information\n" + 
                                "   -delaysign[+|-]    Only insert the public key into the assembly (no signing)\n" +
                                "   -doc:FILE          XML Documentation file to generate\n" + 
-                               "   -g                 Generate debugging information\n" +
                                "   -keycontainer:NAME The key pair container used to strongname the assembly\n" +
                                "   -keyfile:FILE      The strongname key file used to strongname the assembly\n" +
-                               "   -langversion:TEXT  Specifies language version modes: ISO-1 or Default" + Environment.NewLine +
+                               "   -langversion:TEXT  Specifies language version modes: ISO-1 or Default\n" + 
                                "   -lib:PATH1,PATH2   Adds the paths to the assembly link path\n" +
                                "   -main:class        Specified the class that contains the entry point\n" +
                                "   -noconfig[+|-]     Disables implicit references to assemblies\n" +
                                "   -nostdlib[+|-]     Does not load core libraries\n" +
                                "   -nowarn:W1[,W2]    Disables one or more warnings\n" + 
-                               "   -optimize[+|-]     Enables code optimalizations" + Environment.NewLine +
+                               "   -optimize[+|-]     Enables code optimalizations\n" + 
                                "   -out:FNAME         Specifies output file\n" +
                                "   -pkg:P1[,Pn]       References packages P1..Pn\n" + 
-                               "   --expect-error X   Expect that error X will be encountered\n" +
                                "   -recurse:SPEC      Recursively compiles the files in SPEC ([dir]/file)\n" + 
                                "   -reference:ASS     References the specified assembly (-r:ASS)\n" +
                                "   -target:KIND       Specifies the target (KIND is one of: exe, winexe,\n" +
@@ -262,7 +277,7 @@ namespace Mono.CSharp
 
                public static int counter1, counter2;
                
-               public static int Main (string[] args)
+       public static int Main (string[] args)
                {
                        RootContext.Version = LanguageVersion.Default;
                        bool ok = MainDriver (args);
@@ -451,18 +466,7 @@ namespace Mono.CSharp
                //
                static string GetSystemDir ()
                {
-                       Assembly [] assemblies = AppDomain.CurrentDomain.GetAssemblies ();
-
-                       foreach (Assembly a in assemblies){
-                               string codebase = a.Location;
-                                string fn = System.IO.Path.GetFileName (codebase);
-                               if (fn == "corlib.dll" || fn == "mscorlib.dll"){
-                                       return codebase.Substring (0, codebase.LastIndexOf (System.IO.Path.DirectorySeparatorChar));
-                               }
-                       }
-
-                       Report.Error (-15, "Can not compute my system path");
-                       return "";
+                       return Path.GetDirectoryName (typeof (object).Assembly.Location);
                }
 
                //
@@ -614,22 +618,13 @@ namespace Mono.CSharp
                                Report.Error (
                                        1900,
                                        "--wlevel requires a value from 0 to 4");
-                               Environment.Exit (1);
+                               return;
                        }
                        if (level < 0 || level > 4){
                                Report.Error (1900, "Warning level must be 0 to 4");
-                               Environment.Exit (1);
+                               return;
                        }
                        RootContext.WarningLevel = level;
-                       TestWarningConflict ();
-               }
-
-               static void TestWarningConflict ()
-               {
-                       if (RootContext.WarningLevel == 0 && Report.WarningsAreErrors) {
-                               Report.Error (1901, "Conflicting options specified: Warning level 0; Treat warnings as errors");
-                               Environment.Exit (1);
-                       }
                }
 
                static void SetupV2 ()
@@ -666,6 +661,7 @@ namespace Mono.CSharp
                                return true;
                                
                        case "--main": case "-m":
+                               Report.Warning (-29, "Compatibility: Use -main:CLASS instead of --main CLASS or -m CLASS");
                                if ((i + 1) >= args.Length){
                                        Usage ();
                                        Environment.Exit (1);
@@ -674,6 +670,7 @@ namespace Mono.CSharp
                                return true;
                                
                        case "--unsafe":
+                               Report.Warning (-29, "Compatibility: Use -unsafe instead of --unsafe");
                                RootContext.Unsafe = true;
                                return true;
                                
@@ -684,6 +681,7 @@ namespace Mono.CSharp
                                return true;
                                
                        case "--define":
+                               Report.Warning (-29, "Compatibility: Use -d:SYMBOL instead of --define SYMBOL");
                                if ((i + 1) >= args.Length){
                                        Usage ();
                                        Environment.Exit (1);
@@ -714,14 +712,16 @@ namespace Mono.CSharp
                                
                        case "-o": 
                        case "--output":
+                               Report.Warning (-29, "Compatibility: Use -out:FILE instead of --output FILE or -o FILE");
                                if ((i + 1) >= args.Length){
                                        Usage ();
                                        Environment.Exit (1);
                                }
                                SetOutputFile (args [++i]);
                                return true;
-                               
+
                        case "--checked":
+                               Report.Warning (-29, "Compatibility: Use -checked instead of --checked");
                                RootContext.Checked = true;
                                return true;
                                
@@ -731,6 +731,7 @@ namespace Mono.CSharp
                                
                        case "--linkresource":
                        case "--linkres":
+                               Report.Warning (-29, "Compatibility: Use -linkres:VALUE instead of --linkres VALUE");
                                if ((i + 1) >= args.Length){
                                        Usage ();
                                        Report.Error (5, "Missing argument to --linkres"); 
@@ -744,6 +745,7 @@ namespace Mono.CSharp
                                
                        case "--resource":
                        case "--res":
+                               Report.Warning (-29, "Compatibility: Use -res:VALUE instead of --res VALUE");
                                if ((i + 1) >= args.Length){
                                        Usage ();
                                        Report.Error (5, "Missing argument to --resource"); 
@@ -756,6 +758,7 @@ namespace Mono.CSharp
                                return true;
                                
                        case "--target":
+                               Report.Warning (-29, "Compatibility: Use -target:KIND instead of --target KIND");
                                if ((i + 1) >= args.Length){
                                        Environment.Exit (1);
                                        return true;
@@ -782,12 +785,12 @@ namespace Mono.CSharp
                                        break;
                                default:
                                        TargetUsage ();
-                                       Environment.Exit (1);
                                        break;
                                }
                                return true;
                                
                        case "-r":
+                               Report.Warning (-29, "Compatibility: Use -r:LIBRARY instead of -r library");
                                if ((i + 1) >= args.Length){
                                        Usage ();
                                        Environment.Exit (1);
@@ -797,6 +800,7 @@ namespace Mono.CSharp
                                return true;
                                
                        case "-L":
+                               Report.Warning (-29, "Compatibility: Use -lib:ARG instead of --L arg");
                                if ((i + 1) >= args.Length){
                                        Usage ();       
                                        Environment.Exit (1);
@@ -805,6 +809,7 @@ namespace Mono.CSharp
                                return true;
                                
                        case "--nostdlib":
+                               Report.Warning (-29, "Compatibility: Use -nostdlib instead of --nostdlib");
                                RootContext.StdLib = false;
                                return true;
                                
@@ -813,11 +818,12 @@ namespace Mono.CSharp
                                return true;
                                
                        case "--werror":
+                               Report.Warning (-29, "Compatibility: Use -warnaserror: option instead of --werror");
                                Report.WarningsAreErrors = true;
-                               TestWarningConflict();
                                return true;
                                
                        case "--nowarn":
+                               Report.Warning (-29, "Compatibility: Use -nowarn instead of --nowarn");
                                if ((i + 1) >= args.Length){
                                        Usage ();
                                        Environment.Exit (1);
@@ -834,6 +840,7 @@ namespace Mono.CSharp
                                return true;
                                
                        case "--wlevel":
+                               Report.Warning (-29, "Compatibility: Use -warn:LEVEL instead of --wlevel LEVEL");
                                if ((i + 1) >= args.Length){
                                        Report.Error (
                                                1900,
@@ -863,6 +870,7 @@ namespace Mono.CSharp
                                return true;
                                
                        case "--recurse":
+                               Report.Warning (-29, "Compatibility: Use -recurse:PATTERN option instead --recurse PATTERN");
                                if ((i + 1) >= args.Length){
                                        Report.Error (5, "--recurse requires an argument");
                                        Environment.Exit (1);
@@ -880,10 +888,12 @@ namespace Mono.CSharp
                                return true;
                                
                        case "--debug": case "-g":
+                               Report.Warning (-29, "Compatibility: Use -debug option instead of -g or --debug");
                                want_debugging_support = true;
                                return true;
                                
                        case "--noconfig":
+                               Report.Warning (-29, "Compatibility: Use -noconfig option instead of --noconfig");
                                load_default_config = false;
                                return true;
                        }
@@ -892,8 +902,8 @@ namespace Mono.CSharp
                }
 
                //
-               // Currently it is very basic option parsing, but eventually, this will
-               // be the complete option parser
+               // This parses the -arg and /arg options to the compiler, even if the strings
+               // in the following text use "/arg" on the strings.
                //
                static bool CSCParseOption (string option, ref string [] args, ref int i)
                {
@@ -936,7 +946,6 @@ namespace Mono.CSharp
 
                                default:
                                        TargetUsage ();
-                                       Environment.Exit (1);
                                        break;
                                }
                                return true;
@@ -980,6 +989,13 @@ namespace Mono.CSharp
                                return true;
                        }
 
+                       case "/bugreport":
+                               //
+                               // We should collect data, runtime, etc and store in the file specified
+                               //
+                               Console.WriteLine ("To file bug reports, please visit: http://www.mono-project.com/Bugs");
+                               return true;
+
                        case "/linkres":
                        case "/linkresource":
                                if (value == ""){
@@ -1166,7 +1182,6 @@ namespace Mono.CSharp
                        case "/warnaserror":
                        case "/warnaserror+":
                                Report.WarningsAreErrors = true;
-                               TestWarningConflict();
                                return true;
 
                        case "/warnaserror-":
@@ -1195,7 +1210,6 @@ namespace Mono.CSharp
                                                Report.SetIgnoreWarning (warn);
                                        } catch {
                                                Report.Error (1904, String.Format("'{0}' is not a valid warning number", wc));
-                                               Environment.Exit (1);
                                        }
                                }
                                return true;
@@ -1280,8 +1294,7 @@ namespace Mono.CSharp
                                                return true;
                                }
                                Report.Error (1617, "Invalid option '{0}' for /langversion; must be ISO-1 or Default", value);
-                               Environment.Exit (1);
-                               return false;
+                               return true;
 
                        case "/codepage":
                                int cp = -1;
@@ -1305,7 +1318,6 @@ namespace Mono.CSharp
                                        using_default_encoder = false;
                                } catch {
                                        Report.Error (2016, String.Format("Code page '{0}' is invalid or not installed", cp));
-                                       Environment.Exit (1);
                                }
                                return true;
                        }
@@ -1374,6 +1386,8 @@ namespace Mono.CSharp
                        // path.
                        //
 
+                       Hashtable response_file_list = null;
+
                        for (i = 0; i < args.Length; i++){
                                string arg = args [i];
                                if (arg == "")
@@ -1468,8 +1482,6 @@ namespace Mono.CSharp
                        if (parse_only)
                                return true;
                        
-                       Tokenizer.Cleanup ();
-                       
                        //
                        // Load Core Library for default compilation
                        //
@@ -1511,12 +1523,13 @@ namespace Mono.CSharp
                                        output_file = first_source + RootContext.TargetExt;
                        }
 
-                       CodeGen.Init (output_file, output_file, want_debugging_support);
+                       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.Error (0, new Location (-1), "Cannot use /target:module on this runtime: try the Mono runtime instead.");
+                                       Report.RuntimeMissingSupport (Location.Null, "/target:module");
                                        Environment.Exit (1);
                                }
 
@@ -1529,7 +1542,7 @@ namespace Mono.CSharp
                        if (modules.Count > 0) {
                                MethodInfo adder_method = typeof (AssemblyBuilder).GetMethod ("AddModule", BindingFlags.Instance|BindingFlags.NonPublic);
                                if (adder_method == null) {
-                                       Report.Error (0, new Location (-1), "Cannot use /addmodule on this runtime: Try the Mono runtime instead.");
+                                       Report.RuntimeMissingSupport (Location.Null, "/addmodule");
                                        Environment.Exit (1);
                                }
 
@@ -1556,6 +1569,8 @@ namespace Mono.CSharp
                        if (timestamps)
                                ShowTime ("   Core Types done");
 
+                       CodeGen.Module.ResolveAttributes ();
+
                        //
                        // The second pass of the compiler
                        //
@@ -1570,6 +1585,9 @@ namespace Mono.CSharp
                        if (!RootContext.StdLib)
                                RootContext.BootCorlib_PopulateCoreTypes ();
                        RootContext.PopulateTypes ();
+
+                       TypeManager.InitCodeHelpers ();
+
                        RootContext.DefineTypes ();
                        
                        if (RootContext.Documentation != null &&
@@ -1577,8 +1595,6 @@ namespace Mono.CSharp
                                        output_file))
                                return false;
 
-                       TypeManager.InitCodeHelpers ();
-
                        //
                        // Verify using aliases now
                        //
@@ -1588,7 +1604,7 @@ namespace Mono.CSharp
                                return false;
                        }
                        
-                       if (RootContext.VerifyClsCompliance) { 
+                       if (RootContext.VerifyClsCompliance) {
                                CodeGen.Assembly.ResolveClsCompliance ();
                                if (CodeGen.Assembly.IsClsCompliant) {
                                AttributeTester.VerifyModulesClsCompliance ();
@@ -1596,6 +1612,8 @@ namespace Mono.CSharp
                                        AttributeTester.VerifyTopLevelNameClsCompliance ();
                                }
                        }
+                       if (Report.Errors > 0)
+                               return false;
                        
                        //
                        // The code generator
@@ -1633,7 +1651,7 @@ namespace Mono.CSharp
 
                                if (ep == null) {
                                        if (RootContext.MainClass != null) {
-                                               DeclSpace main_cont = RootContext.Tree.Decls [RootContext.MainClass] as DeclSpace;
+                                               DeclSpace main_cont = RootContext.Tree.GetDecl (MemberName.FromDotted (RootContext.MainClass));
                                                if (main_cont == null) {
                                                        Report.Error (1555, output_file, "Could not find '{0}' specified for Main method", RootContext.MainClass); 
                                                        return false;
@@ -1688,8 +1706,7 @@ namespace Mono.CSharp
                                        null, CallingConventions.Any, argst, null);
                                
                                if (embed_res == null) {
-                                       Report.Warning (0, new Location (-1),
-                                                       "Cannot embed resources on this runtime: try the Mono runtime instead.");
+                                       Report.RuntimeMissingSupport (Location.Null, "Resource embedding");
                                } else {
                                        foreach (string spec in embedded_resources) {
                                                int cp;
@@ -1775,18 +1792,28 @@ namespace Mono.CSharp
        // This is the only public entry point
        //
        public class CompilerCallableEntryPoint : MarshalByRefObject {
-               static bool used = false;
-               
-               public bool InvokeCompiler (string [] args)
+               public static bool InvokeCompiler (string [] args, TextWriter error)
                {
-                       if (used)
+                       Report.Stderr = error;
+                       try {
+                               return Driver.MainDriver (args) && Report.Errors == 0;
+                       }
+                       finally {
+                               Report.Stderr = Console.Error;
                                Reset ();
-                       bool ok = Driver.MainDriver (args);
-                       return ok && Report.Errors == 0;
+                       }
                }
-
-               public void Reset ()
+               
+               static void Reset ()
                {
+                       Driver.Reset ();
+                       Location.Reset ();
+                       RootContext.Reset ();
+                       Report.Reset ();
+                       TypeManager.Reset ();
+                       TypeHandle.Reset ();
+                       Namespace.Reset ();
+                       CodeGen.Reset ();
                }
        }
 }