**** Merged r40732-r40872 from MCS ****
[mono.git] / mcs / gmcs / driver.cs
old mode 100755 (executable)
new mode 100644 (file)
index 8ded7ff..4d74fe1
@@ -6,6 +6,7 @@
 // Licensed under the terms of the GNU GPL
 //
 // (C) 2001, 2002, 2003 Ximian, Inc (http://www.ximian.com)
+// (C) 2004 Novell, Inc
 //
 
 namespace Mono.CSharp
@@ -18,6 +19,7 @@ namespace Mono.CSharp
        using System.IO;
        using System.Text;
        using System.Globalization;
+       using System.Xml;
 
        public enum Target {
                Library, Exe, Module, WinExe
@@ -49,9 +51,6 @@ namespace Mono.CSharp
                // Lookup paths
                static ArrayList link_paths;
 
-               // Whether we want Yacc to output its progress
-               static bool yacc_verbose = false;
-
                // Whether we want to only run the tokenizer
                static bool tokenize = false;
                
@@ -63,7 +62,6 @@ namespace Mono.CSharp
                static bool timestamps = false;
                static bool pause = false;
                static bool show_counters = false;
-               public static bool parser_verbose = false;
                
                //
                // Whether to load the initial config file (what CSC.RSP has by default)
@@ -105,12 +103,6 @@ namespace Mono.CSharp
                //
                static bool using_default_encoder = true;
 
-               //
-               // The system version we are using, if not specified on the commandline we
-               // will use the same version as corlib for looking for libraries in the GAC.
-               //
-               static string sys_version;
-
                public static void ShowTime (string msg)
                {
                        if (!timestamps)
@@ -182,7 +174,6 @@ namespace Mono.CSharp
                        SeekableStreamReader reader = new SeekableStreamReader (input, encoding, using_default_encoder);
                                
                        parser = new CSharpParser (reader, file, defines);
-                       parser.yacc_verbose_flag = yacc_verbose;
                        try {
                                parser.parse ();
                        } catch (Exception ex) {
@@ -211,6 +202,7 @@ namespace Mono.CSharp
                                "Mono C# compiler, (C) 2001 - 2003 Ximian, Inc.\n" +
                                "mcs [options] source-files\n" +
                                "   --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" +
@@ -222,11 +214,13 @@ namespace Mono.CSharp
                                "   -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 +
                                "   -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 +
                                "   -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" +
@@ -262,7 +256,7 @@ namespace Mono.CSharp
                                "For more information on Mono, visit the project Web site\n" +
                                "   http://www.go-mono.com\n\n" +
 
-                               "The compiler was written by Miguel de Icaza, Ravi Pratap and Martin Baulig");
+                               "The compiler was written by Miguel de Icaza, Ravi Pratap, Martin Baulig, Marek Safar, Raja R Harinath");
                        Environment.Exit (0);
                }
 
