@@ -49,6 +49,7 @@ export class Evaluator extends AbstractParseTreeVisitor<any> implements LGFilePa
49
49
public static readonly fromFileFunctionName = 'fromFile' ;
50
50
public static readonly templateFunctionName = 'template' ;
51
51
public static readonly isTemplateFunctionName = 'isTemplate' ;
52
+ private static readonly ReExecuteSuffix = '!' ;
52
53
53
54
public constructor ( templates : LGTemplate [ ] , expressionEngine : ExpressionEngine ) {
54
55
super ( ) ;
@@ -65,11 +66,15 @@ export class Evaluator extends AbstractParseTreeVisitor<any> implements LGFilePa
65
66
66
67
/**
67
68
* Evaluate a template with given name and scope.
68
- * @param templateName template name.
69
+ * @param inputTemplateName template name.
69
70
* @param scope scope.
70
71
* @returns Evaluate result.
71
72
*/
72
- public evaluateTemplate ( templateName : string , scope : any ) : any {
73
+ public evaluateTemplate ( inputTemplateName : string , scope : any ) : any {
74
+ let templateName : string ;
75
+ let reExecute : boolean ;
76
+ ( { reExecute, pureTemplateName : templateName } = this . parseTemplateName ( inputTemplateName ) ) ;
77
+
73
78
if ( ! ( templateName in this . templateMap ) ) {
74
79
throw new Error ( `No such template: ${ templateName } ` ) ;
75
80
}
@@ -91,7 +96,7 @@ export class Evaluator extends AbstractParseTreeVisitor<any> implements LGFilePa
91
96
92
97
if ( this . evalutationTargetStack . length !== 0 ) {
93
98
previousEvaluateTarget = this . evalutationTargetStack [ this . evalutationTargetStack . length - 1 ] ;
94
- if ( previousEvaluateTarget . evaluatedChildren . has ( currentEvulateId ) ) {
99
+ if ( ! reExecute && previousEvaluateTarget . evaluatedChildren . has ( currentEvulateId ) ) {
95
100
return previousEvaluateTarget . evaluatedChildren . get ( currentEvulateId ) ;
96
101
}
97
102
}
@@ -236,7 +241,9 @@ export class Evaluator extends AbstractParseTreeVisitor<any> implements LGFilePa
236
241
} ) . join ( '' ) ;
237
242
}
238
243
239
- public constructScope ( templateName : string , args : any [ ] ) : any {
244
+ public constructScope ( inputTemplateName : string , args : any [ ] ) : any {
245
+ var templateName = this . parseTemplateName ( inputTemplateName ) . pureTemplateName ;
246
+
240
247
if ( ! this . templateMap [ templateName ] ) {
241
248
throw new Error ( `No such template ${ templateName } ` ) ;
242
249
}
@@ -403,9 +410,10 @@ export class Evaluator extends AbstractParseTreeVisitor<any> implements LGFilePa
403
410
return baseLookup ( name . substring ( prebuiltPrefix . length ) ) ;
404
411
}
405
412
406
- if ( this . templateMap [ name ] ) {
413
+ var templateName = this . parseTemplateName ( name ) . pureTemplateName ;
414
+ if ( templateName in this . templateMap ) {
407
415
// tslint:disable-next-line: max-line-length
408
- return new ExpressionEvaluator ( name , ExpressionFunctions . apply ( this . templateEvaluator ( name ) ) , ReturnType . Object , this . validTemplateReference ) ;
416
+ return new ExpressionEvaluator ( templateName , ExpressionFunctions . apply ( this . templateEvaluator ( name ) ) , ReturnType . Object , this . validTemplateReference ) ;
409
417
}
410
418
411
419
if ( name === Evaluator . templateFunctionName ) {
@@ -581,4 +589,16 @@ export class Evaluator extends AbstractParseTreeVisitor<any> implements LGFilePa
581
589
throw new Error ( `arguments mismatch for template ${ templateName } , expect ${ expectedArgsCount } actual ${ actualArgsCount } ` ) ;
582
590
}
583
591
}
592
+
593
+ private parseTemplateName ( templateName : string ) : { reExecute : boolean ; pureTemplateName : string } {
594
+ if ( ! templateName ) {
595
+ throw new Error ( 'template name is empty.' ) ;
596
+ }
597
+
598
+ if ( templateName . endsWith ( Evaluator . ReExecuteSuffix ) ) {
599
+ return { reExecute :true , pureTemplateName : templateName . substr ( 0 , templateName . length - Evaluator . ReExecuteSuffix . length ) } ;
600
+ } else {
601
+ return { reExecute :false , pureTemplateName : templateName } ;
602
+ }
603
+ }
584
604
}
0 commit comments