Пример #1
0
		//
		// 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;
        }
Пример #4
0
		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);
		}