-
Notifications
You must be signed in to change notification settings - Fork 240
Expand file tree
/
Copy pathHandlebarsCompiler.cs
More file actions
110 lines (92 loc) · 4.49 KB
/
Copy pathHandlebarsCompiler.cs
File metadata and controls
110 lines (92 loc) · 4.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
using System;
using System.Collections.Generic;
using System.Linq;
using Expressions.Shortcuts;
using HandlebarsDotNet.Compiler.Lexer;
using HandlebarsDotNet.IO;
using HandlebarsDotNet.PathStructure;
namespace HandlebarsDotNet.Compiler
{
public delegate void TemplateDelegate(in EncodedTextWriter writer, BindingContext context);
internal static class HandlebarsCompiler
{
public static TemplateDelegate Compile(ExtendedStringReader source, CompilationContext compilationContext)
{
var configuration = compilationContext.Configuration;
var createdFeatures = configuration.Features;
for (var index = 0; index < createdFeatures.Count; index++)
{
createdFeatures[index].OnCompiling(configuration);
}
var tokens = Tokenizer.Tokenize(source);
var expressions = ExpressionBuilder.ConvertTokensToExpressions(tokens, configuration);
var action = FunctionBuilder.Compile(expressions, compilationContext, out var decorators);
if (decorators.Count > 0)
{
var a1 = action;
var decorator = decorators.Compile(compilationContext);
action = (in EncodedTextWriter writer, BindingContext context) =>
{
decorator(writer, context, a1)(writer, context);
};
}
for (var index = 0; index < createdFeatures.Count; index++)
{
createdFeatures[index].CompilationCompleted();
}
return action;
}
internal static TemplateDelegate CompileView(ViewReaderFactory readerFactoryFactory, string templatePath, CompilationContext compilationContext)
{
var configuration = compilationContext.Configuration;
IEnumerable<object> tokens;
using (var sr = readerFactoryFactory(configuration, templatePath))
{
using (var reader = new ExtendedStringReader(sr))
{
tokens = Tokenizer.Tokenize(reader).ToArray();
}
}
var layoutToken = tokens.OfType<LayoutToken>().SingleOrDefault();
var expressions = ExpressionBuilder.ConvertTokensToExpressions(tokens, configuration);
var compiledView = FunctionBuilder.Compile(expressions, compilationContext, out var decorators);
if (decorators.Count > 0)
{
var a1 = compiledView;
var decorator = decorators.Compile(compilationContext);
compiledView = (in EncodedTextWriter writer, BindingContext context) =>
{
decorator(writer, context, a1)(writer, context);
};
}
if (layoutToken == null) return compiledView;
var fs = configuration.FileSystem;
var layoutPath = fs.Closest(templatePath, layoutToken.Value + ".hbs");
if (layoutPath == null)
throw new InvalidOperationException($"Cannot find layout '{layoutToken.Value}' for template '{templatePath}'");
var compiledLayout = CompileView(readerFactoryFactory, layoutPath, new CompilationContext(compilationContext));
return (in EncodedTextWriter writer, BindingContext context) =>
{
var config = context.Configuration;
using var bindingContext = BindingContext.Create(config, null);
foreach (var pair in context.ContextDataObject)
{
switch (pair.Key.WellKnownVariable)
{
case WellKnownVariable.Parent:
case WellKnownVariable.Root:
continue;
}
bindingContext.ContextDataObject[pair.Key] = pair.Value;
}
using var innerWriter = ReusableStringWriter.Get(config.FormatProvider);
using var textWriter = new EncodedTextWriter(innerWriter, config.TextEncoder, FormatterProvider.Current, true);
compiledView(textWriter, context);
var inner = innerWriter.ToString();
var viewModel = new LayoutViewModel(inner, context.Value);
bindingContext.Value = viewModel;
compiledLayout(writer, bindingContext);
};
}
}
}