public override void CompileParseTree(Compilation compilation, ErrorNodeList errorNodes)
{
TrivialHashtable ambiguousTypes = new TrivialHashtable();
TrivialHashtable scopeFor = new TrivialHashtable();
TrivialHashtable referencedLabels = new TrivialHashtable();
Hashtable exceptionNames = new Hashtable();
ErrorHandler errorHandler = new ErrorHandler(errorNodes);
string target = "";
ZingCompilerOptions zoptions = compilation.CompilerParameters as ZingCompilerOptions;
if (zoptions != null && zoptions.DumpSource)
{
target = compilation.CompilerParameters.OutputAssembly;
if (string.IsNullOrEmpty(target))
{
target = Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar;
}
string output = Path.GetDirectoryName(target);
if (string.IsNullOrEmpty(output)) output = Directory.GetCurrentDirectory();
target = Path.GetFileNameWithoutExtension(target);
}
if (this.Options == null)
this.Options = compilation.CompilerParameters;
//Attach scopes to namespaces and types so that forward references to base types can be looked up in the appropriate namespace scope
Scoper scoper = new Scoper(scopeFor);
scoper.VisitCompilation(compilation);
//Walk IR looking up names
TypeSystem typeSystem = new TypeSystem(errorHandler);
Looker looker = new Looker(compilation.GlobalScope, errorHandler, scopeFor, typeSystem, // LJW: added typeSystem
ambiguousTypes, referencedLabels, exceptionNames);
looker.VisitCompilation(compilation);
//Walk IR inferring types and resolving overloads
Resolver resolver = new Resolver(errorHandler, typeSystem);
resolver.VisitCompilation(compilation);
Checker checker = new Checker(errorHandler, typeSystem, scopeFor, ambiguousTypes, referencedLabels); // LJW: added scopeFor
checker.VisitCompilation(compilation);
// Walk the Zing IR splicing it into our code-gen templates
Splicer splicer = new Splicer(this.Options, referencedLabels, exceptionNames);
CompilationUnit cuMerged = splicer.CodeGen(compilation);
//
// If the 'dumpSource' option is given, then we decompile the IR to C# and write this
// to a file.
//
if (zoptions != null && zoptions.DumpSource)
{
// Once the codegen is done and we have the IR for the generated code, we use the
// decompiler to get C# back out, and hand this to the standard compiler. Later,
// we'll replace this with the X# normalizer and avoid going in and out of source
// code (except for compiler debugging).
string tempSrc;
string tempName = compilation.CompilerParameters.OutputAssembly + ".cs";
Decompiler decompiler = new Decompiler();
tempSrc = decompiler.Decompile(cuMerged);
StreamWriter sw = File.CreateText(tempName);
sw.Write(tempSrc);
sw.Close();
}
if (zoptions != null && zoptions.DumpLabels)
{
string tempName = compilation.CompilerParameters.OutputAssembly + ".labels";
StreamWriter sw = File.CreateText(tempName);
sw.Write(splicer.LabelString);
sw.Close();
}
for (int i = 0; i < RequiredTypes.Length; i++)
{
R.Assembly asm = R.Assembly.GetAssembly(RequiredTypes[i]);
if (!compilation.CompilerParameters.ReferencedAssemblies.Contains(asm.Location))
compilation.CompilerParameters.ReferencedAssemblies.Add(asm.Location);
}
// The if-statement added by Jiri Adamek
// It loads a native ZOM assembly if used
if (zoptions != null && zoptions.ZomAssemblyName != null)
{
compilation.CompilerParameters.ReferencedAssemblies.Add(zoptions.ZomAssemblyName);
}
CS.Compiler csCompiler = new CS.Compiler();
// We have to create a new module to pull in references from the
// assemblies we just added above.
compilation.TargetModule = this.targetModule =
csCompiler.CreateModule(compilation.CompilerParameters, errorNodes);
// Our one top-level type must be added to the module's type list
compilation.TargetModule.Types.Add(((Namespace)cuMerged.Nodes[0]).NestedNamespaces[0].Types[0]);
// The restorer patches the DeclaringModule field of our types
Restorer restorer = new Restorer(compilation.TargetModule);
restorer.VisitCompilationUnit(cuMerged);
// Replace the Zing compilation unit with our generated code before invoking
// the Spec# back end.
compilation.CompilationUnits = new CompilationUnitList(cuMerged);
foreach (CompilationUnit cunit in compilation.CompilationUnits)
cunit.Compilation = compilation;
// For retail builds, disable the time-consuming definite-assignment checks
// in the Spec# compiler.
if (!this.Options.IncludeDebugInformation)
compilation.CompilationUnits[0].PreprocessorDefinedSymbols["NODEFASSIGN"] = "true";
// Let the Spec# back end process the IR from here
csCompiler.CompileParseTree(compilation, errorNodes);
}