private Assembly CompileAssembly(List <ScriptClass> scriptsForLang) { TempFileCollection allTempFiles = compiler.CompilerResults.TempFiles; CompilerErrorCollection allErrors = compiler.CompilerResults.Errors; ScriptClass lastScript = scriptsForLang[scriptsForLang.Count - 1]; CodeDomProvider provider; bool isVB = false; try { provider = lastScript.compilerInfo.CreateProvider(); } catch (ConfigurationException e) { // The CodeDom provider type could not be located, or some error in machine.config allErrors.Add(compiler.CreateError(lastScript.EndLineInfo, /*[XT_041]*/ Res.Xslt_ScriptCompileException, e.Message)); return(null); } #if !FEATURE_PAL // visualbasic isVB = provider is Microsoft.VisualBasic.VBCodeProvider; #endif // !FEATURE_PAL CodeCompileUnit[] codeUnits = new CodeCompileUnit[scriptsForLang.Count]; CompilerParameters compilParams = lastScript.compilerInfo.CreateDefaultCompilerParameters(); // compilParams.ReferencedAssemblies.Add(typeof(System.Xml.Res).Assembly.Location); compilParams.ReferencedAssemblies.Add("System.dll"); if (isVB) { compilParams.ReferencedAssemblies.Add("Microsoft.VisualBasic.dll"); } bool refAssembliesByHref = false; for (int idx = 0; idx < scriptsForLang.Count; idx++) { ScriptClass script = scriptsForLang[idx]; CodeNamespace scriptNs = new CodeNamespace(ScriptClassesNamespace); // Add imported namespaces foreach (string ns in defaultNamespaces) { scriptNs.Imports.Add(new CodeNamespaceImport(ns)); } if (isVB) { scriptNs.Imports.Add(new CodeNamespaceImport("Microsoft.VisualBasic")); } foreach (string ns in script.nsImports) { scriptNs.Imports.Add(new CodeNamespaceImport(ns)); } scriptNs.Types.Add(script.typeDecl); CodeCompileUnit unit = new CodeCompileUnit(); { unit.Namespaces.Add(scriptNs); if (isVB) { // This settings have sense for Visual Basic only. In future releases we may allow to specify // them explicitly in the msxsl:script element. unit.UserData["AllowLateBound"] = true; // Allow variables to be declared untyped unit.UserData["RequireVariableDeclaration"] = false; // Allow variables to be undeclared } // Put SecurityTransparentAttribute and SecurityRulesAttribute on the first CodeCompileUnit only if (idx == 0) { unit.AssemblyCustomAttributes.Add(new CodeAttributeDeclaration("System.Security.SecurityTransparentAttribute")); // We want the assemblies generated for scripts to stick to the old security model unit.AssemblyCustomAttributes.Add( new CodeAttributeDeclaration( new CodeTypeReference(typeof(System.Security.SecurityRulesAttribute)), new CodeAttributeArgument( new CodeFieldReferenceExpression( new CodeTypeReferenceExpression(typeof(System.Security.SecurityRuleSet)), "Level1")))); } } codeUnits[idx] = unit; foreach (string name in script.refAssemblies) { compilParams.ReferencedAssemblies.Add(name); } refAssembliesByHref |= script.refAssembliesByHref; } XsltSettings settings = compiler.Settings; compilParams.WarningLevel = settings.WarningLevel >= 0 ? settings.WarningLevel : compilParams.WarningLevel; compilParams.TreatWarningsAsErrors = settings.TreatWarningsAsErrors; compilParams.IncludeDebugInformation = compiler.IsDebug; string asmPath = compiler.ScriptAssemblyPath; if (asmPath != null && scriptsForLang.Count < scriptClasses.Count) { asmPath = Path.ChangeExtension(asmPath, "." + GetLanguageName(lastScript.compilerInfo) + Path.GetExtension(asmPath)); } compilParams.OutputAssembly = asmPath; string tempDir = (settings.TempFiles != null) ? settings.TempFiles.TempDir : null; compilParams.TempFiles = new TempFileCollection(tempDir); // We need only .dll and .pdb, but there is no way to specify that bool keepFiles = (compiler.IsDebug && asmPath == null); #if DEBUG keepFiles = keepFiles || XmlILTrace.IsEnabled; #endif keepFiles = keepFiles && !settings.CheckOnly; compilParams.TempFiles.KeepFiles = keepFiles; // If GenerateInMemory == true, then CodeDom loads the compiled assembly using Assembly.Load(byte[]) // instead of Assembly.Load(AssemblyName). That means the assembly will be loaded in the anonymous // context (http://blogs.msdn.com/Microsoft/archive/2003/05/29/57143.aspx), and its dependencies can only // be loaded from the Load context or using AssemblyResolve event. However we want to use the LoadFrom // context to preload all dependencies specified by <ms:assembly href="uri-reference"/>, so we turn off // GenerateInMemory here. compilParams.GenerateInMemory = (asmPath == null && !compiler.IsDebug && !refAssembliesByHref) || settings.CheckOnly; CompilerResults results; try { results = provider.CompileAssemblyFromDom(compilParams, codeUnits); } catch (ExternalException e) { // Compiler might have created temporary files results = new CompilerResults(compilParams.TempFiles); results.Errors.Add(compiler.CreateError(lastScript.EndLineInfo, /*[XT_041]*/ Res.Xslt_ScriptCompileException, e.Message)); } if (!settings.CheckOnly) { foreach (string fileName in results.TempFiles) { allTempFiles.AddFile(fileName, allTempFiles.KeepFiles); } } foreach (CompilerError error in results.Errors) { FixErrorPosition(error, scriptsForLang); compiler.AddModule(error.FileName); } allErrors.AddRange(results.Errors); return(results.Errors.HasErrors ? null : results.CompiledAssembly); }
private Type CompileClass(ScriptClass script) { TempFileCollection allTempFiles = compiler.CompilerResults.TempFiles; CompilerErrorCollection allErrors = compiler.CompilerResults.Errors; CodeDomProvider provider; bool isVB = false; try { provider = script.compilerInfo.CreateProvider(); } catch (ConfigurationException e) { // The CodeDom provider type could not be located, or some error in machine.config allErrors.Add(script.CreateCompileExceptionError(e)); return(null); } CodeNamespace scriptNs = new CodeNamespace("System.Xml.Xsl.CompiledQuery"); // Add #using directives foreach (string ns in defaultNamespaces) { scriptNs.Imports.Add(new CodeNamespaceImport(ns)); } if (isVB) { scriptNs.Imports.Add(new CodeNamespaceImport("Microsoft.VisualBasic")); } foreach (string ns in script.nsImports) { scriptNs.Imports.Add(new CodeNamespaceImport(ns)); } scriptNs.Types.Add(script.typeDecl); CodeCompileUnit unit = new CodeCompileUnit(); { unit.Namespaces.Add(scriptNs); unit.UserData["AllowLateBound"] = true; // Allow variables to be undeclared unit.UserData["RequireVariableDeclaration"] = false; // Allow variables to be declared untyped unit.AssemblyCustomAttributes.Add(new CodeAttributeDeclaration("System.Security.SecurityTransparentAttribute")); } CompilerParameters compilParams = new CompilerParameters(); compilParams.ReferencedAssemblies.Add(typeof(System.Xml.Res).Assembly.Location); compilParams.ReferencedAssemblies.Add("System.dll"); if (isVB) { compilParams.ReferencedAssemblies.Add("Microsoft.VisualBasic.dll"); } foreach (string name in script.refAssemblies) { compilParams.ReferencedAssemblies.Add(name); } XsltSettings settings = compiler.Settings; compilParams.WarningLevel = settings.WarningLevel >= 0 ? settings.WarningLevel : 4; compilParams.TreatWarningsAsErrors = settings.TreatWarningsAsErrors; compilParams.IncludeDebugInformation = settings.IncludeDebugInformation; compilParams.CompilerOptions = script.compilerInfo.CreateDefaultCompilerParameters().CompilerOptions; bool keepFiles = (settings.IncludeDebugInformation || XmlILTrace.IsEnabled) && !settings.CheckOnly; compilParams.GenerateInMemory = settings.CheckOnly; // We need only .dll and .pdb, but there is no way to specify that compilParams.TempFiles.KeepFiles = keepFiles; CompilerResults results; try { results = provider.CompileAssemblyFromDom(compilParams, unit); } catch (ExternalException e) { // Compiler might have created temporary files results = new CompilerResults(compilParams.TempFiles); results.Errors.Add(script.CreateCompileExceptionError(e)); } if (!settings.CheckOnly) { foreach (string fileName in results.TempFiles) { allTempFiles.AddFile(fileName, allTempFiles.KeepFiles); } } foreach (CompilerError e in results.Errors) { script.FixFileName(e); } allErrors.AddRange(results.Errors); if (results.Errors.HasErrors) { return(null); } return(results.CompiledAssembly.GetType("System.Xml.Xsl.CompiledQuery." + script.typeDecl.Name)); }