private JinjaUserDefinedFunction ConvertMacroToUserDefinedFunction(MacroNode macro) { var usesCaller = macro.Contents.Transform(CallerFinderVisitor.Instance).Any(x => x); Func <UserDefinedArgumentData, object?> func = arguments => { using var checkout = StringBuilderPool.Instance.Checkout(); var stringBuilder = checkout.CheckedOutObject; Scopes.Push($"Macro: {macro.FunctionDeclaration.Name}"); foreach (var arg in arguments.AllArguments) { Scopes.Current.DefineAndSetVariable(arg.Name, arg.Value); } Scopes.Current.DefineAndSetVariable("varargs", arguments.AdditionalPositionalArguments.Select(arg => arg.Value)); Scopes.Current.DefineAndSetVariable("kwargs", arguments.AdditionalKeywordArguments); foreach (var output in macro.Contents.Transform(this)) { stringBuilder.Append(output); } Scopes.Pop($"Macro: {macro.FunctionDeclaration.Name}"); return(stringBuilder.ToString()); }; UserDefinedFunction.UserDefinedFunctionDelegate del = args => func(args); return(new JinjaUserDefinedFunction(macro.FunctionDeclaration, del, usesCaller)); }
public IEnumerable <string> Transform(CallNode item) { _EncounteredOutputStyleBlock = true; if (!(ShouldRender && _EncounteredOutputStyleBlock)) { yield break; } Func <UserDefinedArgumentData, object?> func = arguments => { using var checkout = StringBuilderPool.Instance.Checkout(); var stringBuilder = checkout.CheckedOutObject; foreach (var output in item.Contents.Transform(this)) { stringBuilder.Append(output); } return(stringBuilder.ToString()); }; if (Environment.Evaluation.TryParseFunctionDeclaration(item.CallerDefinition.Expression, out var functionDeclaration) == false || functionDeclaration == null) { throw new NotImplementedException(); } Scopes.Push($"Call: {item.CallerDefinition.Expression}"); UserDefinedFunction.UserDefinedFunctionDelegate del = args => func(args); Scopes.Current.DefineAndSetVariable("caller", new JinjaUserDefinedFunction(functionDeclaration, del)); var evalObj = Environment.Evaluation.EvaluateDynamic(item.MacroCall.ExpressionParserNode, ExpressionParserTransformer); if (!(evalObj is ExpressionParser.Void)) { yield return(JinjaCustomStringProvider.Instance.ToString(evalObj)); } Scopes.Pop($"Call: {item.CallerDefinition.Expression}"); }