protected override bool DoCompile(){
if (!this.isClosed && !this.isEngineCompiled){
this.SetUpCompilerEnvironment();
if (this.PEFileName == null){
// we use random default names to avoid overwriting cached assembly files when debugging VSA
this.PEFileName = this.GenerateRandomPEFileName();
}
this.SaveSourceForDebugging(); // Save sources needed for debugging (does nothing if no debug info)
this.numberOfErrors = 0; // Records number of errors during compilation.
this.isEngineCompiled = true; // OnCompilerError sets to false if it encounters an unrecoverable error.
Globals.ScopeStack.Push(this.GetGlobalScope().GetObject());
try{
try{
foreach (Object item in this.vsaItems){
Debug.Assert(item is VsaReference || item is VsaStaticCode || item is VsaHostObject);
if (item is VsaReference)
((VsaReference)item).Compile(); //Load the assembly into memory.
}
if (this.vsaItems.Count > 0)
this.SetEnclosingContext(new WrappedNamespace("", this)); //Provide a way to find types that are not inside of a name space
// Add VSA global items to the global scope
foreach (Object item in this.vsaItems){
if (item is VsaHostObject)
((VsaHostObject)item).Compile();
}
foreach (Object item in this.vsaItems){
if (item is VsaStaticCode)
((VsaStaticCode)item).Parse();
}
foreach (Object item in this.vsaItems){
if (item is VsaStaticCode)
((VsaStaticCode)item).ProcessAssemblyAttributeLists();
}
foreach (Object item in this.vsaItems){
if (item is VsaStaticCode)
((VsaStaticCode)item).PartiallyEvaluate();
}
foreach (Object item in this.vsaItems){
if (item is VsaStaticCode)
((VsaStaticCode)item).TranslateToIL();
}
foreach (Object item in this.vsaItems){
if (item is VsaStaticCode)
((VsaStaticCode)item).GetCompiledType();
}
if (null != this.globalScope)
this.globalScope.Compile(); //In case the host added items to the global scope
}catch(JScriptException se){
// It's a bit strange because we may be capturing an exception
// thrown by VsaEngine.OnCompilerError (in the case where
// this.engineSite is null. This is fine though. All we end up doing
// is capturing and then rethrowing the same error.
this.OnCompilerError(se);
}catch(System.IO.FileLoadException e){
JScriptException se = new JScriptException(JSError.ImplicitlyReferencedAssemblyNotFound);
se.value = e.FileName;
this.OnCompilerError(se);
this.isEngineCompiled = false;
}catch(EndOfFile){
// an error was reported during PartiallyEvaluate and the host decided to abort
// swallow the exception and keep going
}catch{
// internal compiler error -- make sure we don't claim to have compiled, then rethrow
this.isEngineCompiled = false;
throw;
}
}finally{
Globals.ScopeStack.Pop();
}
if (this.isEngineCompiled){
// there were no unrecoverable errors, but we want to return true only if there is IL
this.isEngineCompiled = (this.numberOfErrors == 0 || this.alwaysGenerateIL);
}
}
if (this.managedResources != null){
foreach (ResInfo managedResource in this.managedResources){
if (managedResource.isLinked){
this.CompilerGlobals.assemblyBuilder.AddResourceFile(managedResource.name,
Path.GetFileName(managedResource.filename),
managedResource.isPublic?
ResourceAttributes.Public:
ResourceAttributes.Private);
}else{
try{
using (ResourceReader reader = new ResourceReader(managedResource.filename))
{
IResourceWriter writer = this.CompilerGlobals.module.DefineResource(managedResource.name,
managedResource.filename,
managedResource.isPublic?
ResourceAttributes.Public:
ResourceAttributes.Private);
foreach (DictionaryEntry resource in reader)
writer.AddResource((string)resource.Key, resource.Value);
}
}catch(System.ArgumentException){
JScriptException se = new JScriptException(JSError.InvalidResource);
se.value = managedResource.filename;
this.OnCompilerError(se);
this.isEngineCompiled = false;
return false;
}
}
}
}
if (this.isEngineCompiled)
this.EmitReferences();
// Save things out to a local PE file when doSaveAfterCompile is set; this is set when an
// output name is given (allows JSC to avoid IVsaEngine.SaveCompiledState). The proper
// values for VSA are doSaveAfterCompile == false and genStartupClass == true. We allow
// genStartupClass to be false for scenarios like JSTest and the Debugger
if (this.isEngineCompiled){
if (this.doSaveAfterCompile){
if (this.PEFileKind != PEFileKinds.Dll)
this.CreateMain();
// After executing this code path, it is an error to call SaveCompiledState (until the engine is recompiled)
try{
compilerGlobals.assemblyBuilder.Save(Path.GetFileName(this.PEFileName),
this.PEKindFlags, this.PEMachineArchitecture);
}catch(Exception e){
throw new VsaException(VsaError.SaveCompiledStateFailed, e.Message, e);
}catch{
throw new VsaException(VsaError.SaveCompiledStateFailed);
}
}else if (this.genStartupClass){
// this is generated for VSA hosting
this.CreateStartupClass();
}
}
return this.isEngineCompiled;
}