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 HashSet<string> assemblies = new HashSet<string> (); assemblies.UnionWith (settings.Assemblies); assemblies.UnionWith (host.StandardAssemblyReferences); foreach (string assem in assemblies) { 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; }
public string GetTemplateSourceCode(string name) { string sourceCode = File.ReadAllText(GetTemplateFileName(name)); var host = T4Generator as ITextTemplatingEngineHost; ParsedTemplate pt = ParsedTemplate.FromText(sourceCode, T4Generator); if (pt.Errors.HasErrors) { host.LogErrors(pt.Errors); return(null); } TemplateSettings settings = TemplatingEngine.GetSettings(T4Generator, pt); var ccu = TemplatingEngine.GenerateCompileUnit(host, sourceCode, pt, settings); var opts = new CodeGeneratorOptions(); using (var writer = new StringWriter()) { settings.Provider.GenerateCodeFromCompileUnit(ccu, writer, opts); return(writer.ToString()); } }
public void Process(ParsedTemplate template) { foreach (var processor in _processors) { processor?.Process(template); } }
public Formatter Parse() { var f = _locatorFactory.CloneForTagLib(_lib); if (_initialLocator == null) { _initialLocator = f.GetNewLocator(); } var formatter = new InternalFormatter(new TagLibParserFactory(new TagLibForParsing(_lib), _expressionLib, f, _tagValidator), _expressionLib, _template, _allowTags, _initialLocator); try { formatter.Parse(); CreateTemplateProcessorFor(_lib).Process(formatter.ParsedTemplate); if (_templateValidator != null) { _templateValidator.Validate(formatter.ParsedTemplate); } CreateTemplateValidatorFor(_lib).Validate(formatter.ParsedTemplate); } finally { _templateParsed = formatter.ParsedTemplate; } return(this); }
public override void BuildSourceCode(StringBuilder source, ParsedTemplate parsed) { switch (Command) { case CustomCommand.Argument: source.Append(parsed.Template.OutputItemName); if (string.IsNullOrEmpty(Format)) { source.Append(".Write("); source.Append(ArgumentName); source.Append(");"); } else { source.Append(".WriteFormatted("); source.Append(ArgumentName); source.Append(", \""); source.Append(Format); source.Append("\");"); } return; case CustomCommand.CurrentUser: source.Append(parsed.Template.OutputItemName); source.Append(".Write(\""); source.Append(Environment.UserName); source.Append("\");"); return; } base.BuildSourceCode(source, parsed); }
public void Validate(ParsedTemplate template) { foreach (var validator in _validators) { validator?.Validate(template); } }
public void IncludeOnceTest() { var host = new DummyHost(); host.Locations.Add(FooIncludeName, FooIncludeName); host.Contents.Add(FooIncludeName, FooInclude.NormalizeNewlines()); host.Locations.Add(BarIncludeName, BarIncludeName); host.Contents.Add(BarIncludeName, BarInclude.NormalizeNewlines()); var pt = ParsedTemplate.FromTextInternal(IncludeSample.NormalizeNewlines(), host); Assert.Empty(pt.Errors); var content = new List <TemplateSegment> (pt.Content); var dirs = new List <Directive> (pt.Directives); Assert.Empty(dirs); Assert.Collection(content, t => Assert.Equal("One\n", t.Text), t => Assert.Equal("Foo\n", t.Text), t => Assert.Equal("Two\n", t.Text), t => Assert.Equal("Bar\n", t.Text), t => Assert.Equal("Three\n", t.Text), t => Assert.Equal("Four\n", t.Text), t => Assert.Equal("Bar\n", t.Text), t => Assert.Equal("Five\n", t.Text) ); }
public AST(ParsedTemplate source, Options options = Options.None, string name = null) : this() { Name = name; Context = new Context(1, 1); Yield(this, source); Prune(options); }
public CompiledTemplate (ParsedTemplate parsedTemplate, ITextTemplatingEngineHost host, Assembly assembly, TemplateSettings settings) { this.host = host; this.assembly = assembly; this.settings = settings; this.parsedTemplate = parsedTemplate; }
internal static OperationResult <TemplateLarnacaProperties> Extract(ParsedTemplate pt) { if (pt is null) { throw new ArgumentNullException(nameof(pt)); } OperationResult <TemplateLarnacaProperties> theReturn = new OperationResult <TemplateLarnacaProperties>() { StatusMessage = string.Empty, Data = new TemplateLarnacaProperties() }; var templateDirective = pt.Directives.FirstOrDefault(d => d.Name.Equals("template", StringComparison.OrdinalIgnoreCase)); if (!templateDirective.Attributes.TryGetValue(nameof(Type), out var templateTypeString)) { theReturn.StatusCode = 1; theReturn.StatusMessage += $"Template missing '{nameof(Type)}' from Template directive"; } else if (Enum.TryParse <ETemplateType>(templateTypeString, out var templateType)) { theReturn.Data.Type = templateType; } else { theReturn.StatusCode = 1; theReturn.StatusMessage += $"Template '{nameof(Type)}'={templateTypeString} from Template directive could not be parsed"; } if (!templateDirective.Attributes.TryGetValue(nameof(Replication), out var templateReplicationString)) { theReturn.StatusCode = 1; theReturn.StatusMessage += $"Template missing '{nameof(Replication)}' from Template directive"; } else if (Enum.TryParse <ETemplateReplication>(templateReplicationString, out var templateReplication)) { theReturn.Data.Replication = templateReplication; } else { theReturn.StatusCode = 1; theReturn.StatusMessage += $"Template '{nameof(Replication)}'={templateReplicationString} from Template directive could not be parsed"; } if (templateDirective.Attributes.TryGetValue(nameof(DoNotCompile), out var doNotCompileString)) { if (!bool.TryParse(doNotCompileString, out var doNotCompile)) { theReturn.StatusCode = 1; theReturn.StatusMessage += $"Template '{nameof(DoNotCompile)}'={doNotCompileString} from Template directive could not be parsed"; } else { theReturn.Data.DoNotCompile = doNotCompile; } } return(theReturn); }
private static void Yield(AST ast, ParsedTemplate source) { if (source == null) { return; } ast.Yield(source.TemplateParsed); }
private void ApplySettings(ParsedTemplate tmp, ITemplateCodeGenerator g) { g.Namespace = tmp.Namespace; g.ClassName = tmp.ClassName; g.TemplateName = tmp.TemplateName; g.BaseClass = GetBaseClass(tmp); g.ModelType = Convert.ToString(tmp.ModelType); g.Accessibility = "public"; }
static void Generate(TemplateGenerator host, ProjectFile file, out string outputFile) { outputFile = null; string content; try { content = File.ReadAllText(file.FilePath); } catch (IOException ex) { host.Errors.Add(new CompilerError { ErrorText = GettextCatalog.GetString("Could not read input file '{0}':\n{1}", file.FilePath, ex) }); return; } var pt = ParsedTemplate.FromText(content, host); if (pt.Errors.HasErrors) { host.Errors.AddRange(pt.Errors); return; } var settings = TemplatingEngine.GetSettings(host, pt); if (pt.Errors.HasErrors) { host.Errors.AddRange(pt.Errors); return; } outputFile = file.FilePath.ChangeExtension(settings.Provider.FileExtension); settings.Name = settings.Provider.CreateValidIdentifier(file.FilePath.FileNameWithoutExtension); settings.Namespace = CustomToolService.GetFileNamespace(file, outputFile); settings.IncludePreprocessingHelpers = string.IsNullOrEmpty(settings.Inherits); settings.IsPreprocessed = true; var ccu = TemplatingEngine.GenerateCompileUnit(host, content, pt, settings); host.Errors.AddRange(pt.Errors); if (pt.Errors.HasErrors) { return; } try { using (var writer = new StreamWriter(outputFile, false, System.Text.Encoding.UTF8)) { settings.Provider.GenerateCodeFromCompileUnit(ccu, writer, new CodeGeneratorOptions()); } } catch (IOException ex) { host.Errors.Add(new CompilerError { ErrorText = GettextCatalog.GetString("Could not write output file '{0}':\n{1}", outputFile, ex) }); } }
public ParsedTemplate Parse(string messageTemplate) { ParsedTemplate parsedTemplate; if (!_cachedParsedTemplates.TryGetValue(messageTemplate, out parsedTemplate)) { parsedTemplate = new ParsedTemplate(messageTemplate); } return(parsedTemplate); }
public void DefaultLanguage() { DummyHost host = new DummyHost(); string template = @"<#= DateTime.Now #>"; ParsedTemplate pt = ParsedTemplate.FromText(template, host); Assert.AreEqual(0, host.Errors.Count); TemplateSettings settings = TemplatingEngine.GetSettings(host, pt); Assert.AreEqual(settings.Language, "C#"); }
public void DefaultLanguage() { var host = new DummyHost(); string template = @"<#= DateTime.Now #>"; var pt = ParsedTemplate.FromTextInternal(template, host); Assert.Empty(host.Errors); TemplateSettings settings = TemplatingEngine.GetSettings(host, pt); Assert.Equal("C#", settings.Language); }
private string GetBaseClass(ParsedTemplate tmp) { // TODO Better handling of assembly qualified names (the assembly implies assembly that needs to be loaded by compiler) // TODO Resolving will probably be required if OriginalString is qual name (uncommon) var tr = tmp.Settings.SelectBaseClass(tmp.BaseClass, tmp.ModelType) ?? tmp.Settings.TemplateBaseClass ?? TypeReference.FromType(typeof(HxlTemplateExtension)); return(Regex.Replace(tr.ToString(), ",.*$", string.Empty)); }
public void ParseTest() { string tf = "test.input"; var pt = ParsedTemplate.FromTextInternal( ParseSample1.NormalizeNewlines(), new DummyHost { TemplateFile = tf } ); Assert.Empty(pt.Errors); var content = new List <TemplateSegment> (pt.Content); var dirs = new List <Directive> (pt.Directives); Assert.Single(dirs); Assert.Equal(6, content.Count); Assert.Equal("template", dirs[0].Name); Assert.Single(dirs[0].Attributes); Assert.Equal("C#v3.5", dirs[0].Attributes["language"]); Assert.Equal(new Location(tf, 1, 1), dirs[0].TagStartLocation); Assert.Equal(new Location(tf, 1, 34), dirs[0].EndLocation); Assert.Equal("Line One\nLine Two\n", content[0].Text); Assert.Equal("\nvar foo = 5;\n", content[1].Text); Assert.Equal("Line Three ", content[2].Text); Assert.Equal(" bar ", content[3].Text); Assert.Equal("\nLine Four\n", content[4].Text); Assert.Equal(" \nvar s = \"baz \\\\#>\";\n", content[5].Text); Assert.Equal(SegmentType.Content, content[0].Type); Assert.Equal(SegmentType.Block, content[1].Type); Assert.Equal(SegmentType.Content, content[2].Type); Assert.Equal(SegmentType.Expression, content[3].Type); Assert.Equal(SegmentType.Content, content[4].Type); Assert.Equal(SegmentType.Helper, content[5].Type); Assert.Equal(new Location(tf, 4, 1), content[1].TagStartLocation); Assert.Equal(new Location(tf, 7, 12), content[3].TagStartLocation); Assert.Equal(new Location(tf, 9, 1), content[5].TagStartLocation); Assert.Equal(new Location(tf, 2, 1), content[0].StartLocation); Assert.Equal(new Location(tf, 4, 3), content[1].StartLocation); Assert.Equal(new Location(tf, 7, 1), content[2].StartLocation); Assert.Equal(new Location(tf, 7, 15), content[3].StartLocation); Assert.Equal(new Location(tf, 7, 22), content[4].StartLocation); Assert.Equal(new Location(tf, 9, 4), content[5].StartLocation); Assert.Equal(new Location(tf, 6, 3), content[1].EndLocation); Assert.Equal(new Location(tf, 7, 22), content[3].EndLocation); Assert.Equal(new Location(tf, 11, 3), content[5].EndLocation); }
public void ParseTest() { string tf = "test.input"; var pt = new ParsedTemplate("test.input"); var tk = new Tokeniser(tf, ParseSample1.NormalizeNewlines()); var host = new DummyHost(); pt.Parse(host, tk); Assert.AreEqual(0, pt.Errors.Count); var content = new List <TemplateSegment> (pt.Content); var dirs = new List <Directive> (pt.Directives); Assert.AreEqual(1, dirs.Count); Assert.AreEqual(6, content.Count); Assert.AreEqual("template", dirs[0].Name); Assert.AreEqual(1, dirs[0].Attributes.Count); Assert.AreEqual("C#v3.5", dirs[0].Attributes["language"]); Assert.AreEqual(new Location(tf, 1, 1), dirs[0].TagStartLocation); Assert.AreEqual(new Location(tf, 1, 34), dirs[0].EndLocation); Assert.AreEqual("Line One\nLine Two\n", content[0].Text); Assert.AreEqual("\nvar foo = 5;\n", content[1].Text); Assert.AreEqual("Line Three ", content[2].Text); Assert.AreEqual(" bar ", content[3].Text); Assert.AreEqual("\nLine Four\n", content[4].Text); Assert.AreEqual(" \nvar s = \"baz \\\\#>\";\n", content[5].Text); Assert.AreEqual(SegmentType.Content, content[0].Type); Assert.AreEqual(SegmentType.Block, content[1].Type); Assert.AreEqual(SegmentType.Content, content[2].Type); Assert.AreEqual(SegmentType.Expression, content[3].Type); Assert.AreEqual(SegmentType.Content, content[4].Type); Assert.AreEqual(SegmentType.Helper, content[5].Type); Assert.AreEqual(new Location(tf, 4, 1), content[1].TagStartLocation); Assert.AreEqual(new Location(tf, 7, 12), content[3].TagStartLocation); Assert.AreEqual(new Location(tf, 9, 1), content[5].TagStartLocation); Assert.AreEqual(new Location(tf, 2, 1), content[0].StartLocation); Assert.AreEqual(new Location(tf, 4, 3), content[1].StartLocation); Assert.AreEqual(new Location(tf, 7, 1), content[2].StartLocation); Assert.AreEqual(new Location(tf, 7, 15), content[3].StartLocation); Assert.AreEqual(new Location(tf, 7, 22), content[4].StartLocation); Assert.AreEqual(new Location(tf, 9, 4), content[5].StartLocation); Assert.AreEqual(new Location(tf, 6, 3), content[1].EndLocation); Assert.AreEqual(new Location(tf, 7, 22), content[3].EndLocation); Assert.AreEqual(new Location(tf, 11, 3), content[5].EndLocation); }
public void ParseTest() { string tf = "test.input"; ParsedTemplate pt = new ParsedTemplate ("test.input"); Tokeniser tk = new Tokeniser (tf, ParseSample1); DummyHost host = new DummyHost (); pt.Parse (host, tk); Assert.AreEqual (0, pt.Errors.Count); var content = new List<TemplateSegment> (pt.Content); var dirs = new List<Directive> (pt.Directives); Assert.AreEqual (1, dirs.Count); Assert.AreEqual (6, content.Count); Assert.AreEqual ("template", dirs[0].Name); Assert.AreEqual (1, dirs[0].Attributes.Count); Assert.AreEqual ("C#v3.5", dirs[0].Attributes["language"]); Assert.AreEqual (new Location (tf, 1, 1), dirs[0].TagStartLocation); Assert.AreEqual (new Location (tf, 1, 34), dirs[0].EndLocation); Assert.AreEqual ("Line One\r\nLine Two\r\n", content[0].Text); Assert.AreEqual ("\r\nfoo\r\n", content[1].Text); Assert.AreEqual ("Line Three ", content[2].Text); Assert.AreEqual (" bar ", content[3].Text); Assert.AreEqual ("\r\nLine Four\r\n", content[4].Text); Assert.AreEqual (" \r\nbaz \\#>\r\n", content[5].Text); Assert.AreEqual (SegmentType.Content, content[0].Type); Assert.AreEqual (SegmentType.Block, content[1].Type); Assert.AreEqual (SegmentType.Content, content[2].Type); Assert.AreEqual (SegmentType.Expression, content[3].Type); Assert.AreEqual (SegmentType.Content, content[4].Type); Assert.AreEqual (SegmentType.Helper, content[5].Type); Assert.AreEqual (new Location (tf, 4, 1), content[1].TagStartLocation); Assert.AreEqual (new Location (tf, 7, 12), content[3].TagStartLocation); Assert.AreEqual (new Location (tf, 9, 1), content[5].TagStartLocation); Assert.AreEqual (new Location (tf, 2, 1), content[0].StartLocation); Assert.AreEqual (new Location (tf, 4, 3), content[1].StartLocation); Assert.AreEqual (new Location (tf, 7, 1), content[2].StartLocation); Assert.AreEqual (new Location (tf, 7, 15), content[3].StartLocation); Assert.AreEqual (new Location (tf, 7, 22), content[4].StartLocation); Assert.AreEqual (new Location (tf, 9, 4), content[5].StartLocation); Assert.AreEqual (new Location (tf, 6, 3), content[1].EndLocation); Assert.AreEqual (new Location (tf, 7, 22), content[3].EndLocation); Assert.AreEqual (new Location (tf, 11, 3), content[5].EndLocation); }
public string Render(Hash hash) { var renderParams = new RenderParameters(); TextWriter textWriter = new StringWriter(); hash.Add("Context", CreateContextHash()); renderParams.LocalVariables = hash; renderParams.RethrowErrors = true; ParsedTemplate.Render(textWriter, renderParams); textWriter.Flush(); return(textWriter.ToString().Trim()); }
public override ParsedDocument Parse (bool storeAst, string fileName, TextReader content, Project project = null) { ParsedTemplate template = new ParsedTemplate (fileName); try { var tk = new Tokeniser (fileName, content.ReadToEnd ()); template.ParseWithoutIncludes (tk); } catch (ParserException ex) { template.LogError (ex.Message, ex.Location); } T4ParsedDocument doc = new T4ParsedDocument (fileName, template.RawSegments); doc.Flags |= ParsedDocumentFlags.NonSerializable; foreach (System.CodeDom.Compiler.CompilerError err in template.Errors) doc.Errors.Add (new Error (err.IsWarning? ErrorType.Warning : ErrorType.Error, err.ErrorText, err.Line, err.Column)); return doc; }
protected override void Load() { try { _template = Formatter.LocatorBasedFormatter(_factory.Lib, _name, _locator, _factory).ParsedTemplate; } catch (ResourceException FNFe) { throw TemplateException.TemplateFailedToInitialize(_name, FNFe).WithHttpErrorCode(404); } catch (ExceptionWithContext EWC) { throw TemplateExceptionWithContext.ErrorInTemplate(_name, EWC).AddErrorCodeIfNull(500); } catch (Exception e) { throw TemplateException.ErrorInTemplate(_name, e).WithHttpErrorCode(500); } }
public override System.Threading.Tasks.Task<ParsedDocument> Parse (ParseOptions parseOptions, System.Threading.CancellationToken cancellationToken) { var fileName = parseOptions.FileName; ParsedTemplate template = new ParsedTemplate (fileName); var readOnlyDoc = TextEditorFactory.CreateNewReadonlyDocument (parseOptions.Content, fileName); try { var tk = new Tokeniser (fileName, readOnlyDoc.Text); template.ParseWithoutIncludes (tk); } catch (ParserException ex) { template.LogError (ex.Message, ex.Location); } var errors = new List<Error> (); foreach (System.CodeDom.Compiler.CompilerError err in template.Errors) { errors.Add (new Error (err.IsWarning ? ErrorType.Warning : ErrorType.Error, err.ErrorText, new DocumentLocation (err.Line, err.Column))); } var doc = new T4ParsedDocument (fileName, template.RawSegments, errors); doc.Flags |= ParsedDocumentFlags.NonSerializable; return System.Threading.Tasks.Task.FromResult((ParsedDocument)doc); }
internal static void GenerateCode(ITextTemplatingEngineHost host, string content, string namespac, string name, TextWriter writer) { ParsedTemplate pt = ParsedTemplate.FromText(content, host); if (pt.Errors.HasErrors) { host.LogErrors(pt.Errors); return; } TemplateSettings settings = TemplatingEngine.GetSettings(host, pt); if (name != null) { settings.Name = name; } if (namespac != null) { settings.Namespace = namespac; } if (pt.Errors.HasErrors) { host.LogErrors(pt.Errors); return; } var ccu = TemplatingEngine.GenerateCompileUnit(host, pt, settings); if (pt.Errors.HasErrors) { host.LogErrors(pt.Errors); return; } var opts = new System.CodeDom.Compiler.CodeGeneratorOptions(); settings.Provider.GenerateCodeFromCompileUnit(ccu, writer, opts); }
static string GenerateCode(ITextTemplatingEngineHost host, string content, string name, string generatorNewline) { var pt = ParsedTemplate.FromTextInternal(content, host); if (pt.Errors.HasErrors) { host.LogErrors(pt.Errors); return(null); } TemplateSettings settings = TemplatingEngine.GetSettings(host, pt); if (name != null) { settings.Namespace = name; } if (pt.Errors.HasErrors) { host.LogErrors(pt.Errors); return(null); } var ccu = TemplatingEngine.GenerateCompileUnit(host, content, pt, settings); if (pt.Errors.HasErrors) { host.LogErrors(pt.Errors); return(null); } var opts = new CodeGeneratorOptions(); using var writer = new StringWriter() { NewLine = generatorNewline }; settings.Provider.GenerateCodeFromCompileUnit(ccu, writer, opts); return(writer.ToString()); }
public override ParsedDocument Parse(ProjectDom dom, string fileName, string content) { ParsedTemplate template = new ParsedTemplate(fileName); try { Tokeniser tk = new Tokeniser(fileName, content); template.ParseWithoutIncludes(tk); } catch (ParserException ex) { template.LogError(ex.Message, ex.Location); } T4ParsedDocument doc = new T4ParsedDocument(fileName, template.RawSegments); doc.Flags |= ParsedDocumentFlags.NonSerializable; foreach (System.CodeDom.Compiler.CompilerError err in template.Errors) { doc.Errors.Add(new Error(err.IsWarning? ErrorType.Warning : ErrorType.Error, err.Line, err.Column, err.ErrorText)); } return(doc); }
public override ParsedDocument Parse(bool storeAst, string fileName, TextReader content, Project project = null) { ParsedTemplate template = new ParsedTemplate(fileName); try { var tk = new Tokeniser(fileName, content.ReadToEnd()); template.ParseWithoutIncludes(tk); } catch (ParserException ex) { template.LogError(ex.Message, ex.Location); } var errors = new List <Error> (); foreach (System.CodeDom.Compiler.CompilerError err in template.Errors) { errors.Add(new Error(err.IsWarning ? ErrorType.Warning : ErrorType.Error, err.ErrorText, err.Line, err.Column)); } var doc = new T4ParsedDocument(fileName, template.RawSegments, errors); doc.Flags |= ParsedDocumentFlags.NonSerializable; return(doc); }
public override System.Threading.Tasks.Task <ParsedDocument> Parse(ParseOptions parseOptions, System.Threading.CancellationToken cancellationToken) { var fileName = parseOptions.FileName; ParsedTemplate template = new ParsedTemplate(fileName); var readOnlyDoc = TextEditorFactory.CreateNewReadonlyDocument(parseOptions.Content, fileName); try { var tk = new Tokeniser(fileName, readOnlyDoc.Text); template.ParseWithoutIncludes(tk); } catch (ParserException ex) { template.LogError(ex.Message, ex.Location); } var errors = new List <Error> (); foreach (System.CodeDom.Compiler.CompilerError err in template.Errors) { errors.Add(new Error(err.IsWarning ? ErrorType.Warning : ErrorType.Error, err.ErrorText, new DocumentLocation(err.Line, err.Column))); } var doc = new T4ParsedDocument(fileName, template.RawSegments, errors); doc.Flags |= ParsedDocumentFlags.NonSerializable; return(System.Threading.Tasks.Task.FromResult((ParsedDocument)doc)); }
public static CodeCompileUnit GenerateCompileUnit(ITextTemplatingEngineHost host, ParsedTemplate pt, TemplateSettings settings) { //prep the compile unit var ccu = new CodeCompileUnit (); var namespac = new CodeNamespace (settings.Namespace); ccu.Namespaces.Add (namespac); var imports = new HashSet<string> (); imports.UnionWith (settings.Imports); imports.UnionWith (host.StandardImports); foreach (string ns in imports) namespac.Imports.Add (new CodeNamespaceImport (ns)); //prep the type var type = new CodeTypeDeclaration (settings.Name); type.IsPartial = true; if (!String.IsNullOrEmpty (settings.Inherits)) type.BaseTypes.Add (new CodeTypeReference (settings.Inherits)); else type.BaseTypes.Add (new CodeTypeReference (typeof (TextTransformation))); namespac.Types.Add (type); //prep the transform method var transformMeth = new CodeMemberMethod () { Name = "TransformText", ReturnType = new CodeTypeReference (typeof (String)), Attributes = MemberAttributes.Public | MemberAttributes.Override }; //method references that will need to be used multiple times var writeMeth = new CodeMethodReferenceExpression (new CodeThisReferenceExpression (), "Write"); var toStringMeth = new CodeMethodReferenceExpression (new CodeTypeReferenceExpression (typeof (ToStringHelper)), "ToStringWithCulture"); bool helperMode = false; //build the code from the segments foreach (TemplateSegment seg in pt.Content) { CodeStatement st = null; var location = new CodeLinePragma (seg.StartLocation.FileName ?? host.TemplateFile, seg.StartLocation.Line); switch (seg.Type) { case SegmentType.Block: if (helperMode) //TODO: are blocks permitted after helpers? throw new ParserException ("Blocks are not permitted after helpers", seg.StartLocation); st = new CodeSnippetStatement (seg.Text); break; case SegmentType.Expression: st = new CodeExpressionStatement ( new CodeMethodInvokeExpression (writeMeth, new CodeMethodInvokeExpression (toStringMeth, new CodeSnippetExpression (seg.Text)))); break; case SegmentType.Content: st = new CodeExpressionStatement (new CodeMethodInvokeExpression (writeMeth, new CodePrimitiveExpression (seg.Text))); break; case SegmentType.Helper: type.Members.Add (new CodeSnippetTypeMember (seg.Text) { LinePragma = 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); type.Members.Add (new CodeSnippetTypeMember (writer.ToString ()) { LinePragma = location }); } } else { st.LinePragma = location; transformMeth.Statements.Add (st); continue; } } } //complete the transform method transformMeth.Statements.Add (new CodeMethodReturnStatement ( new CodeMethodInvokeExpression ( new CodePropertyReferenceExpression ( new CodeThisReferenceExpression (), "GenerationEnvironment"), "ToString"))); type.Members.Add (transformMeth); //generate the Host property if needed if (settings.HostSpecific) { var hostField = new CodeMemberField (new CodeTypeReference (typeof (ITextTemplatingEngineHost)), "hostValue"); hostField.Attributes = (hostField.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Private; type.Members.Add (hostField); var hostProp = new CodeMemberProperty () { Name = "Host", Attributes = MemberAttributes.Public, HasGet = true, HasSet = true, Type = hostField.Type }; var hostFieldRef = new CodeFieldReferenceExpression (new CodeThisReferenceExpression (), "hostValue"); hostProp.SetStatements.Add (new CodeAssignStatement (hostFieldRef, new CodePropertySetValueReferenceExpression ())); hostProp.GetStatements.Add (new CodeMethodReturnStatement (hostFieldRef)); type.Members.Add (hostProp); } return ccu; }
private static TemplateGenerationResult GenerateTemplate( string templateFile, DeserializedLarancaFile larancaFile, string folder, string collectorTypesAsm, string genUtilsAsm, string newtonsoftAsm, string projFile) { var generator = new ToolTemplateGenerator(); var inputFile = templateFile; string inputContent; try { inputContent = File.ReadAllText(inputFile); } catch (IOException ex) { Console.Error.WriteLine("Could not read input file '" + inputFile + "':\n" + ex); return(new TemplateGenerationResult() { StatusCode = 1 }); } if (inputContent.Length == 0) { Console.Error.WriteLine("Input is empty"); return(new TemplateGenerationResult() { StatusCode = 1 }); } var pt = ParsedTemplate.FromText(inputContent, generator); var larnacaPropertiesExtractResult = TemplateLarnacaProperties.Extract(pt); if (larnacaPropertiesExtractResult.Fail()) { Console.Error.WriteLine($"Failed to parse larnaca propertsions of template: {templateFile}. {larnacaPropertiesExtractResult.StatusMessage}"); } var settings = TemplatingEngine.GetSettings(generator, pt); settings.Log = Console.Out; if (pt.Errors.Count > 0) { foreach (var currentError in pt.Errors) { var currentCompilerError = (CompilerError)currentError; if (currentCompilerError.IsWarning) { Console.WriteLine(currentCompilerError.ToString()); } else { Console.Error.WriteLine(currentCompilerError.ToString()); generator.Errors.Add(currentCompilerError); } } } var outputFile = inputFile; if (Path.HasExtension(outputFile)) { var dir = Path.GetDirectoryName(outputFile); var fn = Path.GetFileNameWithoutExtension(outputFile); outputFile = Path.Combine(dir, fn + (settings.Extension ?? ".txt")); } else { outputFile = outputFile + (settings.Extension ?? ".txt"); } HashSet <string> assemblyNamesToRemove = new HashSet <string>(new[] { Path.GetFileName(collectorTypesAsm), Path.GetFileName(genUtilsAsm), Path.GetFileName(newtonsoftAsm), }, StringComparer.OrdinalIgnoreCase); //fix template assemblies path foreach (var x in settings.Assemblies.ToArray()) { if (assemblyNamesToRemove.Contains(Path.GetFileName(x))) { settings.Assemblies.Remove(x); } else { settings.Assemblies.Add(FixPath(x, folder)); } } settings.Assemblies.Add(collectorTypesAsm); settings.Assemblies.Add(genUtilsAsm); settings.Assemblies.Add(newtonsoftAsm); string outputContent = null; if (!generator.Errors.HasErrors) { var larnacaDirective = pt.Directives.FirstOrDefault(d => d.Name.Equals("larnaca", StringComparison.OrdinalIgnoreCase)); if (larancaFile?.DatabaseMeta != null) { generator.AddParameter(null, null, "dbMeta", larancaFile.DatabaseMeta); } generator.AddParameter(null, null, "projFile", projFile); outputContent = generator.ProcessTemplate(pt, inputFile, inputContent, ref outputFile, settings); } if (!generator.Errors.HasErrors) { try { if (outputFile.EndsWith(".g.g.cs", StringComparison.OrdinalIgnoreCase)) { outputFile = outputFile.Substring(0, outputFile.Length - ".g.g.cs".Length) + ".g.cs"; } File.WriteAllText(outputFile, outputContent, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false)); if (outputFile.EndsWith(".cs", StringComparison.OrdinalIgnoreCase)) { if (larnacaPropertiesExtractResult.Data?.DoNotCompile ?? false) { return(new TemplateGenerationResult()); } else { return(new TemplateGenerationResult() { CSFileToCompile = outputFile }); } } else if (outputFile.EndsWith(".csproj", StringComparison.OrdinalIgnoreCase)) { if ((larnacaPropertiesExtractResult.Data?.Type ?? ETemplateType.undefined) == ETemplateType.Analysis) { return(new TemplateGenerationResult() { AnalysisProjectFileToBuild = outputFile }); } else { return(new TemplateGenerationResult()); } } else { return(new TemplateGenerationResult()); } } catch (IOException ex) { Console.Error.WriteLine("Could not write output file '" + outputFile + "':\n" + ex); return(new TemplateGenerationResult() { StatusCode = 1 }); } } else { Console.Error.WriteLine(inputFile == null ? "Processing failed." : $"Processing '{inputFile}' failed."); return(new TemplateGenerationResult() { StatusCode = 1 }); } }
static bool ComplainExcessAttributes(Directive dt, ParsedTemplate pt) { if (dt.Attributes.Count == 0) return false; StringBuilder sb = new StringBuilder ("Unknown attributes "); bool first = true; foreach (string key in dt.Attributes.Keys) { if (!first) { sb.Append (", "); } else { first = false; } sb.Append (key); } sb.Append (" found in "); sb.Append (dt.Name); sb.Append (" directive."); pt.LogWarning (sb.ToString (), dt.StartLocation); return false; }
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; }
internal static OperationResult InstallUpdateTemplates(string csproj, string[] larancaFiles, string[] larnacaFilesPackageIdentities, string targetDir, string outAddedTemplates) { var templatesRootPath = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(typeof(TemplateFileManager).Assembly.Location), "templates")); var csprojFolder = Path.GetDirectoryName(Path.GetFullPath(csproj)); var targetFolderFullPath = Path.GetFullPath(Path.Combine(csprojFolder, targetDir)); var rellativeTargetPath = Path.GetRelativePath(csprojFolder, targetFolderFullPath); List <TemplateFile> templates = new List <TemplateFile>(); foreach (var currentTemplate in Directory.EnumerateFiles(templatesRootPath, "*.lca.tt", SearchOption.AllDirectories)) { ETemplateType templateType = ETemplateType.undefined; ETemplateReplication templateReplication = ETemplateReplication.undefined; bool templateError; var fullTemplatePath = Path.GetFullPath(currentTemplate); try { var templateContent = File.ReadAllText(fullTemplatePath); var generator = new ToolTemplateGenerator(); var pt = ParsedTemplate.FromText(templateContent, generator); var extractResult = TemplateLarnacaProperties.Extract(pt); if (extractResult.Fail()) { templateError = true; Console.Error.WriteLine($"Failed to extract larnaca properties from template {fullTemplatePath}. {extractResult.StatusMessage}"); } else { templateError = false; templateType = extractResult.Data.Type; templateReplication = extractResult.Data.Replication; } } catch (Exception ex) { templateError = true; Console.Error.WriteLine($"Failed to load template {currentTemplate}: {ex}"); } if (templateError) { continue; } string subPath; if (fullTemplatePath.StartsWith(templatesRootPath, StringComparison.OrdinalIgnoreCase)) { subPath = fullTemplatePath.Substring(templatesRootPath.Length + 1); } else { subPath = Path.GetFileName(currentTemplate); } string targetRelativePath; if (templateReplication == ETemplateReplication.Single) { // no need to larnaca package subdir string targetFullPath = Path.Combine(targetFolderFullPath, subPath); targetRelativePath = Path.GetRelativePath(csprojFolder, targetFullPath); } else { targetRelativePath = null; } bool singleTemplateWritten = false; if (templateType == ETemplateType.Analysis) { if (templateReplication != ETemplateReplication.Single) { Console.Error.WriteLine($"Invalid template {currentTemplate}, cannot have templateType={templateType} and templateReplication={templateReplication}"); } else { templates.Add(new TemplateFile(fullTemplatePath, subPath, targetRelativePath, "none")); } } else { for (int i = 0; i < larancaFiles.Length; i++) { string currentLarnacaFile = larancaFiles[i]; string currentLarnacaPackageId = larnacaFilesPackageIdentities[i]; var loadedFile = DeserializedLarancaFile.Load(currentLarnacaFile); if (loadedFile.Fail()) { Console.Error.WriteLine($"Failed to load larnaca file ({currentLarnacaFile}): {loadedFile.StatusMessage}"); } else { if (loadedFile.Data.DatabaseMeta != null && templateType == ETemplateType.DB) { if (templateReplication == ETemplateReplication.Project) { var targetLarnacaPackageSubdir = Path.Combine(targetFolderFullPath, currentLarnacaPackageId); string targetFullPath = Path.Combine(targetLarnacaPackageSubdir, subPath); targetRelativePath = Path.GetRelativePath(csprojFolder, targetFullPath); templates.Add(new TemplateFile(fullTemplatePath, subPath, targetRelativePath, currentLarnacaPackageId)); } else { if (!singleTemplateWritten) { singleTemplateWritten = true; templates.Add(new TemplateFile(fullTemplatePath, subPath, targetRelativePath, "none")); } } } } } } } var updateCsprojOp = WriteTemplateFilesToCsproj(csproj, templates); if (updateCsprojOp.Fail()) { return(updateCsprojOp); } foreach (var currentTemplate in templates) { // todo: check if newer if (currentTemplate.TemplateUpdateTemplateMode != ETemplateUpdateTemplateMode.None) { var targetPath = Path.GetFullPath(Path.Combine(csprojFolder, currentTemplate.TargetRelativePath)); Directory.CreateDirectory(Path.GetDirectoryName(targetPath)); File.Copy(currentTemplate.SourceFullPath, targetPath, true); } } if (!string.IsNullOrWhiteSpace(outAddedTemplates)) { Directory.CreateDirectory(Path.GetDirectoryName(outAddedTemplates)); File.WriteAllText(outAddedTemplates, string.Join(Environment.NewLine, updateCsprojOp.Data.Values.Select(t => t.TargetRelativePath))); } return(new OperationResult()); }
public CSharpCodeEmitter(TextWriter output, ParsedTemplate template) { this.template = template; this.output = output; }
protected void Load() { try { _template = Formatter.LocatorBasedFormatter(_lib, _path, _resource, _factory).ParsedTemplate; } catch (ResourceException FNFe) { throw TemplateException.TemplateFailedToInitialize(_path, FNFe).WithHttpErrorCode(404); } catch (ExceptionWithContext EWC) { throw TemplateExceptionWithContext.ErrorInTemplate(_path, EWC).AddErrorCodeIfNull(500); } catch (Exception e) { throw TemplateException.ErrorInTemplate(_path, e).WithHttpErrorCode(500); } }
return false; } public static CodeCompileUnit GenerateCompileUnit (ITextTemplatingEngineHost host, ParsedTemplate pt, TemplateSettings settings) { //prep the compile unit CodeCompileUnit ccu = new CodeCompileUnit (); CodeNamespace namespac = new CodeNamespace (settings.Namespace); ccu.Namespaces.Add (namespac); HashSet<string> imports = new HashSet<string> (); imports.UnionWith (settings.Imports); imports.UnionWith (host.StandardImports); foreach (string ns in imports) namespac.Imports.Add (new CodeNamespaceImport (ns)); //prep the type CodeTypeDeclaration type = new CodeTypeDeclaration (settings.Name); if (!String.IsNullOrEmpty (settings.Inherits)) type.BaseTypes.Add (new CodeTypeReference (settings.Inherits)); else type.BaseTypes.Add (new CodeTypeReference (typeof (TextTransformation))); namespac.Types.Add (type); //prep the transform method CodeMemberMethod transformMeth = new CodeMemberMethod (); transformMeth.Name = "TransformText"; transformMeth.ReturnType = new CodeTypeReference (typeof (String)); transformMeth.Attributes = MemberAttributes.Public | MemberAttributes.Override; //method references that will need to be used multiple times CodeMethodReferenceExpression writeMeth = new CodeMethodReferenceExpression (new CodeThisReferenceExpression (), "Write"); CodeMethodReferenceExpression toStringMeth = new CodeMethodReferenceExpression (new CodeTypeReferenceExpression (typeof (ToStringHelper)), "ToStringWithCulture"); //build the code from the segments foreach (TemplateSegment seg in pt.Content) { CodeStatement st = null; switch (seg.Type) { case SegmentType.Block: st = new CodeSnippetStatement (seg.Text); break; case SegmentType.Expression: st = new CodeExpressionStatement ( new CodeMethodInvokeExpression (writeMeth, new CodeMethodInvokeExpression (toStringMeth, new CodeSnippetExpression (seg.Text)))); break; case SegmentType.Content: st = new CodeExpressionStatement (new CodeMethodInvokeExpression (writeMeth, new CodePrimitiveExpression (seg.Text))); break; case SegmentType.Helper: CodeTypeMember mem = new CodeSnippetTypeMember (seg.Text); mem.LinePragma = new CodeLinePragma (host.TemplateFile, seg.StartLocation.Line); type.Members.Add (mem); break; default: throw new InvalidOperationException (); } if (st != null) { st.LinePragma = new CodeLinePragma (host.TemplateFile, seg.StartLocation.Line); transformMeth.Statements.Add (st); } } //complete the transform method transformMeth.Statements.Add (new CodeMethodReturnStatement ( new CodeMethodInvokeExpression ( new CodePropertyReferenceExpression ( new CodeThisReferenceExpression (), "GenerationEnvironment"), "ToString"))); type.Members.Add (transformMeth); //generate the Host property if needed if (settings.HostSpecific) { CodeMemberField hostField = new CodeMemberField (new CodeTypeReference (typeof (ITextTemplatingEngineHost)), "hostValue"); hostField.Attributes = (hostField.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Private; type.Members.Add (hostField); CodeMemberProperty hostProp = new CodeMemberProperty (); hostProp.Name = "Host"; hostProp.Attributes = MemberAttributes.Public; hostProp.HasGet = hostProp.HasGet = true; hostProp.Type = hostField.Type; CodeFieldReferenceExpression hostFieldRef = new CodeFieldReferenceExpression (new CodeThisReferenceExpression (), "hostValue"); hostProp.SetStatements.Add (new CodeAssignStatement (hostFieldRef, new CodePropertySetValueReferenceExpression ())); hostProp.GetStatements.Add (new CodeMethodReturnStatement (hostFieldRef)); type.Members.Add (hostProp); }
public override Output CreateNewOutput(ParsedTemplate parsedTemplate, TextWriter writer) { return new CustomOutput(parsedTemplate, writer); }
/// <summary> /// Extracts template source and assembly references information from T4 template file. /// </summary> /// <param name="t4templatePath">Path to T4 template.</param> /// <param name="references">List of assembly references for Roslyn.</param> /// <param name="templateCode">Template source code.</param> /// <param name="imports">List of imports (usings) from T4 template.</param> /// <returns>Status of method execution.</returns> private int PreprocessTemplate(string t4templatePath, out IReadOnlyCollection <MetadataReference> references, out string templateCode, out IReadOnlyList <string> imports) { references = Array.Empty <MetadataReference>(); imports = Array.Empty <string>(); var generator = new TemplateGenerator(); var templateText = File.ReadAllText(t4templatePath); var template = ParsedTemplate.FromText(templateText, generator); // parse template by mono.t4 if (!generator.PreprocessTemplate(null, TEMPLATE_CLASS_NAME, null, templateText, out var language, out var referencesFromTemplate, out templateCode)) { Console.Error.WriteLine("T4 template pre-processing failed:"); foreach (CompilerError?error in generator.Errors) { if (error != null) { Console.Error.WriteLine($"\t{error.FileName} ({error.Line}, {error.Column}): {error.ErrorText}"); } } return(StatusCodes.T4_ERROR); } // make some basic assertions if (language != "C#") { Console.Error.WriteLine($"T4 template language should be C# but got '{language}'"); return(StatusCodes.T4_ERROR); } // prepare references for compilation var referencesList = new List <MetadataReference>(); // normalize assembly pathes for (var i = 0; i < referencesFromTemplate.Length; i++) { referencesFromTemplate[i] = Path.GetFullPath(referencesFromTemplate[i]); } // imports from T4 referencesList.AddRange(referencesFromTemplate.Select(file => MetadataReference.CreateFromFile(file))); // default linq2db imports // current tool (for host class) referencesList.Add(MetadataReference.CreateFromFile(typeof(LinqToDBHost).Assembly.Location)); // linq2db.Tools referencesList.Add(MetadataReference.CreateFromFile(typeof(ScaffoldOptions).Assembly.Location)); // linq2db referencesList.Add(MetadataReference.CreateFromFile(typeof(ProviderName).Assembly.Location)); // reference all current runtime assemblies to not force user to specify a lot of small stuff // // get path to framework folder var fwPath = Path.GetDirectoryName(typeof(object).Assembly.Location) !; // reference netstandard + System* referencesList.Add(MetadataReference.CreateFromFile(Path.Combine(fwPath, "netstandard.dll"))); foreach (var asmName in Directory.GetFiles(fwPath, "System*.dll")) { referencesList.Add(MetadataReference.CreateFromFile(Path.Combine(fwPath, asmName))); } var usings = new List <string>(); foreach (var directive in template.Directives) { if (directive.Name.ToLowerInvariant() == "import") { usings.Add(directive.Extract("namespace")); } } references = referencesList; imports = usings; // register assembly resolver for loaded template RegisterAssemblyResolver(referencesFromTemplate); return(StatusCodes.SUCCESS); }
public TemplateAttribute(ParsedTemplate resultParts) { _resultParts = resultParts; }
public Formatter Parse() { var f = _locatorFactory.CloneForTagLib(_lib); if (_initialLocator == null) { _initialLocator = f.GetNewLocator(); } var formatter = new InternalFormatter(new TagLibParserFactory(new TagLibForParsing(_lib), _expressionLib, f, _tagValidator), _expressionLib, _template, _allowTags, _initialLocator); try { formatter.Parse(); var templateValidator = _templateValidator ?? CreateTemplateValidatorFor(_lib); templateValidator.Validate(formatter.ParsedTemplate); } finally { _templateParsed = formatter.ParsedTemplate; } return this; }
public bool PrepareTransformation(Guid runnerId, ParsedTemplate pt, string content, ITextTemplatingEngineHost host, TemplateSettings settings) { return(runFactory.PrepareTransformation(runnerId, pt, content, host, settings)); }
public CustomOutput(ParsedTemplate template, TextWriter writer) : base(template, writer) { }