private static Assembly CompileAssembly(Template template, TemplateCompilation compilation) { string source = compilation.SourceCode; Assembly cachedAssembly = TemplateExpressionAssemblyCache.GetAssembly(source); if (cachedAssembly != null) return cachedAssembly; CompilerParameters config = new CompilerParameters() { GenerateInMemory = true }; foreach (string asmName in template.ReferencedAssemblies) config.ReferencedAssemblies.Add(asmName); if (!config.ReferencedAssemblies.Contains("FistCore.Generator.TemplateEngine.dll")) config.ReferencedAssemblies.Add("FistCore.Generator.TemplateEngine.dll"); if (!config.ReferencedAssemblies.Contains("FistCore.Core.dll")) config.ReferencedAssemblies.Add("FistCore.Core.dll"); Dictionary<string, string> options = new Dictionary<string, string>(); options["CompilerVersion"] = "v3.5"; Microsoft.CSharp.CSharpCodeProvider compiler = new Microsoft.CSharp.CSharpCodeProvider(options); //CodeDomProvider compiler = CodeDomProvider.CreateProvider("CSharp"); // All referenced assemblies must be in the same directory as entry assembly. string oldCwd = Directory.GetCurrentDirectory(); Directory.SetCurrentDirectory(IoUtil.GetExecutableDirectory()); CompilerResults output = compiler.CompileAssemblyFromSource(config, source); Directory.SetCurrentDirectory(oldCwd); if (output.Errors.HasErrors) { SetCompilerErrors(compilation, output.Errors); string errmsg = compilation.GetCompilationErrorsDescription(); throw new Exception(template.Header.Title + Environment.NewLine + errmsg); } TemplateExpressionAssemblyCache.SetAssembly(source, output.CompiledAssembly); return output.CompiledAssembly; }
private static void SetCompilerErrors(TemplateCompilation compilation, CompilerErrorCollection errors) { StringBuilder otherErrors = new StringBuilder(); foreach (CompilerError err in errors) { ExpressionCompilationItem faultyItem = compilation.GetItemByClassLineNumber(err.Line); if (faultyItem != null) faultyItem.CompilationError = GetErrorText(err); else otherErrors.AppendLine(GetErrorText(err)); } compilation.OtherCompilationErrors = otherErrors.ToString(); }
private static TemplateCompilation GenerateAssemblySourceCode(Template template) { // One class (ITemplateExpression implementation) per expression. List<string> allDistinctExpressions = GetAllDistinctExpressions(template); TemplateCompilation compilation = new TemplateCompilation(); StringBuilder asmSource = new StringBuilder(); GenerateUsingDirectives(template, asmSource); asmSource.AppendLine(NamespaceDeclaration); asmSource.AppendLine(" {"); List<string> generatedClassNames = new List<string>(); int firstLineOfCurrClass = TextUtil.CountLines(asmSource.ToString()) + 1; foreach (string expression in allDistinctExpressions) { string className = CreateUniqueClassName(expression); if (!generatedClassNames.Contains(className)) { string classSourceCode = GenerateExpressionClassSource(className, expression); asmSource.AppendLine(classSourceCode); int currClassLineCount = TextUtil.CountLines(classSourceCode); ExpressionCompilationItem compilationItem = new ExpressionCompilationItem() { ClassFirstLineInSourceFile = firstLineOfCurrClass, ClassLastLineInSourceFile = firstLineOfCurrClass + currClassLineCount, //ClassName = className, //ClassSourceCode = classSourceCode, Expression = expression, XmlLine = template.XmlLines.GetLineWithText(expression) }; compilation.Expressions.Add(compilationItem); // 1st line of next class. firstLineOfCurrClass = compilationItem.ClassLastLineInSourceFile + 1; } } asmSource.AppendLine(" }"); compilation.SourceCode = asmSource.ToString(); return compilation; }