// // This parses the -arg and /arg options to the compiler, even if the strings // in the following text use "/arg" on the strings. // ParseResult ParseOption (string option, ref string[] args, CompilerSettings settings) { int idx = option.IndexOf (':'); string arg, value; if (idx == -1) { arg = option; value = ""; } else { arg = option.Substring (0, idx); value = option.Substring (idx + 1); } switch (arg.ToLowerInvariant ()) { case "/nologo": return ParseResult.Success; case "/t": case "/target": bool is_dotnet = true; switch (value) { case "exe": settings.Target = Target.Exe; break; case "winexe": settings.Target = Target.WinExe; break; case "library": settings.Target = Target.Library; settings.TargetExt = ".dll"; break; case "module": settings.Target = Target.Module; settings.TargetExt = ".netmodule"; break; case "javascript": settings.Target = Target.JavaScript; settings.TargetExt = ".js"; settings.AddConditionalSymbol ("TARGET_JS"); is_dotnet = false; break; case "cpp": settings.Target = Target.Cpp; settings.TargetExt = ".cpp"; settings.AddConditionalSymbol ("TARGET_CPP"); is_dotnet = false; break; default: report.Error (2019, "Invalid target type for -target. Valid options are `exe', `winexe', `library', `module', `javascript' or `cpp'"); return ParseResult.Error; } if (is_dotnet) { settings.AddConditionalSymbol ("TARGET_IL"); } return ParseResult.Success; case "/out": if (value.Length == 0) { Error_RequiresFileName (option); return ParseResult.Error; } settings.OutputFile = value; return ParseResult.Success; case "/o": case "/o+": case "/optimize": case "/optimize+": settings.Optimize = true; return ParseResult.Success; case "/o-": case "/optimize-": settings.Optimize = false; return ParseResult.Success; // TODO: Not supported by csc 3.5+ case "/incremental": case "/incremental+": case "/incremental-": // nothing. return ParseResult.Success; case "/d": case "/define": { if (value.Length == 0) { Error_RequiresArgument (option); return ParseResult.Error; } foreach (string d in value.Split (argument_value_separator)) { string conditional = d.Trim (); if (!Tokenizer.IsValidIdentifier (conditional)) { report.Warning (2029, 1, "Invalid conditional define symbol `{0}'", conditional); continue; } settings.AddConditionalSymbol (conditional); } return ParseResult.Success; } case "/bugreport": // // We should collect data, runtime, etc and store in the file specified // output.WriteLine ("To file bug reports, please visit: http://www.mono-project.com/Bugs"); return ParseResult.Success; case "/pkg": { string packages; if (value.Length == 0) { Error_RequiresArgument (option); return ParseResult.Error; } packages = String.Join (" ", value.Split (new Char[] { ';', ',', '\n', '\r' })); string pkgout = Driver.GetPackageFlags (packages, report); if (pkgout == null) return ParseResult.Error; string[] xargs = pkgout.Trim (new Char[] { ' ', '\n', '\r', '\t' }).Split (new Char[] { ' ', '\t' }); args = AddArgs (args, xargs); return ParseResult.Success; } case "/linkres": case "/linkresource": case "/res": case "/resource": AssemblyResource res = null; string[] s = value.Split (argument_value_separator, StringSplitOptions.RemoveEmptyEntries); switch (s.Length) { case 1: if (s[0].Length == 0) goto default; res = new AssemblyResource (s[0], Path.GetFileName (s[0])); break; case 2: res = new AssemblyResource (s[0], s[1]); break; case 3: if (s[2] != "public" && s[2] != "private") { report.Error (1906, "Invalid resource visibility option `{0}'. Use either `public' or `private' instead", s[2]); return ParseResult.Error; } res = new AssemblyResource (s[0], s[1], s[2] == "private"); break; default: report.Error (-2005, "Wrong number of arguments for option `{0}'", option); return ParseResult.Error; } if (res != null) { res.IsEmbeded = arg[1] == 'r' || arg[1] == 'R'; AddResource (res, settings); } return ParseResult.Success; case "/recurse": if (value.Length == 0) { Error_RequiresFileName (option); return ParseResult.Error; } ProcessSourceFiles (value, true, settings.SourceFiles); return ParseResult.Success; case "/r": case "/reference": { if (value.Length == 0) { Error_RequiresFileName (option); return ParseResult.Error; } string[] refs = value.Split (argument_value_separator); foreach (string r in refs) { if (r.Length == 0) continue; string val = r; int index = val.IndexOf ('='); if (index > -1) { string alias = r.Substring (0, index); string assembly = r.Substring (index + 1); AddAssemblyReference (alias, assembly, settings); if (refs.Length != 1) { report.Error (2034, "Cannot specify multiple aliases using single /reference option"); return ParseResult.Error; } } else { settings.AssemblyReferences.Add (val); } } return ParseResult.Success; } case "/addmodule": { if (value.Length == 0) { Error_RequiresFileName (option); return ParseResult.Error; } string[] refs = value.Split (argument_value_separator); foreach (string r in refs) { settings.Modules.Add (r); } return ParseResult.Success; } case "/win32res": { if (value.Length == 0) { Error_RequiresFileName (option); return ParseResult.Error; } if (settings.Win32IconFile != null) report.Error (1565, "Cannot specify the `win32res' and the `win32ico' compiler option at the same time"); settings.Win32ResourceFile = value; return ParseResult.Success; } case "/win32icon": { if (value.Length == 0) { Error_RequiresFileName (option); return ParseResult.Error; } if (settings.Win32ResourceFile != null) report.Error (1565, "Cannot specify the `win32res' and the `win32ico' compiler option at the same time"); settings.Win32IconFile = value; return ParseResult.Success; } case "/doc": { if (value.Length == 0) { Error_RequiresFileName (option); return ParseResult.Error; } settings.DocumentationFile = value; return ParseResult.Success; } case "/lib": { string[] libdirs; if (value.Length == 0) { return ParseResult.Error; } libdirs = value.Split (argument_value_separator); foreach (string dir in libdirs) settings.ReferencesLookupPaths.Add (dir); return ParseResult.Success; } case "/debug-": settings.GenerateDebugInfo = false; return ParseResult.Success; case "/debug": if (value.Equals ("full", StringComparison.OrdinalIgnoreCase) || value.Equals ("pdbonly", StringComparison.OrdinalIgnoreCase) || idx < 0) { settings.GenerateDebugInfo = true; return ParseResult.Success; } if (value.Length > 0) { report.Error (1902, "Invalid debug option `{0}'. Valid options are `full' or `pdbonly'", value); } else { Error_RequiresArgument (option); } return ParseResult.Error; case "/debug+": settings.GenerateDebugInfo = true; return ParseResult.Success; case "/checked": case "/checked+": settings.Checked = true; return ParseResult.Success; case "/checked-": settings.Checked = false; return ParseResult.Success; case "/clscheck": case "/clscheck+": settings.VerifyClsCompliance = true; return ParseResult.Success; case "/clscheck-": settings.VerifyClsCompliance = false; return ParseResult.Success; case "/unsafe": case "/unsafe+": settings.Unsafe = true; return ParseResult.Success; case "/unsafe-": settings.Unsafe = false; return ParseResult.Success; case "/warnaserror": case "/warnaserror+": if (value.Length == 0) { settings.WarningsAreErrors = true; parser_settings.WarningsAreErrors = true; } else { if (!ProcessWarningsList (value, v => settings.AddWarningAsError (v))) return ParseResult.Error; } return ParseResult.Success; case "/warnaserror-": if (value.Length == 0) { settings.WarningsAreErrors = false; } else { if (!ProcessWarningsList (value, v => settings.AddWarningOnly (v))) return ParseResult.Error; } return ParseResult.Success; case "/warn": case "/w": if (value.Length == 0) { Error_RequiresArgument (option); return ParseResult.Error; } SetWarningLevel (value, settings); return ParseResult.Success; case "/nowarn": if (value.Length == 0) { Error_RequiresArgument (option); return ParseResult.Error; } if (!ProcessWarningsList (value, v => settings.SetIgnoreWarning (v))) return ParseResult.Error; return ParseResult.Success; case "/noconfig": settings.LoadDefaultReferences = false; return ParseResult.Success; case "/platform": if (value.Length == 0) { Error_RequiresArgument (option); return ParseResult.Error; } switch (value.ToLowerInvariant ()) { case "arm": settings.Platform = Platform.Arm; break; case "anycpu": settings.Platform = Platform.AnyCPU; break; case "x86": settings.Platform = Platform.X86; break; case "x64": settings.Platform = Platform.X64; break; case "itanium": settings.Platform = Platform.IA64; break; case "anycpu32bitpreferred": settings.Platform = Platform.AnyCPU32Preferred; break; default: report.Error (1672, "Invalid -platform option `{0}'. Valid options are `anycpu', `anycpu32bitpreferred', `arm', `x86', `x64' or `itanium'", value); return ParseResult.Error; } return ParseResult.Success; case "/sdk": if (value.Length == 0) { Error_RequiresArgument (option); return ParseResult.Error; } settings.SdkVersion = value; return ParseResult.Success; // We just ignore this. case "/errorreport": case "/filealign": if (value.Length == 0) { Error_RequiresArgument (option); return ParseResult.Error; } return ParseResult.Success; // We just ignore this. case "/errorendlocation": case "/highentropyva-": case "/highentropyva+": case "/highentropyva": case "/utf8output": return ParseResult.Success; // We just ignore this. case "/preferreduilang": switch (value.ToLowerInvariant()) { default: return ParseResult.Success; } case "/helpinternal": OtherFlags (); return ParseResult.Stop; case "/help": case "/?": Usage (); return ParseResult.Stop; case "/main": case "/m": if (value.Length == 0) { Error_RequiresArgument (option); return ParseResult.Error; } settings.MainClass = value; return ParseResult.Success; case "/nostdlib": case "/nostdlib+": settings.StdLib = false; return ParseResult.Success; case "/nostdlib-": settings.StdLib = true; return ParseResult.Success; case "/fullpaths": settings.ShowFullPaths = true; return ParseResult.Success; case "/keyfile": if (value.Length == 0) { Error_RequiresFileName (option); return ParseResult.Error; } settings.StrongNameKeyFile = value; return ParseResult.Success; case "/keycontainer": if (value.Length == 0) { Error_RequiresArgument (option); return ParseResult.Error; } settings.StrongNameKeyContainer = value; return ParseResult.Success; case "/delaysign+": case "/delaysign": settings.StrongNameDelaySign = true; return ParseResult.Success; case "/delaysign-": settings.StrongNameDelaySign = false; return ParseResult.Success; case "/langversion": if (value.Length == 0) { Error_RequiresArgument (option); return ParseResult.Error; } switch (value.ToLowerInvariant ()) { case "iso-1": settings.Version = LanguageVersion.ISO_1; return ParseResult.Success; case "default": settings.Version = LanguageVersion.Default; return ParseResult.Success; case "iso-2": settings.Version = LanguageVersion.ISO_2; return ParseResult.Success; case "3": settings.Version = LanguageVersion.V_3; return ParseResult.Success; case "4": settings.Version = LanguageVersion.V_4; return ParseResult.Success; case "5": settings.Version = LanguageVersion.V_5; return ParseResult.Success; case "future": settings.Version = LanguageVersion.Future; return ParseResult.Success; } report.Error (1617, "Invalid -langversion option `{0}'. It must be `ISO-1', `ISO-2', `3', `4', `5', `Default' or `Future'", value); return ParseResult.Error; case "/codepage": if (value.Length == 0) { Error_RequiresArgument (option); return ParseResult.Error; } switch (value) { case "utf8": settings.Encoding = Encoding.UTF8; break; case "reset": settings.Encoding = Encoding.Default; break; default: try { settings.Encoding = Encoding.GetEncoding (int.Parse (value)); } catch { report.Error (2016, "Code page `{0}' is invalid or not installed", value); } return ParseResult.Error; } return ParseResult.Success; default: return ParseResult.UnknownOption; } }
private static CompilerSettings MapSettings(CompilerOptions options, string outputAssemblyPath, string outputDocFilePath, IErrorReporter er) { var allPaths = options.AdditionalLibPaths.Concat(new[] { Environment.CurrentDirectory }).ToList(); var result = new CompilerSettings { Target = (options.HasEntryPoint ? Target.Exe : Target.Library), Platform = Platform.AnyCPU, TargetExt = (options.HasEntryPoint ? ".exe" : ".dll"), MainClass = options.EntryPointClass, VerifyClsCompliance = false, Optimize = false, Version = LanguageVersion.V_5, EnhancedWarnings = false, LoadDefaultReferences = false, TabSize = 1, WarningsAreErrors = options.TreatWarningsAsErrors, FatalCounter = 100, WarningLevel = options.WarningLevel, Encoding = Encoding.UTF8, DocumentationFile = !string.IsNullOrEmpty(options.DocumentationFile) ? outputDocFilePath : null, OutputFile = outputAssemblyPath, AssemblyName = GetAssemblyName(options), StdLib = false, StdLibRuntimeVersion = RuntimeVersion.v4, StrongNameKeyContainer = options.KeyContainer, StrongNameKeyFile = options.KeyFile, }; result.SourceFiles.AddRange(options.SourceFiles.Select((f, i) => new SourceFile(f, f, i + 1))); foreach (var r in options.References) { string resolvedPath = ResolveReference(r.Filename, allPaths, er); if (r.Alias == null) result.AssemblyReferences.Add(resolvedPath); else result.AssemblyReferencesAliases.Add(Tuple.Create(r.Alias, resolvedPath)); } foreach (var c in options.DefineConstants) result.AddConditionalSymbol(c); foreach (var w in options.DisabledWarnings) result.SetIgnoreWarning(w); foreach (var w in options.WarningsAsErrors) result.AddWarningAsError(w); foreach (var w in options.WarningsNotAsErrors) result.AddWarningOnly(w); if (options.EmbeddedResources.Count > 0) result.Resources = options.EmbeddedResources.Select(r => new AssemblyResource(r.Filename, r.ResourceName, isPrivate: !r.IsPublic) { IsEmbeded = true }).ToList(); if (result.AssemblyReferencesAliases.Count > 0) { // NRefactory does currently not support reference aliases, this check will hopefully go away in the future. er.Region = DomRegion.Empty; er.Message(Messages._7998, "aliased reference"); } return result; }
private static CompilerSettings MapSettings(CompilerOptions options, string outputAssemblyPath, string outputDocFilePath, IErrorReporter er) { var allPaths = options.AdditionalLibPaths.Concat(new[] { Environment.CurrentDirectory }).ToList(); var result = new CompilerSettings(); result.Target = Target.Library; result.Platform = Platform.AnyCPU; result.TargetExt = ".dll"; result.VerifyClsCompliance = false; result.Optimize = false; result.Version = LanguageVersion.V_5; result.EnhancedWarnings = false; result.LoadDefaultReferences = false; result.TabSize = 1; result.WarningsAreErrors = options.TreatWarningsAsErrors; result.FatalCounter = 100; result.WarningLevel = options.WarningLevel; result.AssemblyReferences = options.References.Where(r => r.Alias == null).Select(r => ResolveReference(r.Filename, allPaths, er)).ToList(); result.AssemblyReferencesAliases = options.References.Where(r => r.Alias != null).Select(r => Tuple.Create(r.Alias, ResolveReference(r.Filename, allPaths, er))).ToList(); result.Encoding = Encoding.UTF8; result.DocumentationFile = !string.IsNullOrEmpty(options.DocumentationFile) ? outputDocFilePath : null; result.OutputFile = outputAssemblyPath; result.AssemblyName = GetAssemblyName(options); result.StdLib = false; result.StdLibRuntimeVersion = RuntimeVersion.v4; result.StrongNameKeyContainer = options.KeyContainer; result.StrongNameKeyFile = options.KeyFile; result.SourceFiles.AddRange(options.SourceFiles.Select((f, i) => new SourceFile(f, f, i + 1))); foreach (var c in options.DefineConstants) result.AddConditionalSymbol(c); foreach (var w in options.DisabledWarnings) result.SetIgnoreWarning(w); result.SetIgnoreWarning(660); // 660 and 661: class defines operator == or operator != but does not override Equals / GetHashCode. These warnings don't really apply, since we have no Equals / GetHashCode methods to override. result.SetIgnoreWarning(661); foreach (var w in options.WarningsAsErrors) result.AddWarningAsError(w); foreach (var w in options.WarningsNotAsErrors) result.AddWarningOnly(w); if (result.AssemblyReferencesAliases.Count > 0) { // NRefactory does currently not support reference aliases, this check will hopefully go away in the future. er.Region = DomRegion.Empty; er.Message(7998, "aliased reference"); } return result; }
void AddWarningAsError (string warningId, CompilerSettings settings) { int id; try { id = int.Parse (warningId); } catch { report.CheckWarningCode (warningId, Location.Null); return; } if (!report.CheckWarningCode (id, Location.Null)) return; settings.AddWarningAsError (id); }