execute method
Executes the statement within the given ctx and returns the result as a JinjaValue.
Implementation
@override
JinjaValue execute(Context ctx) {
// A 'call' block is equivalent to calling the target function/macro
// with an additional keyword argument named 'caller', which is itself
// a macro that renders the body of the call block.
final callerMacro = JinjaFunction('caller', (callArgs, callKwargs) {
final callerCtx = ctx.derive();
_bindParameters(
'caller',
callerArgs,
callArgs,
callKwargs,
callerCtx,
ctx,
);
return _execCaptured(body, callerCtx);
});
final callExpr = call;
// We need to execute the call expression but inject the 'caller' kwarg.
// Instead of executing callExpr directly, we manually resolve the callee
// and invoke it with the combined arguments.
final callee = callExpr.callee.execute(ctx);
if (callee is! JinjaFunction) {
throw Exception('Callee must be a function/macro');
}
final args = callExpr.args
.where((a) => a is! KeywordArgumentExpression)
.map((a) => a.execute(ctx))
.toList();
final kwargs = <String, JinjaValue>{};
for (final arg in callExpr.args.whereType<KeywordArgumentExpression>()) {
kwargs[(arg.key as Identifier).name] = arg.val.execute(ctx);
}
// Inject caller
kwargs['caller'] = callerMacro;
return callee.handler(args, kwargs);
}