//
// Copyright 2001, 2002, 2003 Ximian, Inc (http://www.ximian.com)
// Copyright 2004, 2005, 2006, 2007, 2008 Novell, Inc
+// Copyright 2011 Xamarin Inc
//
using System;
using System.Text;
using System.Globalization;
using System.Diagnostics;
+using System.Threading;
namespace Mono.CSharp
{
}
}
- void tokenize_file (CompilationUnit file)
+ void tokenize_file (SourceFile sourceFile, ModuleContainer module, ParserSession session)
{
Stream input;
try {
- input = File.OpenRead (file.Name);
+ input = File.OpenRead (sourceFile.Name);
} catch {
- Report.Error (2001, "Source file `" + file.Name + "' could not be found");
+ Report.Error (2001, "Source file `" + sourceFile.Name + "' could not be found");
return;
}
using (input){
SeekableStreamReader reader = new SeekableStreamReader (input, ctx.Settings.Encoding);
- Tokenizer lexer = new Tokenizer (reader, file, ctx);
+ var file = new CompilationSourceFile (module, sourceFile);
+
+ Tokenizer lexer = new Tokenizer (reader, file, session, ctx.Report);
int token, tokens = 0, errors = 0;
while ((token = lexer.token ()) != Token.EOF){
void Parse (ModuleContainer module)
{
- Location.Initialize ();
+ bool tokenize_only = module.Compiler.Settings.TokenizeOnly;
+ var sources = module.Compiler.SourceFiles;
+
+ Location.Initialize (sources);
- bool tokenize_only = ctx.Settings.TokenizeOnly;
- var cu = Location.SourceFiles;
- for (int i = 0; i < cu.Count; ++i) {
+ var session = new ParserSession {
+ UseJayGlobalArrays = true,
+ LocatedTokens = new LocatedToken[15000]
+ };
+
+ for (int i = 0; i < sources.Count; ++i) {
if (tokenize_only) {
- tokenize_file (cu[i]);
+ tokenize_file (sources[i], module, session);
} else {
- Parse (cu[i], module);
+ Parse (sources[i], module, session, Report);
}
}
}
- void Parse (CompilationUnit file, ModuleContainer module)
+#if false
+ void ParseParallel (ModuleContainer module)
+ {
+ var sources = module.Compiler.SourceFiles;
+
+ Location.Initialize (sources);
+
+ var pcount = Environment.ProcessorCount;
+ var threads = new Thread[System.Math.Max (2, pcount - 1)];
+
+ for (int i = 0; i < threads.Length; ++i) {
+ var t = new Thread (l => {
+ var session = new ParserSession () {
+ //UseJayGlobalArrays = true,
+ };
+
+ var report = new Report (ctx, Report.Printer); // TODO: Implement flush at once printer
+
+ for (int ii = (int) l; ii < sources.Count; ii += threads.Length) {
+ Parse (sources[ii], module, session, report);
+ }
+
+ // TODO: Merge warning regions
+ });
+
+ t.Start (i);
+ threads[i] = t;
+ }
+
+ for (int t = 0; t < threads.Length; ++t) {
+ threads[t].Join ();
+ }
+ }
+#endif
+
+ public void Parse (SourceFile file, ModuleContainer module, ParserSession session, Report report)
{
Stream input;
try {
input = File.OpenRead (file.Name);
} catch {
- Report.Error (2001, "Source file `{0}' could not be found", file.Name);
+ report.Error (2001, "Source file `{0}' could not be found", file.Name);
return;
}
// Check 'MZ' header
if (input.ReadByte () == 77 && input.ReadByte () == 90) {
- Report.Error (2015, "Source file `{0}' is a binary file and not a text file", file.Name);
+
+ report.Error (2015, "Source file `{0}' is a binary file and not a text file", file.Name);
input.Close ();
return;
}
input.Position = 0;
- SeekableStreamReader reader = new SeekableStreamReader (input, ctx.Settings.Encoding);
+ SeekableStreamReader reader = new SeekableStreamReader (input, ctx.Settings.Encoding, session.StreamReaderBuffer);
+
+ Parse (reader, file, module, session, report);
+
+ if (ctx.Settings.GenerateDebugInfo && report.Errors == 0 && !file.HasChecksum) {
+ input.Position = 0;
+ var checksum = session.GetChecksumAlgorithm ();
+ file.SetChecksum (checksum.ComputeHash (input));
+ }
- Parse (reader, file, module);
reader.Dispose ();
input.Close ();
- }
-
- public void Parse (SeekableStreamReader reader, CompilationUnit file, ModuleContainer module)
+ }
+
+ public static void Parse (SeekableStreamReader reader, SourceFile sourceFile, ModuleContainer module, ParserSession session, Report report)
{
- CSharpParser parser = new CSharpParser (reader, file, module);
+ var file = new CompilationSourceFile (module, sourceFile);
+ module.AddTypeContainer (file);
+
+ CSharpParser parser = new CSharpParser (reader, file, report, session);
parser.parse ();
}
{
Location.InEmacs = Environment.GetEnvironmentVariable ("EMACS") == "t";
- var r = new Report (new ConsoleReportPrinter ());
- CommandLineParser cmd = new CommandLineParser (r);
+ CommandLineParser cmd = new CommandLineParser (Console.Out);
var settings = cmd.ParseArguments (args);
- if (settings == null || r.Errors > 0)
+ if (settings == null)
return 1;
if (cmd.HasBeenStopped)
return 0;
- Driver d = new Driver (new CompilerContext (settings, r));
+ Driver d = new Driver (new CompilerContext (settings, new ConsoleReportPrinter ()));
if (d.Compile () && d.Report.Errors == 0) {
if (d.Report.Warnings > 0) {
public static string GetPackageFlags (string packages, Report report)
{
+#if MONO_FEATURE_PROCESS_START
ProcessStartInfo pi = new ProcessStartInfo ();
pi.FileName = "pkg-config";
pi.RedirectStandardOutput = true;
p.Close ();
return pkgout;
+#else
+ throw new NotSupportedException ("Process.Start is not supported on this platform.");
+#endif // MONO_FEATURE_PROCESS_START
}
//
// If we are an exe, require a source file for the entry point or
// if there is nothing to put in the assembly, and we are not a library
//
- if (Location.FirstFile == null &&
+ if (settings.FirstSourceFile == null &&
((settings.Target == Target.Exe || settings.Target == Target.WinExe || settings.Target == Target.Module) ||
settings.Resources == null)) {
Report.Error (2008, "No files to compile were specified");
return false;
}
+ if (settings.Platform == Platform.AnyCPU32Preferred && (settings.Target == Target.Library || settings.Target == Target.Module)) {
+ Report.Error (4023, "Platform option `anycpu32bitpreferred' is valid only for executables");
+ return false;
+ }
+
TimeReporter tr = new TimeReporter (settings.Timestamps);
ctx.TimeReporter = tr;
tr.StartTotal ();
if (Report.Errors > 0)
return false;
- if (settings.TokenizeOnly || settings.ParseOnly)
+ if (settings.TokenizeOnly || settings.ParseOnly) {
+ tr.StopTotal ();
+ tr.ShowStats ();
return true;
-
- if (RootContext.ToplevelTypes.NamespaceEntry != null)
- throw new InternalErrorException ("who set it?");
+ }
var output_file = settings.OutputFile;
string output_file_name;
if (output_file == null) {
- output_file_name = Location.FirstFile;
+ var source_file = settings.FirstSourceFile;
- if (output_file_name == null) {
+ if (source_file == null) {
Report.Error (1562, "If no source files are specified you must specify the output file with -out:");
return false;
}
+ output_file_name = source_file.Name;
int pos = output_file_name.LastIndexOf ('.');
if (pos > 0)
output_file = output_file_name;
} else {
output_file_name = Path.GetFileName (output_file);
+
+ if (string.IsNullOrEmpty (Path.GetFileNameWithoutExtension (output_file_name)) ||
+ output_file_name.IndexOfAny (Path.GetInvalidFileNameChars ()) >= 0) {
+ Report.Error (2021, "Output file name is not valid");
+ return false;
+ }
}
#if STATIC
// loaded assembly into compiled builder to be resolved
// correctly
tr.Start (TimeReporter.TimerType.CreateTypeTotal);
- module.CreateType ();
+ module.CreateContainer ();
importer.AddCompiledAssembly (assembly);
+ references_loader.CompiledAssembly = assembly;
tr.Stop (TimeReporter.TimerType.CreateTypeTotal);
references_loader.LoadReferences (module);
tr.Start (TimeReporter.TimerType.PredefinedTypesInit);
- if (!ctx.BuildinTypes.CheckDefinitions (module))
+ if (!ctx.BuiltinTypes.CheckDefinitions (module))
return false;
tr.Stop (TimeReporter.TimerType.PredefinedTypesInit);
var assembly = new AssemblyDefinitionDynamic (module, output_file_name, output_file);
module.SetDeclaringAssembly (assembly);
- var importer = new ReflectionImporter (module, ctx.BuildinTypes);
+ var importer = new ReflectionImporter (module, ctx.BuiltinTypes);
assembly.Importer = importer;
var loader = new DynamicLoader (importer, ctx);
loader.LoadReferences (module);
- if (!ctx.BuildinTypes.CheckDefinitions (module))
+ if (!ctx.BuiltinTypes.CheckDefinitions (module))
return false;
if (!assembly.Create (AppDomain.CurrentDomain, AssemblyBuilderAccess.Save))
return false;
- module.CreateType ();
+ module.CreateContainer ();
loader.LoadModules (assembly, module.GlobalRootNamespace);
#endif
+ module.InitializePredefinedTypes ();
+
+ if (settings.GetResourceStrings != null)
+ module.LoadGetResourceStrings (settings.GetResourceStrings);
+
tr.Start (TimeReporter.TimerType.ModuleDefinitionTotal);
module.Define ();
tr.Stop (TimeReporter.TimerType.ModuleDefinitionTotal);
if (Report.Errors > 0)
return false;
- if (settings.Documentation != null &&
- !settings.Documentation.OutputDocComment (
- output_file, Report))
- return false;
-
- //
- // Verify using aliases now
- //
- tr.Start (TimeReporter.TimerType.UsingVerification);
- NamespaceEntry.VerifyAllUsing ();
- tr.Stop (TimeReporter.TimerType.UsingVerification);
-
- if (Report.Errors > 0){
- return false;
+ if (settings.DocumentationFile != null) {
+ var doc = new DocumentationBuilder (module);
+ doc.OutputDocComment (output_file, settings.DocumentationFile);
}
assembly.Resolve ();
}
tr.Start (TimeReporter.TimerType.CloseTypes);
- module.CloseType ();
+ module.CloseContainer ();
tr.Stop (TimeReporter.TimerType.CloseTypes);
tr.Start (TimeReporter.TimerType.Resouces);
- assembly.EmbedResources ();
+ if (!settings.WriteMetadataOnly)
+ assembly.EmbedResources ();
tr.Stop (TimeReporter.TimerType.Resouces);
if (Report.Errors > 0)
public static bool InvokeCompiler (string [] args, TextWriter error)
{
try {
- var r = new Report (new StreamReportPrinter (error));
- CommandLineParser cmd = new CommandLineParser (r, error);
+ CommandLineParser cmd = new CommandLineParser (error);
var setting = cmd.ParseArguments (args);
- if (setting == null || r.Errors > 0)
+ if (setting == null)
return false;
- var d = new Driver (new CompilerContext (setting, r));
+ var d = new Driver (new CompilerContext (setting, new StreamReportPrinter (error)));
return d.Compile ();
} finally {
Reset ();
public static void Reset (bool full_flag)
{
- CSharpParser.yacc_verbose_flag = 0;
Location.Reset ();
if (!full_flag)
return;
- RootContext.Reset (full_flag);
- TypeManager.Reset ();
- ReferenceContainer.Reset ();
- PointerContainer.Reset ();
- Parameter.Reset ();
-
- CastFromDecimal.Reset ();
- StringConcat.Reset ();
-
- NamespaceEntry.Reset ();
- Attribute.Reset ();
- AnonymousTypeClass.Reset ();
- AnonymousMethodBody.Reset ();
- AnonymousMethodStorey.Reset ();
- SymbolWriter.Reset ();
- Switch.Reset ();
Linq.QueryBlock.TransparentParameter.Reset ();
- Convert.Reset ();
TypeInfo.Reset ();
}
}