@@ -270,15 +264,13 @@ namespace Mono.CSharp
                
                public static int Main (string[] args)
                {
-                       RootContext.V2 = true;
+                       RootContext.Version = LanguageVersion.Default;
                        bool ok = MainDriver (args);
                        
                        if (ok && Report.Errors == 0) {
-                               Console.Write("Compilation succeeded");
                                if (Report.Warnings > 0) {
-                                       Console.Write(" - {0} warning(s)", Report.Warnings);
+                                       Console.WriteLine ("Compilation succeeded - {0} warning(s)", Report.Warnings);
                                }
-                               Console.WriteLine();
                                if (show_counters){
                                        Console.WriteLine ("Counter1: " + counter1);
                                        Console.WriteLine ("Counter2: " + counter2);
@@ -305,7 +297,7 @@ namespace Mono.CSharp
                                        a = Assembly.LoadFrom (assembly);
                                } else {
                                        string ass = assembly;
-                                       if (ass.EndsWith (".dll"))
+                                       if (ass.EndsWith (".dll") || ass.EndsWith (".exe"))
                                                ass = assembly.Substring (0, assembly.Length - 4);
                                        a = Assembly.Load (ass);
                                }
@@ -314,7 +306,7 @@ namespace Mono.CSharp
                        } catch (FileNotFoundException){
                                foreach (string dir in link_paths){
                                        string full_path = Path.Combine (dir, assembly);
-                                       if (!assembly.EndsWith (".dll"))
+                                       if (!assembly.EndsWith (".dll") && !assembly.EndsWith (".exe"))
                                                full_path += ".dll";
 
                                        try {
@@ -642,7 +634,7 @@ namespace Mono.CSharp
 
                static void SetupV2 ()
                {
-                       RootContext.V2 = true;
+                       RootContext.Version = LanguageVersion.Default;
                        defines.Add ("__V2__");
                }
                
@@ -661,12 +653,8 @@ namespace Mono.CSharp
                static bool UnixParseOption (string arg, ref string [] args, ref int i)
                {
                        switch (arg){
-                       case "-vv":
-                               parser_verbose = true;
-                               return true;
-                               
                        case "-v":
-                               yacc_verbose = true;
+                               CSharpParser.yacc_verbose_flag++;
                                return true;
 
                        case "--version":
@@ -963,7 +951,13 @@ namespace Mono.CSharp
 
                        case "/optimize":
                        case "/optimize+":
+                               RootContext.Optimize = true;
+                               return true;
+
                        case "/optimize-":
+                               RootContext.Optimize = false;
+                               return true;
+
                        case "/incremental":
                        case "/incremental+":
                        case "/incremental-":
@@ -1050,7 +1044,15 @@ namespace Mono.CSharp
                                if (embedded_resources == null)
                                        embedded_resources = new ArrayList ();
                                
+                               if (embedded_resources.Contains (value)) {
+                                       Report.Error (1508, String.Format ("The resource identifier '{0}' has already been used in this assembly.", value));
+                               }
+                               else if (value.IndexOf (',') != -1 && embedded_resources.Contains (value.Split (',')[1])) {
+                                       Report.Error (1508, String.Format ("The resource identifier '{0}' has already been used in this assembly.", value));
+                               }
+                               else {
                                embedded_resources.Add (value);
+                               }
                                return true;
                                
                        case "/recurse":
@@ -1106,10 +1108,10 @@ namespace Mono.CSharp
                        }
                        case "/doc": {
                                if (value == ""){
-                                       Report.Error (5, arg + " requires an argument");
+                                       Report.Error (2006, arg + " requires an argument");
                                        Environment.Exit (1);
                                }
-                               // TODO handle the /doc argument to generate xml doc
+                               RootContext.Documentation = new Documentation (value);
                                return true;
                        }
                        case "/lib": {
@@ -1263,9 +1265,24 @@ namespace Mono.CSharp
 
                        case "/v2":
                        case "/2":
+                               Console.WriteLine ("The compiler option -2 is obsolete. Please use /langversion instead");
                                SetupV2 ();
                                return true;
                                
+                       case "/langversion":
+                               switch (value.ToLower (CultureInfo.InvariantCulture)) {
+                                       case "iso-1":
+                                               RootContext.Version = LanguageVersion.ISO_1;
+                                               return true;
+
+                                       case "default":
+                                               SetupV2 ();
+                                               return true;
+                               }
+                               Report.Error (1617, "Invalid option '{0}' for /langversion; must be ISO-1 or Default", value);
+                               Environment.Exit (1);
+                               return false;
+
                        case "/codepage":
                                int cp = -1;
 
@@ -1300,10 +1317,23 @@ namespace Mono.CSharp
                static string [] AddArgs (string [] args, string [] extra_args)
                {
                        string [] new_args;
-
                        new_args = new string [extra_args.Length + args.Length];
-                       args.CopyTo (new_args, 0);
-                       extra_args.CopyTo (new_args, args.Length);
+
+                       // if args contains '--' we have to take that into account
+                       // split args into first half and second half based on '--'
+                       // and add the extra_args before --
+                       int split_position = Array.IndexOf (args, "--");
+                       if (split_position != -1)
+                       {
+                               Array.Copy (args, new_args, split_position);
+                               extra_args.CopyTo (new_args, split_position);
+                               Array.Copy (args, split_position, new_args, split_position + extra_args.Length, args.Length - split_position);
+                       }
+                       else
+                       {
+                               args.CopyTo (new_args, 0);
+                               extra_args.CopyTo (new_args, args.Length);
+                       }
 
                        return new_args;
                }
@@ -1323,8 +1353,6 @@ namespace Mono.CSharp
                        int i;
                        bool parsing_options = true;
 
-                       Console.WriteLine ("ALPHA SOFTWARE: Mono C# Compiler {0} for Generics",
-                                          Assembly.GetExecutingAssembly ().GetName ().Version.ToString ());
                        try {
                                encoding = Encoding.GetEncoding (28591);
                        } catch {
@@ -1408,6 +1436,13 @@ namespace Mono.CSharp
                        if (tokenize)
                                return true;
                        
+                       //
+                       // This will point to the NamespaceEntry of the last file that was parsed, and may
+                       // not be meaningful when resolving classes from other files.  So, reset it to prevent
+                       // silent bugs.
+                       //
+                       RootContext.Tree.Types.NamespaceEntry = null;
+
                        //
                        // If we are an exe, require a source file for the entry point
                        //
@@ -1527,6 +1562,7 @@ namespace Mono.CSharp
                        if (timestamps)
                                ShowTime ("Resolving tree");
                        RootContext.ResolveTree ();
+
                        if (Report.Errors > 0)
                                return false;
                        if (timestamps)
@@ -1536,6 +1572,11 @@ namespace Mono.CSharp
                        RootContext.PopulateTypes ();
                        RootContext.DefineTypes ();
                        
+                       if (RootContext.Documentation != null &&
+                               !RootContext.Documentation.OutputDocComment (
+                                       output_file))
+                               return false;
+
                        TypeManager.InitCodeHelpers ();
 
                        //
@@ -1549,8 +1590,11 @@ namespace Mono.CSharp
                        
                        if (RootContext.VerifyClsCompliance) { 
                                CodeGen.Assembly.ResolveClsCompliance ();
+                               if (CodeGen.Assembly.IsClsCompliant) {
                                AttributeTester.VerifyModulesClsCompliance ();
                                TypeManager.LoadAllImportedTypes ();
+                                       AttributeTester.VerifyTopLevelNameClsCompliance ();
+                               }
                        }
                        
                        //
@@ -1588,6 +1632,22 @@ namespace Mono.CSharp
                                MethodInfo ep = RootContext.EntryPoint;
 
                                if (ep == null) {
+                                       if (RootContext.MainClass != null) {
+                                               DeclSpace main_cont = RootContext.Tree.Decls [RootContext.MainClass] as DeclSpace;
+                                               if (main_cont == null) {
+                                                       Report.Error (1555, output_file, "Could not find '{0}' specified for Main method", RootContext.MainClass); 
+                                                       return false;
+                                               }
+
+                                               if (!(main_cont is ClassOrStruct)) {
+                                                       Report.Error (1556, output_file, "'{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 " + output_file +
                                                              " does not have an entry point defined");
@@ -1640,7 +1700,7 @@ namespace Mono.CSharp
                                                        margs [1] = spec.Substring (0, cp);
                                                } else {
                                                        margs [1] = spec;
-                                                       margs [0] = spec.Replace ('/','.').Replace ('\\', '.');
+                                                       margs [0] = Path.GetFileName (spec);
                                                }
 
                                                if (File.Exists ((string) margs [1]))
@@ -1709,7 +1769,6 @@ namespace Mono.CSharp
 #endif
                        return (Report.Errors == 0);
                }
-
        }
 
        //