コード例 #1
0
        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));
        }
コード例 #2
0
        public void Dispose()
        {
            Debug.Assert(Scopes.Count == 1);
            var rootScope = Scopes.Pop();

            foreach (var line in rootScope)
            {
                Writer.WriteLine(line);
            }
        }
コード例 #3
0
ファイル: ObjectScope.cs プロジェクト: tahiralvi/Nemo
        public void Dispose()
        {
            if (AutoCommit)
            {
                if (_hasException == null)
                {
                    long exceptionCode = Marshal.GetExceptionCode();
                    _hasException = exceptionCode != 0 && exceptionCode != 0xCCCCCCCC;
                }

                if (_hasException.Value || !Item.Commit(ItemType))
                {
                    Item.Rollback(ItemType);
                }
            }
            Transaction.Dispose();
            Scopes.Pop();
        }
コード例 #4
0
        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}");
        }
コード例 #5
0
        public IEnumerable <string> Transform(FilterNode item)
        {
            _EncounteredOutputStyleBlock = true;
            if (ShouldRender == false)
            {
                yield break;
            }

            var filterExpression = $"{item.Filter}(__item)";

            foreach (var output in item.FilterContents.Transform(this))
            {
                Scopes.Push("Filter");
                Scopes.Current.DefineAndSetVariable("__item", output);

                var evaluated = Environment.Evaluation.EvaluateDynamic(filterExpression, Scopes);


                Scopes.Pop("Filter");

                yield return(evaluated?.ToString() ?? string.Empty);
            }
        }
コード例 #6
0
 /// <summary>Starts a new scope</summary>
 /// <returns><see cref="IDisposable"/> to enable automatic restore of the scope in RAII style patterns</returns>
 /// <remarks>
 /// A new scope is pushed on the stack and remains active until the <see cref="IDisposable.Dispose"/> method
 /// of the return is called. Normally, code generation does this with a language provided means of ensuring the
 /// Dispose method is called even when an exception occurs. (i.e. C# 'using' or try/finally)
 /// </remarks>
 public IDisposable EnterScope( )
 {
     Scopes.Push(new Dictionary <string, T>( ));
     return(new DisposableAction(() => Scopes.Pop( )));
 }
コード例 #7
0
        public IEnumerable <string> Transform(ForNode item)
        {
            _EncounteredOutputStyleBlock = true;
            if (!(ShouldRender && _EncounteredOutputStyleBlock))
            {
                yield break;
            }

            object?evalObj;

            if (item.Expression != null)
            {
                evalObj = Environment.Evaluation.EvaluateDynamic(item.Expression.Expression, Scopes);
            }
            else
            {
                evalObj = item.AlreadyEvaluatedObject;
            }

            Func <object?[], object?> loopFunction = args =>
            {
                if (args?.Length != 1)
                {
                    throw new NotImplementedException();
                }
                return(new ForNode(item.PrimaryBlock, item.ElseBlock, item.VariableNames,
                                   args[0], item.Filter, item.Recursive,
                                   item.EndParsingNode, item.WhiteSpaceControl));
            };

            var arr = CollectionEx.ToArray(evalObj) ?? Array.Empty <object>();

            if (item.Filter != null)
            {
                var filtered = new List <object?>();
                foreach (var arrItem in arr)
                {
                    var unpacked = ReflectionHelpers.Unpack(arrItem, item.VariableNames.Length);
                    Scopes.Push($"ForNode | Filter: {item.Filter} Item: {arrItem}");
                    for (var i = 0; i < unpacked.Length; ++i)
                    {
                        Scopes.Current.DefineAndSetVariable(item.VariableNames[i], unpacked[i]);
                    }
                    var result = Environment.Evaluation.EvaluateDynamic(item.Filter.Expression, Scopes);
                    Scopes.Pop($"ForNode | Filter: {item.Filter} Item: {arrItem}");
                    if (TypeCoercion.GetTruthy(result))
                    {
                        filtered.Add(arrItem);
                    }
                }
                arr = filtered.ToArray();
            }

            if (arr.Length == 0 && item.ElseBlock != null)
            {
                foreach (var output in item.ElseBlock.Transform(this))
                {
                    yield return(output);
                }
                yield break;
            }


            var depth = 0;

            if (Scopes.Current.TryGetVariable <LoopInfo>("loop", out var previousLoopInfo) && previousLoopInfo != null)
            {
                depth = previousLoopInfo.depth0 + 1;
            }

            var loopInfo = new LoopInfo(arr, loopFunction, depth);

            for (var index = 0; index < arr.Length; ++index)
            {
                loopInfo.index0 = index;
                var arrItem  = arr[index];
                var unpacked = ReflectionHelpers.Unpack(arrItem, item.VariableNames.Length);

                Scopes.Push($"ForNode: {item.Expression} Item: {arrItem}");
                for (var i = 0; i < unpacked.Length; ++i)
                {
                    Scopes.Current.DefineAndSetVariable(item.VariableNames[i], unpacked[i]);
                }
                Scopes.Current.DefineAndSetVariable("loop", loopInfo);
                foreach (var output in item.PrimaryBlock.Transform(this))
                {
                    yield return(output);
                }
                Scopes.Pop($"ForNode: {item.Expression} Item: {arrItem}");
            }
            yield break;
        }
コード例 #8
0
 internal static CacheEntry LeaveScope()
 {
     return(Scopes.Pop());
 }
コード例 #9
0
 /// <summary>
 /// Do not override this method. Use Disposing instead.
 /// </summary>
 public void Dispose()
 {
     Disposing(); Scopes.Pop();
 }
コード例 #10
0
ファイル: Mira.cs プロジェクト: Pirmayr/Mira
 public void LeaveScope() => scopes.Pop();