protected static CustomT4Host Host(ITemplateInfo templateInfo, string templatesDirectory, OdcmObject odcmObject, OdcmModel odcmModel)
        {
            // Need to always set the host. Typically, this is run against a single platform when generating codefiels.
            // In test cases, we need to target multiple platforms. Since much of this code is static, we need to make sure
            // reset the information provided to the template processor. This change fixes a bug when targeting
            // multiple platforms in a test.
            _host = new CustomT4Host(templateInfo, templatesDirectory, odcmObject, odcmModel);

            return(_host);
        }
        protected static CustomT4Host Host(ITemplateInfo templateInfo, string templatesDirectory, OdcmObject odcmObject, OdcmModel odcmModel)
        {
            if (_host == null)
            {
                _host = new CustomT4Host(templateInfo, templatesDirectory, odcmObject, odcmModel);
            }
            else
            {
                _host.Reset(templateInfo, templatesDirectory, odcmObject, odcmModel);
            }

            return(_host);
        }
Beispiel #3
0
        private Assembly CompileAndLoadTemplateAssembly(ITemplateInfo templateInfo, string templateContent, string className)
        {
            var dummyHost     = new CustomT4Host(templateInfo, this.TemplatesDirectory, null, null);
            var generatedCode = this.T4Engine.PreprocessTemplate(templateContent, dummyHost, className, RuntimeTemplatesNamespace, out var language, out var references);

            var syntaxTree = CSharpSyntaxTree.ParseText(generatedCode);

            var refs = new List <PortableExecutableReference>();

            foreach (var reference in ((string)AppContext.GetData("TRUSTED_PLATFORM_ASSEMBLIES")).Split(Path.PathSeparator))
            {
                refs.Add(MetadataReference.CreateFromFile(reference));
            }
            var compilation = CSharpCompilation.Create($"{templateInfo.TemplateName}.dll",
                                                       syntaxTrees: new[] { syntaxTree },
                                                       references: refs,
                                                       options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));

            var messages = new List <string>();

            using (var ms = new MemoryStream())
            {
                EmitResult result = compilation.Emit(ms);
                if (!result.Success)
                {
                    var failures = result.Diagnostics.Where(diagnostic =>
                                                            diagnostic.IsWarningAsError ||
                                                            diagnostic.Severity == DiagnosticSeverity.Error);

                    foreach (Diagnostic diagnostic in failures.OrderBy(o => o.Location.GetLineSpan().StartLinePosition.Line))
                    {
                        messages.Add($"({diagnostic.Location.GetLineSpan().StartLinePosition.Line}) {diagnostic.Id}: {diagnostic.GetMessage()}");
                    }
                    throw new InvalidOperationException("Template error.");
                }
                else
                {
                    ms.Seek(0, SeekOrigin.Begin);
                    var byteAssembly = ms.ToArray();
                    var assembly     = Assembly.Load(byteAssembly);
                    messages.Add("Compilation successful");
                    return(assembly);
                }
            }
        }
        public string LogErrors(CustomT4Host host, ITemplateInfo templateInfo)
        {
            var sb = new StringBuilder();

            if (host.Errors == null || host.Errors.Count <= 0)
            {
                return(sb.ToString());
            }

            foreach (CompilerError error in host.Errors)
            {
                sb.AppendLine("TemplateProcessor ERROR").
                AppendFormat(@"Name:     {0}{1}", templateInfo.TemplateName, Environment.NewLine).
                AppendFormat(@"Line:     {0}{1}", error.Line, Environment.NewLine).
                AppendFormat(@"Details:  {0}{1}", error.ErrorText, Environment.NewLine).
                AppendLine().
                AppendLine();
            }
            return(sb.ToString());
        }
        private Func <ITextTemplatingEngineHost, string> PreProcessTemplate(ITemplateInfo templateInfo)
        {
            var templateContent = File.ReadAllText(templateInfo.FullPath);

            string language;

            string[] references;
            var      className     = templateInfo.TemplateName.Replace(".", "_");
            var      dummyHost     = new CustomT4Host(templateInfo, this.TemplatesDirectory, null, null);
            var      generatedCode = this.T4Engine.PreprocessTemplate(templateContent, dummyHost, className, RuntimeTemplatesNamespace, out language, out references);

            var parameters = new CompilerParameters
            {
                // OutputAssembly = templateInfo.TemplateName + ".dll",
                GenerateInMemory        = true,
                GenerateExecutable      = false,
                IncludeDebugInformation = true,
            };

            var assemblyLocations = AppDomain.CurrentDomain
                                    .GetAssemblies()
                                    .Where(a => !a.IsDynamic)
                                    .Select(a => a.Location);

            parameters.ReferencedAssemblies.AddRange(assemblyLocations.ToArray());

            parameters.TreatWarningsAsErrors = false;

            var provider = new CSharpCodeProvider();

            var results = provider.CompileAssemblyFromSource(parameters, generatedCode);

            if (results.Errors.Count > 0)
            {
                var realError = false;
                for (int i = 0; i < results.Errors.Count; i++)
                {
                    if (!results.Errors[i].IsWarning)
                    {
                        realError = true;
                    }
                    logger.Error((results.Errors[i].IsWarning ? "Warning" : "Error") + "(" + i.ToString() + "): " + results.Errors[i].ToString());
                    Console.WriteLine((results.Errors[i].IsWarning?"Warning":"Error") + "(" + i.ToString() + "): " + results.Errors[i].ToString());
                }

                if (realError)
                {
                    File.WriteAllText("__ErrorFile.cs", generatedCode);
                    throw new InvalidOperationException("Template error.");
                }
            }

            var assembly          = results.CompiledAssembly;
            var templateClassType = assembly.GetType(RuntimeTemplatesNamespace + "." + className);

            dynamic templateClassInstance = Activator.CreateInstance(templateClassType);

            return((ITextTemplatingEngineHost host) =>
            {
                templateClassInstance.Host = host;
                return templateClassInstance.TransformText();
            });
        }