Merge pull request #1949 from lewurm/fixtype
[mono.git] / mcs / mcs / settings.cs
index e3386ecf37b901f7ddb1af17da91caa7c790938d..13abbd67c67425faf5f9b3701068ea4c9a2aefc2 100644 (file)
@@ -28,9 +28,10 @@ namespace Mono.CSharp {
                V_3 = 3,
                V_4 = 4,
                V_5 = 5,
-               Future = 100,
+               V_6 = 6,
+               Experimental = 100,
 
-               Default = LanguageVersion.V_5,
+               Default = LanguageVersion.V_6,
        }
 
        public enum RuntimeVersion
@@ -47,7 +48,12 @@ namespace Mono.CSharp {
 
        public enum Platform
        {
-               AnyCPU, X86, X64, IA64
+               AnyCPU,
+               AnyCPU32Preferred,
+               Arm,
+               X86,
+               X64,
+               IA64
        }
 
        public class CompilerSettings
@@ -135,10 +141,18 @@ namespace Mono.CSharp {
 
                public bool GenerateDebugInfo;
 
-               // Compiler debug flags only
+               #region Compiler debug flags only
                public bool ParseOnly, TokenizeOnly, Timestamps;
                public int DebugFlags;
                public int VerboseParserFlag;
+               public int FatalCounter;
+               public bool Stacktrace;
+               public bool BreakOnInternalError;
+               #endregion
+
+               public List<string> GetResourceStrings;
+
+               public bool ShowFullPaths;
 
                //
                // Whether we are being linked against the standard libraries.
@@ -149,6 +163,10 @@ namespace Mono.CSharp {
 
                public RuntimeVersion StdLibRuntimeVersion;
 
+               public string RuntimeMetadataVersion;
+
+               public bool WriteMetadataOnly;
+
                readonly List<string> conditional_symbols;
 
                readonly List<SourceFile> source_files;
@@ -165,16 +183,13 @@ namespace Mono.CSharp {
                        Platform = Platform.AnyCPU;
                        Version = LanguageVersion.Default;
                        VerifyClsCompliance = true;
-                       Optimize = true;
                        Encoding = Encoding.UTF8;
                        LoadDefaultReferences = true;
                        StdLibRuntimeVersion = RuntimeVersion.v4;
                        WarningLevel = 4;
 
-                       if (Environment.OSVersion.Platform == PlatformID.Win32NT)
-                               TabSize = 4;
-                       else
-                               TabSize = 8;
+                       // Default to 1 or mdb files would be platform speficic
+                       TabSize = 1;
 
                        AssemblyReferences = new List<string> ();
                        AssemblyReferencesAliases = new List<Tuple<string, string>> ();
@@ -292,8 +307,8 @@ namespace Mono.CSharp {
                        UnknownOption
                }
 
-               static readonly char[] argument_value_separator = new char[] { ';', ',' };
-               static readonly char[] numeric_value_separator = new char[] { ';', ',', ' ' };
+               static readonly char[] argument_value_separator = { ';', ',' };
+               static readonly char[] numeric_value_separator = { ';', ',', ' ' };
 
                readonly TextWriter output;
                readonly Report report;
@@ -341,6 +356,17 @@ namespace Mono.CSharp {
                public CompilerSettings ParseArguments (string[] args)
                {
                        CompilerSettings settings = new CompilerSettings ();
+                       if (!ParseArguments (settings, args))
+                               return null;
+
+                       return settings;
+               }
+
+               public bool ParseArguments (CompilerSettings settings, string[] args)
+               {
+                       if (settings == null)
+                               throw new ArgumentNullException ("settings");
+
                        List<string> response_file_list = null;
                        bool parsing_options = true;
                        stop_argument = false;
@@ -360,7 +386,7 @@ namespace Mono.CSharp {
 
                                        if (response_file_list.Contains (response_file)) {
                                                report.Error (1515, "Response file `{0}' specified multiple times", response_file);
-                                               return null;
+                                               return false;
                                        }
 
                                        response_file_list.Add (response_file);
@@ -368,7 +394,7 @@ namespace Mono.CSharp {
                                        extra_args = LoadArgs (response_file);
                                        if (extra_args == null) {
                                                report.Error (2011, "Unable to open response file: " + response_file);
-                                               return null;
+                                               return false;
                                        }
 
                                        args = AddArgs (args, extra_args);
@@ -390,7 +416,7 @@ namespace Mono.CSharp {
                                                        continue;
                                                case ParseResult.Stop:
                                                        stop_argument = true;
-                                                       return settings;
+                                                       return true;
                                                case ParseResult.UnknownOption:
                                                        if (UnknownOptionHandler != null) {
                                                                var ret = UnknownOptionHandler (args, i);
@@ -424,11 +450,11 @@ namespace Mono.CSharp {
                                                        }
 
                                                        Error_WrongOption (arg);
-                                                       return null;
+                                                       return false;
 
                                                case ParseResult.Stop:
                                                        stop_argument = true;
-                                                       return settings;
+                                                       return true;
                                                }
                                        }
                                }
@@ -436,10 +462,7 @@ namespace Mono.CSharp {
                                ProcessSourceFiles (arg, false, settings.SourceFiles);
                        }
 
-                       if (report.Errors > 0)
-                               return null;
-
-                       return settings;
+                       return report.Errors == 0;
                }
 
                void ProcessSourceFiles (string spec, bool recurse, List<SourceFile> sourceFiles)
@@ -452,7 +475,7 @@ namespace Mono.CSharp {
                                return;
                        }
 
-                       string[] files = null;
+                       string[] files;
                        try {
                                files = Directory.GetFiles (path, pattern);
                        } catch (System.IO.DirectoryNotFoundException) {
@@ -556,36 +579,28 @@ namespace Mono.CSharp {
                        source_file_index.Add (path, unit.Index);
                }
 
-               void AddWarningAsError (string warningId, CompilerSettings settings)
+               public bool ProcessWarningsList (string text, Action<int> action)
                {
-                       int id;
-                       try {
-                               id = int.Parse (warningId);
-                       } catch {
-                               report.CheckWarningCode (warningId, Location.Null);
-                               return;
-                       }
-
-                       if (!report.CheckWarningCode (id, Location.Null))
-                               return;
-
-                       settings.AddWarningAsError (id);
-               }
+                       bool valid = true;
+                       foreach (string wid in text.Split (numeric_value_separator, StringSplitOptions.RemoveEmptyEntries)) {
+                               var warning = wid;
+                               if (warning.Length == 6 && warning [0] == 'C' && warning [1] == 'S')
+                                       warning = warning.Substring (2);
+
+                               int id;
+                               if (!int.TryParse (warning, NumberStyles.AllowLeadingWhite, CultureInfo.InvariantCulture, out id)) {
+                                       continue;
+                               }
 
-               void RemoveWarningAsError (string warningId, CompilerSettings settings)
-               {
-                       int id;
-                       try {
-                               id = int.Parse (warningId);
-                       } catch {
-                               report.CheckWarningCode (warningId, Location.Null);
-                               return;
+                               if (report.CheckWarningCode (id, Location.Null)) {
+                                       action (id);
+                               } else {
+                                       report.Error (1904, "`{0}' is not a valid warning number", wid);
+                                       valid = false;
+                               }
                        }
 
-                       if (!report.CheckWarningCode (id, Location.Null))
-                               return;
-
-                       settings.AddWarningOnly (id);
+                       return valid;
                }
 
                void Error_RequiresArgument (string option)
@@ -605,24 +620,7 @@ namespace Mono.CSharp {
 
                static bool IsExternAliasValid (string identifier)
                {
-                       if (identifier.Length == 0)
-                               return false;
-                       if (identifier[0] != '_' && !char.IsLetter (identifier[0]))
-                               return false;
-
-                       for (int i = 1; i < identifier.Length; i++) {
-                               char c = identifier[i];
-                               if (char.IsLetter (c) || char.IsDigit (c))
-                                       continue;
-
-                               UnicodeCategory category = char.GetUnicodeCategory (c);
-                               if (category != UnicodeCategory.Format || category != UnicodeCategory.NonSpacingMark ||
-                                               category != UnicodeCategory.SpacingCombiningMark ||
-                                               category != UnicodeCategory.ConnectorPunctuation)
-                                       return false;
-                       }
-
-                       return true;
+                       return Tokenizer.IsValidIdentifier (identifier);
                }
 
                static string[] LoadArgs (string file)
@@ -675,14 +673,16 @@ namespace Mono.CSharp {
                {
                        output.WriteLine (
                                "Other flags in the compiler\n" +
-                               "   --fatal[=COUNT]    Makes errors after COUNT fatal\n" +
+                               "   --fatal[=COUNT]    Makes error after COUNT fatal\n" +
                                "   --lint             Enhanced warnings\n" +
+                               "   --metadata-only    Produced assembly will contain metadata only\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" +
-                               "   --mcs-debug X      Sets MCS debugging level to X\n");
+                               "   --mcs-debug X      Sets MCS debugging level to X\n" +
+                               "   --break-on-ice     Breaks compilation on internal compiler error");
                }
 
                //
@@ -938,7 +938,7 @@ namespace Mono.CSharp {
                                return ParseResult.Success;
 
                        case "/debug":
-                               if (value == "full" || value == "pdbonly" || idx < 0) {
+                               if (value.Equals ("full", StringComparison.OrdinalIgnoreCase) || value.Equals ("pdbonly", StringComparison.OrdinalIgnoreCase) || idx < 0) {
                                        settings.GenerateDebugInfo = true;
                                        return ParseResult.Success;
                                }
@@ -988,8 +988,8 @@ namespace Mono.CSharp {
                                        settings.WarningsAreErrors = true;
                                        parser_settings.WarningsAreErrors = true;
                                } else {
-                                       foreach (string wid in value.Split (numeric_value_separator))
-                                               AddWarningAsError (wid, settings);
+                                       if (!ProcessWarningsList (value, settings.AddWarningAsError))
+                                               return ParseResult.Error;
                                }
                                return ParseResult.Success;
 
@@ -997,12 +997,13 @@ namespace Mono.CSharp {
                                if (value.Length == 0) {
                                        settings.WarningsAreErrors = false;
                                } else {
-                                       foreach (string wid in value.Split (numeric_value_separator))
-                                               RemoveWarningAsError (wid, settings);
+                                       if (!ProcessWarningsList (value, settings.AddWarningOnly))
+                                               return ParseResult.Error;
                                }
                                return ParseResult.Success;
 
                        case "/warn":
+                       case "/w":
                                if (value.Length == 0) {
                                        Error_RequiresArgument (option);
                                        return ParseResult.Error;
@@ -1012,28 +1013,15 @@ namespace Mono.CSharp {
                                return ParseResult.Success;
 
                        case "/nowarn":
-                                       if (value.Length == 0) {
-                                               Error_RequiresArgument (option);
-                                               return ParseResult.Error;
-                                       }
+                               if (value.Length == 0) {
+                                       Error_RequiresArgument (option);
+                                       return ParseResult.Error;
+                               }
 
-                                       var warns = value.Split (numeric_value_separator);
-                                       foreach (string wc in warns) {
-                                               try {
-                                                       if (wc.Trim ().Length == 0)
-                                                               continue;
+                               if (!ProcessWarningsList (value, settings.SetIgnoreWarning))
+                                       return ParseResult.Error;
 
-                                                       int warn = Int32.Parse (wc);
-                                                       if (warn < 1) {
-                                                               throw new ArgumentOutOfRangeException ("warn");
-                                                       }
-                                                       settings.SetIgnoreWarning (warn);
-                                               } catch {
-                                                       report.Error (1904, "`{0}' is not a valid warning number", wc);
-                                                       return ParseResult.Error;
-                                               }
-                                       }
-                                       return ParseResult.Success;
+                               return ParseResult.Success;
 
                        case "/noconfig":
                                settings.LoadDefaultReferences = false;
@@ -1045,7 +1033,10 @@ namespace Mono.CSharp {
                                        return ParseResult.Error;
                                }
 
-                               switch (value.ToLower (CultureInfo.InvariantCulture)) {
+                               switch (value.ToLowerInvariant ()) {
+                               case "arm":
+                                       settings.Platform = Platform.Arm;
+                                       break;
                                case "anycpu":
                                        settings.Platform = Platform.AnyCPU;
                                        break;
@@ -1058,8 +1049,12 @@ namespace Mono.CSharp {
                                case "itanium":
                                        settings.Platform = Platform.IA64;
                                        break;
+                               case "anycpu32bitpreferred":
+                                       settings.Platform = Platform.AnyCPU32Preferred;
+                                       break;
                                default:
-                                       report.Error (1672, "Invalid platform type for -platform. Valid options are `anycpu', `x86', `x64' or `itanium'");
+                                       report.Error (1672, "Invalid -platform option `{0}'. Valid options are `anycpu', `anycpu32bitpreferred', `arm', `x86', `x64' or `itanium'",
+                                               value);
                                        return ParseResult.Error;
                                }
 
@@ -1112,7 +1107,7 @@ namespace Mono.CSharp {
                                return ParseResult.Success;
 
                        case "/fullpaths":
-                               report.Printer.ShowFullPaths = true;
+                               settings.ShowFullPaths = true;
                                return ParseResult.Success;
 
                        case "/keyfile":
@@ -1150,11 +1145,13 @@ namespace Mono.CSharp {
 
                                switch (value.ToLowerInvariant ()) {
                                case "iso-1":
+                               case "1":
                                        settings.Version = LanguageVersion.ISO_1;
                                        return ParseResult.Success;
                                case "default":
                                        settings.Version = LanguageVersion.Default;
                                        return ParseResult.Success;
+                               case "2":
                                case "iso-2":
                                        settings.Version = LanguageVersion.ISO_2;
                                        return ParseResult.Success;
@@ -1167,12 +1164,18 @@ namespace Mono.CSharp {
                                case "5":
                                        settings.Version = LanguageVersion.V_5;
                                        return ParseResult.Success;
-                               case "future":
-                                       settings.Version = LanguageVersion.Future;
+                               case "6":
+                                       settings.Version = LanguageVersion.V_6;
                                        return ParseResult.Success;
+                               case "experimental":
+                                       settings.Version = LanguageVersion.Experimental;
+                                       return ParseResult.Success;
+                               case "future":
+                                       report.Warning (8000, 1, "Language version `future' is no longer supported");
+                                       goto case "6";
                                }
 
-                               report.Error (1617, "Invalid -langversion option `{0}'. It must be `ISO-1', `ISO-2', `3', `4', `5', `Default' or `Future'", value);
+                               report.Error (1617, "Invalid -langversion option `{0}'. It must be `ISO-1', `ISO-2', Default or value in range 1 to 6", value);
                                return ParseResult.Error;
 
                        case "/codepage":
@@ -1198,6 +1201,15 @@ namespace Mono.CSharp {
                                }
                                return ParseResult.Success;
 
+                       case "runtimemetadataversion":
+                               if (value.Length == 0) {
+                                       Error_RequiresArgument (option);
+                                       return ParseResult.Error;
+                               }
+
+                               settings.RuntimeMetadataVersion = value;
+                               return ParseResult.Success;
+
                        default:
                                return ParseResult.UnknownOption;
                        }
@@ -1272,7 +1284,7 @@ namespace Mono.CSharp {
                                return ParseResult.Success;
                                
                        case "--stacktrace":
-                               report.Printer.Stacktrace = true;
+                               settings.Stacktrace = true;
                                return ParseResult.Success;
                                
                        case "--linkresource":
@@ -1435,13 +1447,21 @@ namespace Mono.CSharp {
                                settings.LoadDefaultReferences = false;
                                return ParseResult.Success;
 
+                       case "--metadata-only":
+                               settings.WriteMetadataOnly = true;
+                               return ParseResult.Success;
+
+                       case "--break-on-ice":
+                               settings.BreakOnInternalError = true;
+                               return ParseResult.Success;
+
                        default:
-                               if (arg.StartsWith ("--fatal")){
+                               if (arg.StartsWith ("--fatal", StringComparison.Ordinal)) {
                                        int fatal = 1;
-                                       if (arg.StartsWith ("--fatal="))
+                                       if (arg.StartsWith ("--fatal=", StringComparison.Ordinal))
                                                int.TryParse (arg.Substring (8), out fatal);
 
-                                       report.Printer.FatalCounter = fatal;
+                                       settings.FatalCounter = fatal;
                                        return ParseResult.Success;
                                }
                                if (arg.StartsWith ("--runtime:", StringComparison.Ordinal)) {
@@ -1464,6 +1484,20 @@ namespace Mono.CSharp {
                                        return ParseResult.Success;
                                }
 
+                               if (arg.StartsWith ("--getresourcestrings:", StringComparison.Ordinal)) {
+                                       string file = arg.Substring (21).Trim ();
+                                       if (file.Length < 1) {
+                                               Error_RequiresArgument (arg);
+                                               return ParseResult.Error;
+                                       }
+
+                                       if (settings.GetResourceStrings == null)
+                                               settings.GetResourceStrings = new List<string> ();
+
+                                       settings.GetResourceStrings.Add (file);
+                                       return ParseResult.Success;
+                               }
+
                                return ParseResult.UnknownOption;
                        }
                }
@@ -1518,7 +1552,7 @@ namespace Mono.CSharp {
                void Usage ()
                {
                        output.WriteLine (
-                               "Mono C# compiler, Copyright 2001 - 2011 Novell, Inc.\n" +
+                               "Mono C# compiler, Copyright 2001-2011 Novell, Inc., Copyright 2011-2012 Xamarin, 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" +
@@ -1533,7 +1567,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, 3, 4, 5, Default or Future\n" +
+                               "   -langversion:TEXT    Specifies language version: ISO-1, ISO-2, 3, 4, 5, Default or Experimental\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" +
@@ -1543,12 +1577,13 @@ namespace Mono.CSharp {
                                "   -out:FILE            Specifies output assembly name\n" +
                                "   -pkg:P1[,Pn]         References packages P1..Pn\n" +
                                "   -platform:ARCH       Specifies the target platform of the output assembly\n" +
-                               "                        ARCH can be one of: anycpu, x86, x64 or itanium\n" +
+                               "                        ARCH can be one of: anycpu, anycpu32bitpreferred, arm,\n" +
+                               "                        x86, x64 or itanium. The default is anycpu.\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" +
                                "   -sdk:VERSION         Specifies SDK version of referenced assemblies\n" +
-                               "                        VERSION can be one of: 2, 4 (default) or custom value\n" +
+                               "                        VERSION can be one of: 2, 4, 4.5 (default) or a custom value\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" +