2
// rootcontext.cs: keeps track of our tree representation, and assemblies loaded.
4
// Author: Miguel de Icaza (miguel@ximian.com)
5
// Ravi Pratap (ravi@ximian.com)
6
// Marek Safar (marek.safar@gmail.com)
9
// Dual licensed under the terms of the MIT X11 or GNU GPL
11
// Copyright 2001 Ximian, Inc (http://www.ximian.com)
12
// Copyright 2004-2008 Novell, Inc
14
using System.Collections.Generic;
17
using System.Globalization;
20
namespace Mono.CSharp {
22
public enum LanguageVersion
30
Default = LanguageVersion.V_4,
33
public enum RuntimeVersion
42
Library, Exe, Module, WinExe
47
AnyCPU, X86, X64, IA64
50
public class CompilerSettings
53
public Platform Platform;
54
public string TargetExt;
55
public bool VerifyClsCompliance;
57
public LanguageVersion Version;
58
public bool EnhancedWarnings;
59
public bool LoadDefaultReferences;
60
public string SdkVersion;
62
public string StrongNameKeyFile;
63
public string StrongNameKeyContainer;
64
public bool StrongNameDelaySign;
67
// Assemblies references to be loaded
69
public List<string> AssemblyReferences;
72
// External aliases for assemblies
74
public List<Tuple<string, string>> AssemblyReferencesAliases;
77
// Modules to be embedded
79
public List<string> Modules;
82
// Lookup paths for referenced assemblies
84
public List<string> ReferencesLookupPaths;
89
public Encoding Encoding;
92
// If set, enable XML documentation generation
94
public string DocumentationFile;
96
public string MainClass;
101
public string OutputFile;
104
// The default compiler checked state
109
// If true, the compiler is operating in statement mode,
110
// this currently turns local variable declaration into
111
// static variables of a class
113
public bool StatementMode; // TODO: SUPER UGLY
116
// Whether to allow Unsafe code
120
public string Win32ResourceFile;
121
public string Win32IconFile;
124
// A list of resource files for embedding
126
public List<AssemblyResource> Resources;
128
public bool GenerateDebugInfo;
130
// Compiler debug flags only
131
public bool ParseOnly, TokenizeOnly, Timestamps;
132
public int DebugFlags;
135
// Whether we are being linked against the standard libraries.
136
// This is only used to tell whether `System.Object' should
137
// have a base class or not.
141
public RuntimeVersion StdLibRuntimeVersion;
143
readonly List<string> conditional_symbols;
145
readonly List<CompilationSourceFile> source_files;
147
public CompilerSettings ()
152
Platform = Platform.AnyCPU;
153
Version = LanguageVersion.Default;
154
VerifyClsCompliance = true;
156
Encoding = Encoding.UTF8;
157
LoadDefaultReferences = true;
158
StdLibRuntimeVersion = RuntimeVersion.v4;
160
AssemblyReferences = new List<string> ();
161
AssemblyReferencesAliases = new List<Tuple<string, string>> ();
162
Modules = new List<string> ();
163
ReferencesLookupPaths = new List<string> ();
165
conditional_symbols = new List<string> ();
167
// Add default mcs define
169
conditional_symbols.Add ("__MonoCS__");
171
source_files = new List<CompilationSourceFile> ();
176
public CompilationSourceFile FirstSourceFile {
178
return source_files.Count > 0 ? source_files [0] : null;
182
public bool HasKeyFileOrContainer {
184
return StrongNameKeyFile != null || StrongNameKeyContainer != null;
188
public bool NeedsEntryPoint {
190
return Target == Target.Exe || Target == Target.WinExe;
194
public List<CompilationSourceFile> SourceFiles {
202
public void AddConditionalSymbol (string symbol)
204
if (!conditional_symbols.Contains (symbol))
205
conditional_symbols.Add (symbol);
208
public bool IsConditionalSymbolDefined (string symbol)
210
return conditional_symbols.Contains (symbol);
214
public class CommandLineParser
224
static readonly char[] argument_value_separator = new char[] { ';', ',' };
225
static readonly char[] numeric_value_separator = new char[] { ';', ',', ' ' };
227
readonly Report report;
228
readonly TextWriter output;
231
Dictionary<string, int> source_file_index;
233
public event Func<string[], int, int> UnknownOptionHandler;
235
public CommandLineParser (Report report)
236
: this (report, Console.Out)
240
public CommandLineParser (Report report, TextWriter messagesOutput)
242
this.report = report;
243
this.output = messagesOutput;
246
public bool HasBeenStopped {
248
return stop_argument;
255
"The Mono C# compiler is Copyright 2001-2011, Novell, Inc.\n\n" +
256
"The compiler source code is released under the terms of the \n" +
257
"MIT X11 or GNU GPL licenses\n\n" +
259
"For more information on Mono, visit the project Web site\n" +
260
" http://www.mono-project.com\n\n" +
262
"The compiler was written by Miguel de Icaza, Ravi Pratap, Martin Baulig, Marek Safar, Raja R Harinath, Atushi Enomoto");
265
public CompilerSettings ParseArguments (string[] args)
267
CompilerSettings settings = new CompilerSettings ();
268
List<string> response_file_list = null;
269
bool parsing_options = true;
270
stop_argument = false;
271
source_file_index = new Dictionary<string, int> ();
273
for (int i = 0; i < args.Length; i++) {
274
string arg = args[i];
280
string response_file = arg.Substring (1);
282
if (response_file_list == null)
283
response_file_list = new List<string> ();
285
if (response_file_list.Contains (response_file)) {
286
report.Error (1515, "Response file `{0}' specified multiple times", response_file);
290
response_file_list.Add (response_file);
292
extra_args = LoadArgs (response_file);
293
if (extra_args == null) {
294
report.Error (2011, "Unable to open response file: " + response_file);
298
args = AddArgs (args, extra_args);
302
if (parsing_options) {
304
parsing_options = false;
308
bool dash_opt = arg[0] == '-';
309
bool slash_opt = arg[0] == '/';
311
switch (ParseOptionUnix (arg, ref args, ref i, settings)) {
312
case ParseResult.Error:
313
case ParseResult.Success:
315
case ParseResult.Stop:
316
stop_argument = true;
318
case ParseResult.UnknownOption:
319
if (UnknownOptionHandler != null) {
320
var ret = UnknownOptionHandler (args, i);
330
if (dash_opt || slash_opt) {
332
string csc_opt = dash_opt ? "/" + arg.Substring (1) : arg;
333
switch (ParseOption (csc_opt, ref args, settings)) {
334
case ParseResult.Error:
335
case ParseResult.Success:
337
case ParseResult.UnknownOption:
338
// Need to skip `/home/test.cs' however /test.cs is considered as error
339
if ((slash_opt && arg.Length > 3 && arg.IndexOf ('/', 2) > 0))
342
if (UnknownOptionHandler != null) {
343
var ret = UnknownOptionHandler (args, i);
350
Error_WrongOption (arg);
353
case ParseResult.Stop:
354
stop_argument = true;
360
ProcessSourceFiles (arg, false, settings.SourceFiles);
366
void ProcessSourceFiles (string spec, bool recurse, List<CompilationSourceFile> sourceFiles)
368
string path, pattern;
370
SplitPathAndPattern (spec, out path, out pattern);
371
if (pattern.IndexOf ('*') == -1) {
372
AddSourceFile (spec, sourceFiles);
376
string[] files = null;
378
files = Directory.GetFiles (path, pattern);
379
} catch (System.IO.DirectoryNotFoundException) {
380
report.Error (2001, "Source file `" + spec + "' could not be found");
382
} catch (System.IO.IOException) {
383
report.Error (2001, "Source file `" + spec + "' could not be found");
386
foreach (string f in files) {
387
AddSourceFile (f, sourceFiles);
393
string[] dirs = null;
396
dirs = Directory.GetDirectories (path);
400
foreach (string d in dirs) {
402
// Don't include path in this string, as each
403
// directory entry already does
404
ProcessSourceFiles (d + "/" + pattern, true, sourceFiles);
408
static string[] AddArgs (string[] args, string[] extra_args)
411
new_args = new string[extra_args.Length + args.Length];
413
// if args contains '--' we have to take that into account
414
// split args into first half and second half based on '--'
415
// and add the extra_args before --
416
int split_position = Array.IndexOf (args, "--");
417
if (split_position != -1) {
418
Array.Copy (args, new_args, split_position);
419
extra_args.CopyTo (new_args, split_position);
420
Array.Copy (args, split_position, new_args, split_position + extra_args.Length, args.Length - split_position);
422
args.CopyTo (new_args, 0);
423
extra_args.CopyTo (new_args, args.Length);
429
void AddAssemblyReference (string alias, string assembly, CompilerSettings settings)
431
if (assembly.Length == 0) {
432
report.Error (1680, "Invalid reference alias `{0}='. Missing filename", alias);
436
if (!IsExternAliasValid (alias)) {
437
report.Error (1679, "Invalid extern alias for -reference. Alias `{0}' is not a valid identifier", alias);
441
settings.AssemblyReferencesAliases.Add (Tuple.Create (alias, assembly));
444
void AddResource (AssemblyResource res, CompilerSettings settings)
446
if (settings.Resources == null) {
447
settings.Resources = new List<AssemblyResource> ();
448
settings.Resources.Add (res);
452
if (settings.Resources.Contains (res)) {
453
report.Error (1508, "The resource identifier `{0}' has already been used in this assembly", res.Name);
457
settings.Resources.Add (res);
460
void AddSourceFile (string fileName, List<CompilationSourceFile> sourceFiles)
462
string path = Path.GetFullPath (fileName);
465
if (source_file_index.TryGetValue (path, out index)) {
466
string other_name = sourceFiles[index - 1].Name;
467
if (fileName.Equals (other_name))
468
report.Warning (2002, 1, "Source file `{0}' specified multiple times", other_name);
470
report.Warning (2002, 1, "Source filenames `{0}' and `{1}' both refer to the same file: {2}", fileName, other_name, path);
475
var unit = new CompilationSourceFile (fileName, path, sourceFiles.Count + 1);
476
sourceFiles.Add (unit);
477
source_file_index.Add (path, unit.Index);
480
void Error_RequiresArgument (string option)
482
report.Error (2006, "Missing argument for `{0}' option", option);
485
void Error_RequiresFileName (string option)
487
report.Error (2005, "Missing file specification for `{0}' option", option);
490
void Error_WrongOption (string option)
492
report.Error (2007, "Unrecognized command-line option: `{0}'", option);
495
static bool IsExternAliasValid (string identifier)
497
if (identifier.Length == 0)
499
if (identifier[0] != '_' && !char.IsLetter (identifier[0]))
502
for (int i = 1; i < identifier.Length; i++) {
503
char c = identifier[i];
504
if (char.IsLetter (c) || char.IsDigit (c))
507
UnicodeCategory category = char.GetUnicodeCategory (c);
508
if (category != UnicodeCategory.Format || category != UnicodeCategory.NonSpacingMark ||
509
category != UnicodeCategory.SpacingCombiningMark ||
510
category != UnicodeCategory.ConnectorPunctuation)
517
static string[] LoadArgs (string file)
520
var args = new List<string> ();
523
f = new StreamReader (file);
528
StringBuilder sb = new StringBuilder ();
530
while ((line = f.ReadLine ()) != null) {
533
for (int i = 0; i < t; i++) {
536
if (c == '"' || c == '\'') {
539
for (i++; i < t; i++) {
546
} else if (c == ' ') {
548
args.Add (sb.ToString ());
555
args.Add (sb.ToString ());
560
return args.ToArray ();
566
"Other flags in the compiler\n" +
567
" --fatal[=COUNT] Makes errors after COUNT fatal\n" +
568
" --lint Enhanced warnings\n" +
569
" --parse Only parses the source file\n" +
570
" --runtime:VERSION Sets mscorlib.dll metadata version: v1, v2, v4\n" +
571
" --stacktrace Shows stack trace at error location\n" +
572
" --timestamp Displays time stamps of various compiler events\n" +
573
" -v Verbose parsing (for debugging the parser)\n" +
574
" --mcs-debug X Sets MCS debugging level to X\n");
578
// This parses the -arg and /arg options to the compiler, even if the strings
579
// in the following text use "/arg" on the strings.
581
ParseResult ParseOption (string option, ref string[] args, CompilerSettings settings)
583
int idx = option.IndexOf (':');
590
arg = option.Substring (0, idx);
592
value = option.Substring (idx + 1);
595
switch (arg.ToLowerInvariant ()) {
597
return ParseResult.Success;
603
settings.Target = Target.Exe;
607
settings.Target = Target.WinExe;
611
settings.Target = Target.Library;
612
settings.TargetExt = ".dll";
616
settings.Target = Target.Module;
617
settings.TargetExt = ".netmodule";
621
report.Error (2019, "Invalid target type for -target. Valid options are `exe', `winexe', `library' or `module'");
622
return ParseResult.Error;
624
return ParseResult.Success;
627
if (value.Length == 0) {
628
Error_RequiresFileName (option);
629
return ParseResult.Error;
631
settings.OutputFile = value;
632
return ParseResult.Success;
638
settings.Optimize = true;
639
return ParseResult.Success;
643
settings.Optimize = false;
644
return ParseResult.Success;
646
// TODO: Not supported by csc 3.5+
648
case "/incremental+":
649
case "/incremental-":
651
return ParseResult.Success;
655
if (value.Length == 0) {
656
Error_RequiresArgument (option);
657
return ParseResult.Error;
660
foreach (string d in value.Split (argument_value_separator)) {
661
string conditional = d.Trim ();
662
if (!Tokenizer.IsValidIdentifier (conditional)) {
663
report.Warning (2029, 1, "Invalid conditional define symbol `{0}'", conditional);
667
settings.AddConditionalSymbol (conditional);
669
return ParseResult.Success;
674
// We should collect data, runtime, etc and store in the file specified
676
output.WriteLine ("To file bug reports, please visit: http://www.mono-project.com/Bugs");
677
return ParseResult.Success;
682
if (value.Length == 0) {
683
Error_RequiresArgument (option);
684
return ParseResult.Error;
686
packages = String.Join (" ", value.Split (new Char[] { ';', ',', '\n', '\r' }));
687
string pkgout = Driver.GetPackageFlags (packages, report);
690
return ParseResult.Error;
692
string[] xargs = pkgout.Trim (new Char[] { ' ', '\n', '\r', '\t' }).Split (new Char[] { ' ', '\t' });
693
args = AddArgs (args, xargs);
694
return ParseResult.Success;
698
case "/linkresource":
701
AssemblyResource res = null;
702
string[] s = value.Split (argument_value_separator, StringSplitOptions.RemoveEmptyEntries);
705
if (s[0].Length == 0)
707
res = new AssemblyResource (s[0], Path.GetFileName (s[0]));
710
res = new AssemblyResource (s[0], s[1]);
713
if (s[2] != "public" && s[2] != "private") {
714
report.Error (1906, "Invalid resource visibility option `{0}'. Use either `public' or `private' instead", s[2]);
715
return ParseResult.Error;
717
res = new AssemblyResource (s[0], s[1], s[2] == "private");
720
report.Error (-2005, "Wrong number of arguments for option `{0}'", option);
721
return ParseResult.Error;
725
res.IsEmbeded = arg[1] == 'r' || arg[1] == 'R';
726
AddResource (res, settings);
729
return ParseResult.Success;
732
if (value.Length == 0) {
733
Error_RequiresFileName (option);
734
return ParseResult.Error;
736
ProcessSourceFiles (value, true, settings.SourceFiles);
737
return ParseResult.Success;
741
if (value.Length == 0) {
742
Error_RequiresFileName (option);
743
return ParseResult.Error;
746
string[] refs = value.Split (argument_value_separator);
747
foreach (string r in refs) {
752
int index = val.IndexOf ('=');
754
string alias = r.Substring (0, index);
755
string assembly = r.Substring (index + 1);
756
AddAssemblyReference (alias, assembly, settings);
757
if (refs.Length != 1) {
758
report.Error (2034, "Cannot specify multiple aliases using single /reference option");
759
return ParseResult.Error;
762
settings.AssemblyReferences.Add (val);
765
return ParseResult.Success;
768
if (value.Length == 0) {
769
Error_RequiresFileName (option);
770
return ParseResult.Error;
773
string[] refs = value.Split (argument_value_separator);
774
foreach (string r in refs) {
775
settings.Modules.Add (r);
777
return ParseResult.Success;
780
if (value.Length == 0) {
781
Error_RequiresFileName (option);
782
return ParseResult.Error;
785
if (settings.Win32IconFile != null)
786
report.Error (1565, "Cannot specify the `win32res' and the `win32ico' compiler option at the same time");
788
settings.Win32ResourceFile = value;
789
return ParseResult.Success;
792
if (value.Length == 0) {
793
Error_RequiresFileName (option);
794
return ParseResult.Error;
797
if (settings.Win32ResourceFile != null)
798
report.Error (1565, "Cannot specify the `win32res' and the `win32ico' compiler option at the same time");
800
settings.Win32IconFile = value;
801
return ParseResult.Success;
804
if (value.Length == 0) {
805
Error_RequiresFileName (option);
806
return ParseResult.Error;
809
settings.DocumentationFile = value;
810
return ParseResult.Success;
815
if (value.Length == 0) {
816
return ParseResult.Error;
819
libdirs = value.Split (argument_value_separator);
820
foreach (string dir in libdirs)
821
settings.ReferencesLookupPaths.Add (dir);
822
return ParseResult.Success;
826
settings.GenerateDebugInfo = false;
827
return ParseResult.Success;
830
if (value == "full" || value == "")
831
settings.GenerateDebugInfo = true;
833
return ParseResult.Success;
836
settings.GenerateDebugInfo = true;
837
return ParseResult.Success;
841
settings.Checked = true;
842
return ParseResult.Success;
845
settings.Checked = false;
846
return ParseResult.Success;
850
settings.VerifyClsCompliance = true;
851
return ParseResult.Success;
854
settings.VerifyClsCompliance = false;
855
return ParseResult.Success;
859
settings.Unsafe = true;
860
return ParseResult.Success;
863
settings.Unsafe = false;
864
return ParseResult.Success;
867
case "/warnaserror+":
868
if (value.Length == 0) {
869
report.WarningsAreErrors = true;
871
foreach (string wid in value.Split (numeric_value_separator))
872
report.AddWarningAsError (wid);
874
return ParseResult.Success;
876
case "/warnaserror-":
877
if (value.Length == 0) {
878
report.WarningsAreErrors = false;
880
foreach (string wid in value.Split (numeric_value_separator))
881
report.RemoveWarningAsError (wid);
883
return ParseResult.Success;
886
if (value.Length == 0) {
887
Error_RequiresArgument (option);
888
return ParseResult.Error;
891
SetWarningLevel (value);
892
return ParseResult.Success;
895
if (value.Length == 0) {
896
Error_RequiresArgument (option);
897
return ParseResult.Error;
900
var warns = value.Split (numeric_value_separator);
901
foreach (string wc in warns) {
903
if (wc.Trim ().Length == 0)
906
int warn = Int32.Parse (wc);
908
throw new ArgumentOutOfRangeException ("warn");
910
report.SetIgnoreWarning (warn);
912
report.Error (1904, "`{0}' is not a valid warning number", wc);
913
return ParseResult.Error;
916
return ParseResult.Success;
919
settings.LoadDefaultReferences = false;
920
return ParseResult.Success;
923
if (value.Length == 0) {
924
Error_RequiresArgument (option);
925
return ParseResult.Error;
928
switch (value.ToLower (CultureInfo.InvariantCulture)) {
930
settings.Platform = Platform.AnyCPU;
933
settings.Platform = Platform.X86;
936
settings.Platform = Platform.X64;
939
settings.Platform = Platform.IA64;
942
report.Error (1672, "Invalid platform type for -platform. Valid options are `anycpu', `x86', `x64' or `itanium'");
943
return ParseResult.Error;
946
return ParseResult.Success;
949
if (value.Length == 0) {
950
Error_RequiresArgument (option);
951
return ParseResult.Error;
954
settings.SdkVersion = value;
955
return ParseResult.Success;
957
// We just ignore this.
960
if (value.Length == 0) {
961
Error_RequiresArgument (option);
962
return ParseResult.Error;
965
return ParseResult.Success;
967
case "/helpinternal":
969
return ParseResult.Stop;
974
return ParseResult.Stop;
978
if (value.Length == 0) {
979
Error_RequiresArgument (option);
980
return ParseResult.Error;
982
settings.MainClass = value;
983
return ParseResult.Success;
987
settings.StdLib = false;
988
return ParseResult.Success;
991
settings.StdLib = true;
992
return ParseResult.Success;
995
report.Printer.ShowFullPaths = true;
996
return ParseResult.Success;
999
if (value.Length == 0) {
1000
Error_RequiresFileName (option);
1001
return ParseResult.Error;
1004
settings.StrongNameKeyFile = value;
1005
return ParseResult.Success;
1007
case "/keycontainer":
1008
if (value.Length == 0) {
1009
Error_RequiresArgument (option);
1010
return ParseResult.Error;
1013
settings.StrongNameKeyContainer = value;
1014
return ParseResult.Success;
1018
settings.StrongNameDelaySign = true;
1019
return ParseResult.Success;
1022
settings.StrongNameDelaySign = false;
1023
return ParseResult.Success;
1025
case "/langversion":
1026
if (value.Length == 0) {
1027
Error_RequiresArgument (option);
1028
return ParseResult.Error;
1031
switch (value.ToLowerInvariant ()) {
1033
settings.Version = LanguageVersion.ISO_1;
1034
return ParseResult.Success;
1036
settings.Version = LanguageVersion.Default;
1037
return ParseResult.Success;
1039
settings.Version = LanguageVersion.ISO_2;
1040
return ParseResult.Success;
1042
settings.Version = LanguageVersion.V_3;
1043
return ParseResult.Success;
1045
settings.Version = LanguageVersion.Future;
1046
return ParseResult.Success;
1049
report.Error (1617, "Invalid -langversion option `{0}'. It must be `ISO-1', `ISO-2', `3' or `Default'", value);
1050
return ParseResult.Error;
1053
if (value.Length == 0) {
1054
Error_RequiresArgument (option);
1055
return ParseResult.Error;
1060
settings.Encoding = Encoding.UTF8;
1063
settings.Encoding = Encoding.Default;
1067
settings.Encoding = Encoding.GetEncoding (int.Parse (value));
1069
report.Error (2016, "Code page `{0}' is invalid or not installed", value);
1071
return ParseResult.Error;
1073
return ParseResult.Success;
1076
return ParseResult.UnknownOption;
1081
// Currently handles the Unix-like command line options, but will be
1082
// deprecated in favor of the CSCParseOption, which will also handle the
1083
// options that start with a dash in the future.
1085
ParseResult ParseOptionUnix (string arg, ref string[] args, ref int i, CompilerSettings settings)
1089
CSharpParser.yacc_verbose_flag++;
1090
return ParseResult.Success;
1094
return ParseResult.Stop;
1097
settings.ParseOnly = true;
1098
return ParseResult.Success;
1100
case "--main": case "-m":
1101
report.Warning (-29, 1, "Compatibility: Use -main:CLASS instead of --main CLASS or -m CLASS");
1102
if ((i + 1) >= args.Length){
1103
Error_RequiresArgument (arg);
1104
return ParseResult.Error;
1106
settings.MainClass = args[++i];
1107
return ParseResult.Success;
1110
report.Warning (-29, 1, "Compatibility: Use -unsafe instead of --unsafe");
1111
settings.Unsafe = true;
1112
return ParseResult.Success;
1114
case "/?": case "/h": case "/help":
1117
return ParseResult.Stop;
1120
report.Warning (-29, 1, "Compatibility: Use -d:SYMBOL instead of --define SYMBOL");
1121
if ((i + 1) >= args.Length){
1122
Error_RequiresArgument (arg);
1123
return ParseResult.Error;
1126
settings.AddConditionalSymbol (args [++i]);
1127
return ParseResult.Success;
1130
settings.TokenizeOnly = true;
1131
return ParseResult.Success;
1135
report.Warning (-29, 1, "Compatibility: Use -out:FILE instead of --output FILE or -o FILE");
1136
if ((i + 1) >= args.Length){
1137
Error_RequiresArgument (arg);
1138
return ParseResult.Error;
1140
settings.OutputFile = args[++i];
1141
return ParseResult.Success;
1144
report.Warning (-29, 1, "Compatibility: Use -checked instead of --checked");
1145
settings.Checked = true;
1146
return ParseResult.Success;
1148
case "--stacktrace":
1149
report.Printer.Stacktrace = true;
1150
return ParseResult.Success;
1152
case "--linkresource":
1154
report.Warning (-29, 1, "Compatibility: Use -linkres:VALUE instead of --linkres VALUE");
1155
if ((i + 1) >= args.Length){
1156
Error_RequiresArgument (arg);
1157
return ParseResult.Error;
1160
AddResource (new AssemblyResource (args[++i], args[i]), settings);
1161
return ParseResult.Success;
1165
report.Warning (-29, 1, "Compatibility: Use -res:VALUE instead of --res VALUE");
1166
if ((i + 1) >= args.Length){
1167
Error_RequiresArgument (arg);
1168
return ParseResult.Error;
1171
AddResource (new AssemblyResource (args[++i], args[i], true), settings);
1172
return ParseResult.Success;
1175
report.Warning (-29, 1, "Compatibility: Use -target:KIND instead of --target KIND");
1176
if ((i + 1) >= args.Length){
1177
Error_RequiresArgument (arg);
1178
return ParseResult.Error;
1181
string type = args [++i];
1184
settings.Target = Target.Library;
1185
settings.TargetExt = ".dll";
1189
settings.Target = Target.Exe;
1193
settings.Target = Target.WinExe;
1197
settings.Target = Target.Module;
1198
settings.TargetExt = ".dll";
1201
report.Error (2019, "Invalid target type for -target. Valid options are `exe', `winexe', `library' or `module'");
1204
return ParseResult.Success;
1207
report.Warning (-29, 1, "Compatibility: Use -r:LIBRARY instead of -r library");
1208
if ((i + 1) >= args.Length){
1209
Error_RequiresArgument (arg);
1210
return ParseResult.Error;
1213
string val = args [++i];
1214
int idx = val.IndexOf ('=');
1216
string alias = val.Substring (0, idx);
1217
string assembly = val.Substring (idx + 1);
1218
AddAssemblyReference (alias, assembly, settings);
1219
return ParseResult.Success;
1222
settings.AssemblyReferences.Add (val);
1223
return ParseResult.Success;
1226
report.Warning (-29, 1, "Compatibility: Use -lib:ARG instead of --L arg");
1227
if ((i + 1) >= args.Length){
1228
Error_RequiresArgument (arg);
1229
return ParseResult.Error;
1231
settings.ReferencesLookupPaths.Add (args [++i]);
1232
return ParseResult.Success;
1235
settings.EnhancedWarnings = true;
1236
return ParseResult.Success;
1239
report.Warning (-29, 1, "Compatibility: Use -nostdlib instead of --nostdlib");
1240
settings.StdLib = false;
1241
return ParseResult.Success;
1244
report.Warning (-29, 1, "Compatibility: Use -nowarn instead of --nowarn");
1245
if ((i + 1) >= args.Length){
1246
Error_RequiresArgument (arg);
1247
return ParseResult.Error;
1252
warn = int.Parse (args [++i]);
1255
Environment.Exit (1);
1257
report.SetIgnoreWarning (warn);
1258
return ParseResult.Success;
1261
report.Warning (-29, 1, "Compatibility: Use -warn:LEVEL instead of --wlevel LEVEL");
1262
if ((i + 1) >= args.Length){
1263
Error_RequiresArgument (arg);
1264
return ParseResult.Error;
1267
SetWarningLevel (args [++i]);
1268
return ParseResult.Success;
1271
if ((i + 1) >= args.Length){
1272
Error_RequiresArgument (arg);
1273
return ParseResult.Error;
1277
settings.DebugFlags = int.Parse (args [++i]);
1279
Error_RequiresArgument (arg);
1280
return ParseResult.Error;
1283
return ParseResult.Success;
1287
return ParseResult.Stop;
1290
report.Warning (-29, 1, "Compatibility: Use -recurse:PATTERN option instead --recurse PATTERN");
1291
if ((i + 1) >= args.Length){
1292
Error_RequiresArgument (arg);
1293
return ParseResult.Error;
1295
ProcessSourceFiles (args [++i], true, settings.SourceFiles);
1296
return ParseResult.Success;
1299
settings.Timestamps = true;
1300
return ParseResult.Success;
1302
case "--debug": case "-g":
1303
report.Warning (-29, 1, "Compatibility: Use -debug option instead of -g or --debug");
1304
settings.GenerateDebugInfo = true;
1305
return ParseResult.Success;
1308
report.Warning (-29, 1, "Compatibility: Use -noconfig option instead of --noconfig");
1309
settings.LoadDefaultReferences = false;
1310
return ParseResult.Success;
1313
if (arg.StartsWith ("--fatal")){
1315
if (arg.StartsWith ("--fatal="))
1316
int.TryParse (arg.Substring (8), out fatal);
1318
report.Printer.FatalCounter = fatal;
1319
return ParseResult.Success;
1321
if (arg.StartsWith ("--runtime:", StringComparison.Ordinal)) {
1322
string version = arg.Substring (10);
1327
settings.StdLibRuntimeVersion = RuntimeVersion.v1;
1331
settings.StdLibRuntimeVersion = RuntimeVersion.v2;
1335
settings.StdLibRuntimeVersion = RuntimeVersion.v4;
1338
return ParseResult.Success;
1341
return ParseResult.UnknownOption;
1345
void SetWarningLevel (string s)
1350
level = int.Parse (s);
1353
if (level < 0 || level > 4) {
1354
report.Error (1900, "Warning level must be in the range 0-4");
1357
report.WarningLevel = level;
1361
// Given a path specification, splits the path from the file/pattern
1363
static void SplitPathAndPattern (string spec, out string path, out string pattern)
1365
int p = spec.LastIndexOf ('/');
1368
// Windows does not like /file.cs, switch that to:
1373
pattern = spec.Substring (1);
1375
path = spec.Substring (0, p);
1376
pattern = spec.Substring (p + 1);
1381
p = spec.LastIndexOf ('\\');
1383
path = spec.Substring (0, p);
1384
pattern = spec.Substring (p + 1);
1395
"Mono C# compiler, Copyright 2001 - 2011 Novell, Inc.\n" +
1396
"mcs [options] source-files\n" +
1397
" --about About the Mono C# compiler\n" +
1398
" -addmodule:M1[,Mn] Adds the module to the generated assembly\n" +
1399
" -checked[+|-] Sets default aritmetic overflow context\n" +
1400
" -clscheck[+|-] Disables CLS Compliance verifications\n" +
1401
" -codepage:ID Sets code page to the one in ID (number, utf8, reset)\n" +
1402
" -define:S1[;S2] Defines one or more conditional symbols (short: -d)\n" +
1403
" -debug[+|-], -g Generate debugging information\n" +
1404
" -delaysign[+|-] Only insert the public key into the assembly (no signing)\n" +
1405
" -doc:FILE Process documentation comments to XML file\n" +
1406
" -fullpaths Any issued error or warning uses absolute file path\n" +
1407
" -help Lists all compiler options (short: -?)\n" +
1408
" -keycontainer:NAME The key pair container used to sign the output assembly\n" +
1409
" -keyfile:FILE The key file used to strongname the ouput assembly\n" +
1410
" -langversion:TEXT Specifies language version: ISO-1, ISO-2, 3, Default or Future\n" +
1411
" -lib:PATH1[,PATHn] Specifies the location of referenced assemblies\n" +
1412
" -main:CLASS Specifies the class with the Main method (short: -m)\n" +
1413
" -noconfig Disables implicitly referenced assemblies\n" +
1414
" -nostdlib[+|-] Does not reference mscorlib.dll library\n" +
1415
" -nowarn:W1[,Wn] Suppress one or more compiler warnings\n" +
1416
" -optimize[+|-] Enables advanced compiler optimizations (short: -o)\n" +
1417
" -out:FILE Specifies output assembly name\n" +
1418
" -pkg:P1[,Pn] References packages P1..Pn\n" +
1419
" -platform:ARCH Specifies the target platform of the output assembly\n" +
1420
" ARCH can be one of: anycpu, x86, x64 or itanium\n" +
1421
" -recurse:SPEC Recursively compiles files according to SPEC pattern\n" +
1422
" -reference:A1[,An] Imports metadata from the specified assembly (short: -r)\n" +
1423
" -reference:ALIAS=A Imports metadata using specified extern alias (short: -r)\n" +
1424
" -sdk:VERSION Specifies SDK version of referenced assemblies\n" +
1425
" VERSION can be one of: 2, 4 (default) or custom value\n" +
1426
" -target:KIND Specifies the format of the output assembly (short: -t)\n" +
1427
" KIND can be one of: exe, winexe, library, module\n" +
1428
" -unsafe[+|-] Allows to compile code which uses unsafe keyword\n" +
1429
" -warnaserror[+|-] Treats all warnings as errors\n" +
1430
" -warnaserror[+|-]:W1[,Wn] Treats one or more compiler warnings as errors\n" +
1431
" -warn:0-4 Sets warning level, the default is 4 (short -w:)\n" +
1432
" -helpinternal Shows internal and advanced compiler options\n" +
1435
" -linkresource:FILE[,ID] Links FILE as a resource (short: -linkres)\n" +
1436
" -resource:FILE[,ID] Embed FILE as a resource (short: -res)\n" +
1437
" -win32res:FILE Specifies Win32 resource file (.res)\n" +
1438
" -win32icon:FILE Use this icon for the output\n" +
1439
" @file Read response file for more options\n\n" +
1440
"Options can be of the form -option or /option");
1445
string version = System.Reflection.MethodBase.GetCurrentMethod ().DeclaringType.Assembly.GetName ().Version.ToString ();
1446
output.WriteLine ("Mono C# compiler version {0}", version);
1450
public class RootContext
1453
// Contains the parsed tree
1455
static ModuleContainer root;
1457
static public ModuleContainer ToplevelTypes {
1458
get { return root; }
1459
set { root = value; }