2
// driver.cs: The compiler command line driver.
5
// Miguel de Icaza (miguel@gnu.org)
6
// Marek Safar (marek.safar@gmail.com)
8
// Dual licensed under the terms of the MIT X11 or GNU GPL
10
// Copyright 2001, 2002, 2003 Ximian, Inc (http://www.ximian.com)
11
// Copyright 2004, 2005, 2006, 2007, 2008 Novell, Inc
12
// Copyright 2011 Xamarin Inc
16
using System.Reflection;
17
using System.Reflection.Emit;
18
using System.Collections.Generic;
21
using System.Globalization;
22
using System.Diagnostics;
27
/// The compiler driver.
31
readonly CompilerContext ctx;
33
public Driver (CompilerContext ctx)
44
void tokenize_file (SourceFile sourceFile, ModuleContainer module)
49
input = File.OpenRead (sourceFile.Name);
51
Report.Error (2001, "Source file `" + sourceFile.Name + "' could not be found");
56
SeekableStreamReader reader = new SeekableStreamReader (input, ctx.Settings.Encoding);
57
var file = new CompilationSourceFile (module, sourceFile);
59
Tokenizer lexer = new Tokenizer (reader, file);
60
int token, tokens = 0, errors = 0;
62
while ((token = lexer.token ()) != Token.EOF){
64
if (token == Token.ERROR)
67
Console.WriteLine ("Tokenized: " + tokens + " found " + errors + " errors");
73
void Parse (ModuleContainer module)
75
bool tokenize_only = module.Compiler.Settings.TokenizeOnly;
76
var sources = module.Compiler.SourceFiles;
78
Location.Initialize (sources);
80
for (int i = 0; i < sources.Count; ++i) {
82
tokenize_file (sources[i], module);
84
Parse (sources[i], module);
89
public void Parse (SourceFile file, ModuleContainer module)
94
input = File.OpenRead (file.Name);
96
Report.Error (2001, "Source file `{0}' could not be found", file.Name);
101
if (input.ReadByte () == 77 && input.ReadByte () == 90) {
103
Report.Error (2015, "Source file `{0}' is a binary file and not a text file", file.Name);
109
SeekableStreamReader reader = new SeekableStreamReader (input, ctx.Settings.Encoding);
111
Parse (reader, file, module);
116
public static CSharpParser Parse(SeekableStreamReader reader, SourceFile sourceFile, ModuleContainer module, int lineModifier = 0)
118
var file = new CompilationSourceFile (module, sourceFile);
119
module.AddTypeContainer(file);
121
CSharpParser parser = new CSharpParser (reader, file);
122
parser.Lexer.Line += lineModifier;
123
parser.Lexer.sbag = new SpecialsBag ();
128
public static int Main (string[] args)
130
Location.InEmacs = Environment.GetEnvironmentVariable ("EMACS") == "t";
132
CommandLineParser cmd = new CommandLineParser (Console.Out);
133
var settings = cmd.ParseArguments (args);
134
if (settings == null)
137
if (cmd.HasBeenStopped)
140
Driver d = new Driver (new CompilerContext (settings, new ConsoleReportPrinter ()));
142
if (d.Compile () && d.Report.Errors == 0) {
143
if (d.Report.Warnings > 0) {
144
Console.WriteLine ("Compilation succeeded - {0} warning(s)", d.Report.Warnings);
146
Environment.Exit (0);
151
Console.WriteLine("Compilation failed: {0} error(s), {1} warnings",
152
d.Report.Errors, d.Report.Warnings);
153
Environment.Exit (1);
157
public static string GetPackageFlags (string packages, Report report)
159
ProcessStartInfo pi = new ProcessStartInfo ();
160
pi.FileName = "pkg-config";
161
pi.RedirectStandardOutput = true;
162
pi.UseShellExecute = false;
163
pi.Arguments = "--libs " + packages;
166
p = Process.Start (pi);
167
} catch (Exception e) {
171
report.Error (-27, "Couldn't run pkg-config: " + e.Message);
175
if (p.StandardOutput == null) {
177
throw new ApplicationException ("Specified package did not return any information");
179
report.Warning (-27, 1, "Specified package did not return any information");
184
string pkgout = p.StandardOutput.ReadToEnd ();
186
if (p.ExitCode != 0) {
188
throw new ApplicationException (pkgout);
190
report.Error (-27, "Error running pkg-config. Check the above output.");
200
// Main compilation method
202
public bool Compile ()
204
var settings = ctx.Settings;
207
// If we are an exe, require a source file for the entry point or
208
// if there is nothing to put in the assembly, and we are not a library
210
if (settings.FirstSourceFile == null &&
211
((settings.Target == Target.Exe || settings.Target == Target.WinExe || settings.Target == Target.Module) ||
212
settings.Resources == null)) {
213
Report.Error (2008, "No files to compile were specified");
217
if (settings.Platform == Platform.AnyCPU32Preferred && (settings.Target == Target.Library || settings.Target == Target.Module)) {
218
Report.Error (4023, "Platform option `anycpu32bitpreferred' is valid only for executables");
222
TimeReporter tr = new TimeReporter (settings.Timestamps);
223
ctx.TimeReporter = tr;
226
var module = new ModuleContainer (ctx);
227
RootContext.ToplevelTypes = module;
229
tr.Start (TimeReporter.TimerType.ParseTotal);
231
tr.Stop (TimeReporter.TimerType.ParseTotal);
233
if (Report.Errors > 0)
236
if (settings.TokenizeOnly || settings.ParseOnly) {
242
var output_file = settings.OutputFile;
243
string output_file_name;
244
if (output_file == null) {
245
var source_file = settings.FirstSourceFile;
247
if (source_file == null) {
248
Report.Error (1562, "If no source files are specified you must specify the output file with -out:");
252
output_file_name = source_file.Name;
253
int pos = output_file_name.LastIndexOf ('.');
256
output_file_name = output_file_name.Substring (0, pos);
258
output_file_name += settings.TargetExt;
259
output_file = output_file_name;
261
output_file_name = Path.GetFileName (output_file);
263
if (string.IsNullOrEmpty (Path.GetFileNameWithoutExtension (output_file_name)) ||
264
output_file_name.IndexOfAny (Path.GetInvalidFileNameChars ()) >= 0) {
265
Report.Error (2021, "Output file name is not valid");
271
var importer = new StaticImporter (module);
272
var references_loader = new StaticLoader (importer, ctx);
274
tr.Start (TimeReporter.TimerType.AssemblyBuilderSetup);
275
var assembly = new AssemblyDefinitionStatic (module, references_loader, output_file_name, output_file);
276
assembly.Create (references_loader.Domain);
277
tr.Stop (TimeReporter.TimerType.AssemblyBuilderSetup);
279
// Create compiler types first even before any referenced
280
// assembly is loaded to allow forward referenced types from
281
// loaded assembly into compiled builder to be resolved
283
tr.Start (TimeReporter.TimerType.CreateTypeTotal);
284
module.CreateContainer ();
285
importer.AddCompiledAssembly (assembly);
286
tr.Stop (TimeReporter.TimerType.CreateTypeTotal);
288
references_loader.LoadReferences (module);
290
tr.Start (TimeReporter.TimerType.PredefinedTypesInit);
291
if (!ctx.BuiltinTypes.CheckDefinitions (module))
294
tr.Stop (TimeReporter.TimerType.PredefinedTypesInit);
296
references_loader.LoadModules (assembly, module.GlobalRootNamespace);
298
var assembly = new AssemblyDefinitionDynamic (module, output_file_name, output_file);
299
module.SetDeclaringAssembly (assembly);
301
var importer = new ReflectionImporter (module, ctx.BuiltinTypes);
302
assembly.Importer = importer;
304
var loader = new DynamicLoader (importer, ctx);
305
loader.LoadReferences (module);
307
if (!ctx.BuiltinTypes.CheckDefinitions (module))
310
if (!assembly.Create (AppDomain.CurrentDomain, AssemblyBuilderAccess.Save))
313
module.CreateContainer ();
315
loader.LoadModules (assembly, module.GlobalRootNamespace);
317
module.InitializePredefinedTypes ();
319
tr.Start (TimeReporter.TimerType.ModuleDefinitionTotal);
321
tr.Stop (TimeReporter.TimerType.ModuleDefinitionTotal);
323
if (Report.Errors > 0)
326
if (settings.DocumentationFile != null) {
327
var doc = new DocumentationBuilder (module);
328
doc.OutputDocComment (output_file, settings.DocumentationFile);
333
if (Report.Errors > 0)
337
tr.Start (TimeReporter.TimerType.EmitTotal);
339
tr.Stop (TimeReporter.TimerType.EmitTotal);
341
if (Report.Errors > 0){
345
tr.Start (TimeReporter.TimerType.CloseTypes);
346
module.CloseContainer ();
347
tr.Stop (TimeReporter.TimerType.CloseTypes);
349
tr.Start (TimeReporter.TimerType.Resouces);
350
assembly.EmbedResources ();
351
tr.Stop (TimeReporter.TimerType.Resouces);
353
if (Report.Errors > 0)
359
references_loader.Dispose ();
364
return Report.Errors == 0;
368
public class CompilerCompilationUnit {
369
public ModuleContainer ModuleCompiled { get; set; }
370
public LocationsBag LocationsBag { get; set; }
371
public SpecialsBag SpecialsBag { get; set; }
372
public object LastYYValue { get; set; }
376
// This is the only public entry point
378
public class CompilerCallableEntryPoint : MarshalByRefObject
380
public static bool InvokeCompiler (string [] args, TextWriter error)
383
CommandLineParser cmd = new CommandLineParser (error);
384
var setting = cmd.ParseArguments (args);
388
var d = new Driver (new CompilerContext (setting, new StreamReportPrinter (error)));
395
public static int[] AllWarningNumbers {
397
return Report.AllWarnings;
401
public static void Reset ()
406
public static void PartialReset ()
411
public static void Reset (bool full_flag)
418
Linq.QueryBlock.TransparentParameter.Reset ();