Exemplo n.º 1
0
        private static Expression AddLambdaDefinition(PartialLambdaExpressionDefinition definition, List <Expression> partialContent, Type actionType, Expression[] @params)
        {
            var convertedParams = @params.Select(param =>
            {
                return(param is ParameterExpression
                    ? (ParameterExpression)param
                    : Expression.Parameter(param.Type));
            });

            var block = partialContent.Count > 0
                    ? Expression.Block(partialContent)
                    : EmptyPartial;

            definition.Partial = Expression.Lambda(actionType, block, convertedParams);

            return(Expression.Invoke(definition.Variable, convertedParams));
        }
Exemplo n.º 2
0
        /// <inheritdoc/>
        protected override async Task WriteAsync(CompilationRenderer renderer, PartialToken obj, CompilerContext context)
        {
            var    partialName = obj.Content;
            string template    = null;

            if (context.PartialLoader != null)
            {
                template = await context.PartialLoader.LoadAsync(partialName.ToString());
            }

            if (template != null)
            {
                var sourceDatas = context.GetNestedSourceData().ToArray();
                var key         = PartialLambdaExpressionDefinition.GetKey(template, context.SourceData.Type);

                // Recursive calls use the existing variable to call the partial lambda.
                if (renderer.PartialExpressionCache.TryGetValue(key, out var partialVariable))
                {
                    renderer.AddExpressionToScope(Expression.Invoke(partialVariable.Variable, context.SourceData));
                    return;
                }

                var sourceData = sourceDatas.Select(s => s.Type).ToArray();

                if (sourceData.Length > 16)
                {
                    throw new StubbleException("Cannot call a partial with more than 16 parameters.\nThis is likely due to a large amount of section scopes");
                }

                var actionType = Expression.GetActionType(sourceData);

                var definition = new PartialLambdaExpressionDefinition
                {
                    Variable = Expression.Parameter(actionType)
                };

                renderer.PartialExpressionCache.Add(key, definition);

                var partialContent = await renderer.RenderAsync(context.CompilerSettings.Parser.Parse(template, lineIndent: obj.LineIndent), context) as List <Expression>;

                renderer.AddExpressionToScope(AddLambdaDefinition(definition, partialContent, actionType, sourceDatas));
            }
        }