public IProcessTransformationRunner PrepareTransformationRunner(string content, ITextTemplatingEngineHost host, IProcessTransformationRunFactory runFactory, bool debugging = false) { if (content == null) { throw new ArgumentNullException(nameof(content)); } if (host == null) { throw new ArgumentNullException(nameof(host)); } if (runFactory == null) { throw new ArgumentNullException(nameof(runFactory)); } if (host is ITextTemplatingSessionHost sessionHost) { if (sessionHost.Session == null) { sessionHost.Session = sessionHost.CreateSession(); } } IProcessTransformationRunner runner = null; ParsedTemplate pt = ParsedTemplate.FromText(content, host); TemplateSettings settings = GetSettings(host, pt); settings.Debug = debugging || settings.CachedTemplates; EnsureParameterValuesExist(settings, host, pt); try { if (pt.Errors.HasErrors) { return(null); } runner = CompileAndPrepareRunner(pt, content, host, runFactory, settings); } catch (Exception ex) { if (IsCriticalException(ex)) { throw; } pt.LogError(string.Format(CultureInfo.CurrentCulture, VsTemplatingErrorResources.ExceptionProcessingTemplate, ex), new Location(host.TemplateFile, -1, -1)); } finally { host.LogErrors(pt.Errors); } return(runner); }
public static ParsedTemplate FromText(string content, ITextTemplatingEngineHost host) { ParsedTemplate template = new ParsedTemplate(host.TemplateFile); try { template.Parse(host, new Tokeniser(host.TemplateFile, content)); } catch (ParserException ex) { template.LogError(ex.Message, ex.Location); } return(template); }
public string ProcessTemplate(string content, ITextTemplatingEngineHost host) { ParsedTemplate pt = ParsedTemplate.FromText(content, host); if (pt.Errors.HasErrors) { host.LogErrors(pt.Errors); return(null); } TemplateSettings settings = GetSettings(host, pt); if (pt.Errors.HasErrors) { host.LogErrors(pt.Errors); return(null); } CodeCompileUnit ccu = GenerateCompileUnit(host, pt, settings); if (pt.Errors.HasErrors) { host.LogErrors(pt.Errors); return(null); } System.Reflection.Assembly results = GenerateCode(host, pt, settings, ccu); if (pt.Errors.HasErrors) { host.LogErrors(pt.Errors); return(null); } if (!String.IsNullOrEmpty(settings.Extension)) { host.SetFileExtension(settings.Extension); } if (settings.Encoding != null) { //FIXME: when is this called with false? host.SetOutputEncoding(settings.Encoding, true); } string output = ""; try { output = Run(results, settings.Namespace + "." + settings.Name, host, settings.Culture); } catch (Exception ex) { pt.LogError("Error running transform: " + ex.ToString()); } host.LogErrors(pt.Errors); return(output); }
public string Process() { string output = ""; try { output = TemplatingEngine.Run(assembly, settings.Namespace + "." + settings.Name, host, settings.Culture); } catch (Exception ex) { parsedTemplate.LogError("Error running transform: " + ex); } host.LogErrors(parsedTemplate.Errors); return(output); }
public static ParsedTemplate FromText(string content, ITextTemplatingEngineHost host) { if (host == null) { throw new ArgumentNullException(nameof(host)); } var template = new ParsedTemplate(host.TemplateFile); try { template.Parse(host, new Tokeniser(host.TemplateFile, content)); } catch (ParserException ex) { template.LogError(ex.Message, ex.Location); } return(template); }
public static System.Reflection.Assembly GenerateCode(ITextTemplatingEngineHost host, ParsedTemplate pt, TemplateSettings settings, CodeCompileUnit ccu) { CompilerParameters pars = new CompilerParameters(); pars.GenerateExecutable = false; if (settings.Debug) { pars.GenerateInMemory = false; pars.IncludeDebugInformation = true; pars.TempFiles.KeepFiles = true; } else { pars.GenerateInMemory = true; pars.IncludeDebugInformation = false; } //resolve and add assembly references var assemblies = new Dictionary <string, object>(); UnionWith(assemblies, settings.Assemblies); UnionWith(assemblies, host.StandardAssemblyReferences); foreach (string assem in assemblies.Keys) { string resolvedAssem = host.ResolveAssemblyReference(assem); if (!String.IsNullOrEmpty(resolvedAssem)) { pars.ReferencedAssemblies.Add(resolvedAssem); } else { pt.LogError("Could not resolve assembly reference '" + assem + "'"); return(null); } } CompilerResults results = settings.Provider.CompileAssemblyFromDom(pars, ccu); pt.Errors.AddRange(results.Errors); if (pt.Errors.HasErrors) { return(null); } return(results.CompiledAssembly); }
static void EnsureParameterValuesExist(TemplateSettings settings, ITextTemplatingEngineHost host, ParsedTemplate pt) { foreach (var directive in settings.CustomDirectives) { if (directive.ProcessorName == nameof(ParameterDirectiveProcessor)) { if (directive.Directive.Attributes.TryGetValue("name", out string parameterName)) { if (!string.IsNullOrEmpty(host.ResolveParameterValue(directive.Directive.Name, directive.ProcessorName, parameterName))) { continue; } } pt.LogError(string.Format(CultureInfo.CurrentCulture, VsTemplatingErrorResources.CouldNotVerifyParameterValue, parameterName)); } } }
public static TemplateSettings GetSettings(ITextTemplatingEngineHost host, ParsedTemplate pt) { string language = null; TemplateSettings settings = new TemplateSettings(); foreach (Directive dt in pt.Directives) { switch (dt.Name) { case "template": string val = dt.Extract("language"); if (val != null) { language = val; } val = dt.Extract("debug"); if (val != null) { settings.Debug = string.Compare(val, "true", StringComparison.OrdinalIgnoreCase) == 0; } val = dt.Extract("inherits"); if (val != null) { settings.Inherits = val; } val = dt.Extract("culture"); if (val != null) { System.Globalization.CultureInfo culture = System.Globalization.CultureInfo.GetCultureInfo(val); if (culture == null) { pt.LogWarning("Could not find culture '" + val + "'", dt.StartLocation); } else { settings.Culture = culture; } } val = dt.Extract("hostspecific"); if (val != null) { settings.HostSpecific = string.Compare(val, "true", StringComparison.OrdinalIgnoreCase) == 0; } break; case "assembly": string name = dt.Extract("name"); if (name == null) { pt.LogError("Missing name attribute in assembly directive", dt.StartLocation); } else { settings.Assemblies.Add(name); } break; case "import": string namespac = dt.Extract("namespace"); if (namespac == null) { pt.LogError("Missing namespace attribute in import directive", dt.StartLocation); } else { settings.Imports.Add(namespac); } break; case "output": settings.Extension = dt.Extract("extension"); string encoding = dt.Extract("encoding"); if (encoding != null) { settings.Encoding = Encoding.GetEncoding("encoding"); } break; case "include": throw new InvalidOperationException("Include is handled in the parser"); default: throw new NotImplementedException("Custom directives are not supported yet"); } ComplainExcessAttributes(dt, pt); } if (settings.Name == null) { settings.Name = string.Format("GeneratedTextTransformation{0:x}", new System.Random().Next()); } if (settings.Namespace == null) { settings.Namespace = typeof(TextTransformation).Namespace; } //resolve the CodeDOM provider if (String.IsNullOrEmpty(language)) { pt.LogError("No language was specified for the template"); return(settings); } if (language == "C#v3.5") { Dictionary <string, string> providerOptions = new Dictionary <string, string> (); providerOptions.Add("CompilerVersion", "v3.5"); settings.Provider = new CSharpCodeProvider(providerOptions); } else { settings.Provider = CodeDomProvider.CreateProvider(language); } if (settings.Provider == null) { pt.LogError("A provider could not be found for the language '" + language + "'"); return(settings); } return(settings); }
protected virtual IProcessTransformationRunner CompileAndPrepareRunner(ParsedTemplate pt, string content, ITextTemplatingEngineHost host, IProcessTransformationRunFactory runFactory, TemplateSettings settings) { TransformationRunner runner = null; bool success = false; if (pt == null) { throw new ArgumentNullException(nameof(pt)); } if (host == null) { throw new ArgumentNullException(nameof(host)); } if (runFactory == null) { throw new ArgumentNullException(nameof(runFactory)); } if (settings == null) { throw new ArgumentNullException(nameof(settings)); } try { try { if (runFactory.CreateTransformationRunner() is TransformationRunner theRunner) { runner = theRunner; } } catch (Exception ex) { if (IsCriticalException(ex)) { throw; } pt.LogError(ex.ToString(), new Location(host.TemplateFile)); } if (runner != null && !runner.Errors.HasErrors) { // reference the assemblies and ensure they are path rooted settings.SetAssemblies(ProcessReferences(host, pt, settings)); if (!pt.Errors.HasErrors) { try { success = runFactory.PrepareTransformation(runner.RunnerId, pt, content, host, settings); } catch (SerializationException) { pt.LogError(VsTemplatingErrorResources.SessionHostMarshalError, new Location(host.TemplateFile)); throw; } } } } catch (Exception ex) { if (IsCriticalException(ex)) { throw; } pt.LogError(ex.ToString(), new Location(host.TemplateFile, -1, -1)); } finally { if (runner != null) { pt.Errors.AddRange(runFactory.GetErrors(runner.RunnerId)); } } return(success ? runner : null); }
static void GenerateTransformMethod(CodeTypeDeclaration templateType, TemplateSettings settings, ParsedTemplate pt, string templateFile, bool isOverride) { string baseDirectory = Path.GetDirectoryName(templateFile); var transformMeth = Declare.Method("TransformText").Returns <string> ().AsVirtual(); if (isOverride) { transformMeth.AsOverride(); } transformMeth.WithStatements(Expression.This.SetProperty("GenerationEnvironment", Expression.Null)); CodeExpression toStringHelper = settings.IsPreprocessed ? Expression.This.Property("ToStringHelper") : TypeReference.Global(typeof(ToStringHelper)).AsExpression(); //method references that will need to be used multiple times var writeMeth = Expression.This.Method("Write"); var toStringMeth = toStringHelper.Method("ToStringWithCulture"); bool helperMode = false; //build the code from the segments foreach (TemplateSegment seg in pt.Content) { CodeStatement st = null; CodeLinePragma location = null; if (!settings.NoLinePragmas) { var f = seg.StartLocation.FileName ?? templateFile; if (!string.IsNullOrEmpty(f)) { // FIXME: we need to know where the output file will be to make this work properly if (settings.RelativeLinePragmas) { f = FileUtil.AbsoluteToRelativePath(baseDirectory, f); } else { f = Path.GetFullPath(f); } } location = new CodeLinePragma(f, seg.StartLocation.Line); } switch (seg.Type) { case SegmentType.Block: if (helperMode) { //TODO: are blocks permitted after helpers? pt.LogError("Blocks are not permitted after helpers", seg.TagStartLocation); } st = Statement.Snippet(seg.Text); break; case SegmentType.Expression: st = writeMeth.Invoke(toStringMeth.Invoke(Expression.Snippet(seg.Text))).AsStatement(); break; case SegmentType.Content: st = writeMeth.Invoke(Expression.Primitive(seg.Text)).AsStatement(); break; case SegmentType.Helper: if (!string.IsNullOrEmpty(seg.Text)) { templateType.AddSnippetMember(seg.Text, location); } helperMode = true; break; default: throw new InvalidOperationException(); } if (st != null) { if (helperMode) { //convert the statement into a snippet member and attach it to the top level type //TODO: is there a way to do this for languages that use indentation for blocks, e.g. python? using (var writer = new StringWriter()) { settings.Provider.GenerateCodeFromStatement(st, writer, null); var text = writer.ToString(); if (!string.IsNullOrEmpty(text)) { templateType.AddSnippetMember(text, location); } } } else { st.LinePragma = location; transformMeth.Statements.Add(st); continue; } } } transformMeth.WithStatements(Statement.Return(Expression.This.Property("GenerationEnvironment").InvokeMethod("ToString"))); templateType.AddMember(transformMeth); }