@@ -44,7 +44,7 @@ public static Templates ParseFile(
44
44
var fullPath = Path . GetFullPath ( filePath . NormalizePath ( ) ) ;
45
45
var content = File . ReadAllText ( fullPath ) ;
46
46
47
- return ParseText ( content , fullPath , importResolver , expressionParser ) ;
47
+ return InnerParseText ( content , fullPath , importResolver , expressionParser ) ;
48
48
}
49
49
50
50
/// <summary>
@@ -61,20 +61,39 @@ public static Templates ParseText(
61
61
ImportResolverDelegate importResolver = null ,
62
62
ExpressionParser expressionParser = null )
63
63
{
64
- importResolver = importResolver ?? DefaultFileResolver ;
65
- var lg = new Templates ( content : content , id : id , importResolver : importResolver , expressionParser : expressionParser ) ;
64
+ return InnerParseText ( content , id , importResolver , expressionParser ) ;
65
+ }
66
66
67
+ /// <summary>
68
+ /// Parser to turn lg content into a <see cref="Templates"/> based on the original LGFile.
69
+ /// </summary>
70
+ /// <param name="content">Text content contains lg templates.</param>
71
+ /// <param name="lg">original LGFile.</param>
72
+ /// <returns>new <see cref="Templates"/> entity.</returns>
73
+ public static Templates ParseTextWithRef ( string content , Templates lg )
74
+ {
75
+ if ( lg == null )
76
+ {
77
+ throw new ArgumentNullException ( nameof ( lg ) ) ;
78
+ }
79
+
80
+ var id = "inline content" ;
81
+ var newLG = new Templates ( content : content , id : id , importResolver : lg . ImportResolver , options : lg . Options ) ;
67
82
var diagnostics = new List < Diagnostic > ( ) ;
68
83
try
69
84
{
70
85
var ( templates , imports , invalidTemplateErrors , options ) = AntlrParse ( content , id ) ;
71
- lg . AddRange ( templates ) ;
72
- lg . Imports = imports ;
73
- lg . Options = options ;
86
+ newLG . AddRange ( templates ) ;
87
+ newLG . Imports = imports ;
88
+ newLG . Options = options ;
74
89
diagnostics . AddRange ( invalidTemplateErrors ) ;
75
90
76
- lg . References = GetReferences ( lg , importResolver ) ;
77
- var semanticErrors = new StaticChecker ( lg ) . Check ( ) ;
91
+ newLG . References = GetReferences ( newLG )
92
+ . Union ( lg . References )
93
+ . Union ( new List < Templates > { lg } )
94
+ . ToList ( ) ;
95
+
96
+ var semanticErrors = new StaticChecker ( newLG ) . Check ( ) ;
78
97
diagnostics . AddRange ( semanticErrors ) ;
79
98
}
80
99
catch ( TemplateException ex )
@@ -86,41 +105,47 @@ public static Templates ParseText(
86
105
diagnostics . Add ( BuildDiagnostic ( err . Message , source : id ) ) ;
87
106
}
88
107
89
- lg . Diagnostics = diagnostics ;
108
+ newLG . Diagnostics = diagnostics ;
90
109
91
- return lg ;
110
+ return newLG ;
92
111
}
93
112
94
113
/// <summary>
95
- /// Parser to turn lg content into a <see cref="Templates"/> based on the original LGFile .
114
+ /// Parser to turn lg content into a <see cref="Templates"/>.
96
115
/// </summary>
97
116
/// <param name="content">Text content contains lg templates.</param>
98
- /// <param name="lg">original LGFile.</param>
117
+ /// <param name="id">id is the identifier of content. If importResolver is null, id must be a full path string. </param>
118
+ /// <param name="importResolver">resolver to resolve LG import id to template text.</param>
119
+ /// <param name="expressionParser">expressionEngine parser engine for parsing expressions.</param>
120
+ /// <param name="cachedTemplates">give the file path and templates to avoid parsing and to improve performance.</param>
99
121
/// <returns>new <see cref="Templates"/> entity.</returns>
100
- public static Templates ParseTextWithRef ( string content , Templates lg )
122
+ private static Templates InnerParseText (
123
+ string content ,
124
+ string id = "" ,
125
+ ImportResolverDelegate importResolver = null ,
126
+ ExpressionParser expressionParser = null ,
127
+ Dictionary < string , Templates > cachedTemplates = null )
101
128
{
102
- if ( lg == null )
129
+ cachedTemplates = cachedTemplates ?? new Dictionary < string , Templates > ( ) ;
130
+ if ( cachedTemplates . ContainsKey ( id ) )
103
131
{
104
- throw new ArgumentNullException ( nameof ( lg ) ) ;
132
+ return cachedTemplates [ id ] ;
105
133
}
106
134
107
- var id = "inline content" ;
108
- var newLG = new Templates ( content : content , id : id , importResolver : lg . ImportResolver , options : lg . Options ) ;
135
+ importResolver = importResolver ?? DefaultFileResolver ;
136
+ var lg = new Templates ( content : content , id : id , importResolver : importResolver , expressionParser : expressionParser ) ;
137
+
109
138
var diagnostics = new List < Diagnostic > ( ) ;
110
139
try
111
140
{
112
141
var ( templates , imports , invalidTemplateErrors , options ) = AntlrParse ( content , id ) ;
113
- newLG . AddRange ( templates ) ;
114
- newLG . Imports = imports ;
115
- newLG . Options = options ;
142
+ lg . AddRange ( templates ) ;
143
+ lg . Imports = imports ;
144
+ lg . Options = options ;
116
145
diagnostics . AddRange ( invalidTemplateErrors ) ;
117
146
118
- newLG . References = GetReferences ( newLG , newLG . ImportResolver )
119
- . Union ( lg . References )
120
- . Union ( new List < Templates > { lg } )
121
- . ToList ( ) ;
122
-
123
- var semanticErrors = new StaticChecker ( newLG ) . Check ( ) ;
147
+ lg . References = GetReferences ( lg , cachedTemplates ) ;
148
+ var semanticErrors = new StaticChecker ( lg ) . Check ( ) ;
124
149
diagnostics . AddRange ( semanticErrors ) ;
125
150
}
126
151
catch ( TemplateException ex )
@@ -132,9 +157,9 @@ public static Templates ParseTextWithRef(string content, Templates lg)
132
157
diagnostics . Add ( BuildDiagnostic ( err . Message , source : id ) ) ;
133
158
}
134
159
135
- newLG . Diagnostics = diagnostics ;
160
+ lg . Diagnostics = diagnostics ;
136
161
137
- return newLG ;
162
+ return lg ;
138
163
}
139
164
140
165
/// <summary>
@@ -280,16 +305,16 @@ private static IList<TemplateImport> ExtractLGImports(LGFileParser.FileContext f
280
305
. ToList ( ) ;
281
306
}
282
307
283
- private static IList < Templates > GetReferences ( Templates file , ImportResolverDelegate importResolver )
308
+ private static IList < Templates > GetReferences ( Templates file , Dictionary < string , Templates > cachedTemplates = null )
284
309
{
285
310
var resourcesFound = new HashSet < Templates > ( ) ;
286
- ResolveImportResources ( file , resourcesFound , importResolver ) ;
311
+ ResolveImportResources ( file , resourcesFound , cachedTemplates ?? new Dictionary < string , Templates > ( ) ) ;
287
312
288
313
resourcesFound . Remove ( file ) ;
289
314
return resourcesFound . ToList ( ) ;
290
315
}
291
316
292
- private static void ResolveImportResources ( Templates start , HashSet < Templates > resourcesFound , ImportResolverDelegate importResolver )
317
+ private static void ResolveImportResources ( Templates start , HashSet < Templates > resourcesFound , Dictionary < string , Templates > cachedTemplates )
293
318
{
294
319
var resourceIds = start . Imports . Select ( lg => lg . Id ) ;
295
320
resourcesFound . Add ( start ) ;
@@ -298,11 +323,21 @@ private static void ResolveImportResources(Templates start, HashSet<Templates> r
298
323
{
299
324
try
300
325
{
301
- var ( content , path ) = importResolver ( start . Id , id ) ;
326
+ var ( content , path ) = start . ImportResolver ( start . Id , id ) ;
302
327
if ( resourcesFound . All ( u => u . Id != path ) )
303
328
{
304
- var childResource = ParseText ( content , path , importResolver , start . ExpressionParser ) ;
305
- ResolveImportResources ( childResource , resourcesFound , importResolver ) ;
329
+ Templates childResource ;
330
+ if ( cachedTemplates . ContainsKey ( path ) )
331
+ {
332
+ childResource = cachedTemplates [ path ] ;
333
+ }
334
+ else
335
+ {
336
+ childResource = InnerParseText ( content , path , start . ImportResolver , start . ExpressionParser , cachedTemplates ) ;
337
+ cachedTemplates . Add ( path , childResource ) ;
338
+ }
339
+
340
+ ResolveImportResources ( childResource , resourcesFound , cachedTemplates ) ;
306
341
}
307
342
}
308
343
catch ( TemplateException err )
0 commit comments