using System.Text;
using System.Globalization;
using System.Diagnostics;
+using System.Threading;
namespace Mono.CSharp
{
}
}
- void tokenize_file (CompilationSourceFile 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 (module.Compiler.SourceFiles);
-
bool tokenize_only = module.Compiler.Settings.TokenizeOnly;
var sources = module.Compiler.SourceFiles;
+
+ Location.Initialize (sources);
+
+ var session = new ParserSession {
+ UseJayGlobalArrays = true,
+ LocatedTokens = new LocatedToken[15000]
+ };
+
for (int i = 0; i < sources.Count; ++i) {
if (tokenize_only) {
- tokenize_file (sources[i]);
+ tokenize_file (sources[i], module, session);
} else {
- Parse (sources[i], module);
+ Parse (sources[i], module, session, Report);
}
}
}
- public void Parse (CompilationSourceFile 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, CompilationSourceFile file, ModuleContainer module)
+ }
+
+ public static void Parse (SeekableStreamReader reader, SourceFile sourceFile, ModuleContainer module, ParserSession session, Report report)
{
- file.NamespaceContainer = new NamespaceContainer (null, module, null, file);
+ var file = new CompilationSourceFile (module, sourceFile);
+ module.AddTypeContainer (file);
- CSharpParser parser = new CSharpParser (reader, 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) {
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 ();
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);
tr.Stop (TimeReporter.TimerType.CreateTypeTotal);
if (!assembly.Create (AppDomain.CurrentDomain, AssemblyBuilderAccess.Save))
return false;
- module.CreateType ();
+ module.CreateContainer ();
loader.LoadModules (assembly, module.GlobalRootNamespace);
#endif
module.InitializePredefinedTypes ();
- tr.Start (TimeReporter.TimerType.UsingResolve);
- foreach (var source_file in ctx.SourceFiles) {
- source_file.NamespaceContainer.Resolve ();
- }
- tr.Stop (TimeReporter.TimerType.UsingResolve);
-
tr.Start (TimeReporter.TimerType.ModuleDefinitionTotal);
module.Define ();
tr.Stop (TimeReporter.TimerType.ModuleDefinitionTotal);
}
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;
- AnonymousTypeClass.Reset ();
- AnonymousMethodBody.Reset ();
- AnonymousMethodStorey.Reset ();
- SymbolWriter.Reset ();
- Switch.Reset ();
Linq.QueryBlock.TransparentParameter.Reset ();
TypeInfo.Reset ();
}