Update
[mono.git] / mcs / mcs / driver.cs
old mode 100755 (executable)
new mode 100644 (file)
index 8252349..68a3935
@@ -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,7 +19,6 @@ namespace Mono.CSharp
        using System.Text;
        using System.Globalization;
        using System.Diagnostics;
-       using Mono.Languages;
 
        public enum Target {
                Library, Exe, Module, WinExe
@@ -50,9 +50,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;
                
@@ -64,7 +61,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)
@@ -106,12 +102,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)
@@ -183,7 +173,6 @@ namespace Mono.CSharp
                        SeekableStreamReader reader = new SeekableStreamReader (input, encoding, using_default_encoder);
                                
                        parser = new CSharpParser (reader, file, defines);
-                       parser.yacc_verbose = yacc_verbose;
                        try {
                                parser.parse ();
                        } catch (Exception ex) {
@@ -212,6 +201,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" +
@@ -223,6 +213,7 @@ 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" +
@@ -263,7 +254,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, Martin Baulig and Marek Safar");
+                               "The compiler was written by Miguel de Icaza, Ravi Pratap, Martin Baulig, Marek Safar, Raja Harinath, Raja Harinath, Raja Harinath, Raja Harinath, Raja Harinath, Raja Harinath, Raja Harinath, Raja Harinath, Raja R Harinath");
                        Environment.Exit (0);
                }
 
@@ -274,11 +265,9 @@ namespace Mono.CSharp
                        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 +294,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 +303,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 +631,7 @@ namespace Mono.CSharp
 
                static void SetupV2 ()
                {
-                       RootContext.V2 = true;
+                       RootContext.Version = LanguageVersion.Default;
                        defines.Add ("__V2__");
                }
                
@@ -661,12 +650,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":
@@ -1050,7 +1035,15 @@ namespace Mono.CSharp
                                if (embedded_resources == null)
                                        embedded_resources = new ArrayList ();
                                
-                               embedded_resources.Add (value);
+                               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 +1099,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 +1256,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;
 
@@ -1292,6 +1300,7 @@ namespace Mono.CSharp
                                }
                                return true;
                        }
+
                        //Report.Error (2007, String.Format ("Unrecognized command-line option: '{0}'", option));
                        //Environment.Exit (1);
                        return false;
@@ -1300,10 +1309,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;
                }
@@ -1406,6 +1428,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
                        //
@@ -1525,6 +1554,7 @@ namespace Mono.CSharp
                        if (timestamps)
                                ShowTime ("Resolving tree");
                        RootContext.ResolveTree ();
+
                        if (Report.Errors > 0)
                                return false;
                        if (timestamps)
@@ -1535,6 +1565,11 @@ namespace Mono.CSharp
                        RootContext.PopulateTypes ();
                        RootContext.DefineTypes ();
                        
+                       if (RootContext.Documentation != null &&
+                               !RootContext.Documentation.OutputDocComment (
+                                       output_file))
+                               return false;
+
                        TypeManager.InitCodeHelpers ();
 
                        //
@@ -1548,8 +1583,11 @@ namespace Mono.CSharp
                        
                        if (RootContext.VerifyClsCompliance) { 
                                CodeGen.Assembly.ResolveClsCompliance ();
-                               AttributeTester.VerifyModulesClsCompliance ();
-                               TypeManager.LoadAllImportedTypes ();
+                               if (CodeGen.Assembly.IsClsCompliant) {
+                                       AttributeTester.VerifyModulesClsCompliance ();
+                                       TypeManager.LoadAllImportedTypes ();
+                                       AttributeTester.VerifyTopLevelNameClsCompliance ();
+                               }
                        }
                        
                        //
@@ -1588,16 +1626,19 @@ namespace Mono.CSharp
 
                                if (ep == null) {
                                        if (RootContext.MainClass != null) {
-                                               object main_cont = RootContext.Tree.Decls [RootContext.MainClass];
+                                               DeclSpace main_cont = RootContext.Tree.Decls [RootContext.MainClass] as DeclSpace;
                                                if (main_cont == null) {
-                                                       Report.Error (Message.CS1555_Could_not_find_specified_for_Main_method, output_file, RootContext.MainClass); 
+                                                       Report.Error (1555, output_file, "Could not find '{0}' specified for Main method", RootContext.MainClass); 
                                                        return false;
                                                }
 
                                                if (!(main_cont is ClassOrStruct)) {
-                                                       Report.Error (Message.CS1556_specified_for_Main_method_must_be_a_valid_class_or_struct, output_file, RootContext.MainClass);
+                                                       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)
@@ -1652,7 +1693,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]))
@@ -1721,7 +1762,6 @@ namespace Mono.CSharp
 #endif
                        return (Report.Errors == 0);
                }
-
        }
 
        //