예제 #1
0
        public static Expression <Action <BindingContext, TextWriter, object> > Bind(CompilationContext context, Expression body, string templatePath)
        {
            var configuration = Arg(context.Configuration);

            var writerParameter = Parameter <TextWriter>("buffer");
            var objectParameter = Parameter <object>("data");

            var bindingContext          = Arg <BindingContext>(context.BindingContext);
            var textEncoder             = configuration.Property(o => o.TextEncoder);
            var writer                  = Var <EncodedTextWriter>("writer");
            var encodedWriterExpression = Call(() => EncodedTextWriter.From(writerParameter, (ITextEncoder)textEncoder));
            var parentContextArg        = Var <BindingContext>("parentContext");

            var newBindingContext = Call(
                () => BindingContext.Create((ICompiledHandlebarsConfiguration)configuration, objectParameter, writer, parentContextArg, templatePath)
                );

            Expression blockBuilder = Block()
                                      .Parameter(bindingContext)
                                      .Parameter(writer)
                                      .Parameter <bool>(out var shouldDispose)
                                      .Parameter <bool>(out var shouldDisposeWriter)
                                      .Line(bindingContext.Assign(objectParameter.As <BindingContext>()))
                                      .Line(Condition()
                                            .If(Expression.Equal(bindingContext, Null <BindingContext>()))
                                            .Then(block =>
            {
                block.Line(shouldDispose.Assign(true))
                .Line(writer.Assign(writerParameter.As <EncodedTextWriter>()))
                .Line(Condition()
                      .If(Expression.Equal(writer, Null <EncodedTextWriter>()))
                      .Then(b =>
                {
                    b.Line(shouldDisposeWriter.Assign(true))
                    .Line(writer.Assign(encodedWriterExpression));
                })
                      );

                block.Line(bindingContext.Assign(newBindingContext));
            })
                                            )
                                      .Line(Try()
                                            .Body(block => block.Lines(((BlockExpression)body).Expressions))
                                            .Finally(block =>
            {
                block.Lines(
                    Condition()
                    .If(shouldDispose)
                    .Then(bindingContext.Call(o => o.Dispose())),
                    Condition()
                    .If(shouldDisposeWriter)
                    .Then(writer.Call(o => o.Dispose()))
                    );
            })
                                            );

            return(Expression.Lambda <Action <BindingContext, TextWriter, object> >(blockBuilder, (ParameterExpression)parentContextArg.Expression, (ParameterExpression)writerParameter.Expression, (ParameterExpression)objectParameter.Expression));
        }
예제 #2
0
        public static Expression <Action <BindingContext, TextWriter, object> > Bind(CompilationContext context, Expression body, string templatePath)
        {
            var configuration = ExpressionShortcuts.Arg(context.Configuration);

            var writerParameter = ExpressionShortcuts.Parameter <TextWriter>("buffer");
            var objectParameter = ExpressionShortcuts.Parameter <object>("data");

            var bindingContext          = ExpressionShortcuts.Arg <BindingContext>(context.BindingContext);
            var inlinePartialsParameter = ExpressionShortcuts.Null <IDictionary <string, Action <TextWriter, object> > >();
            var textEncoder             = configuration.Property(o => o.TextEncoder);
            var encodedWriterExpression = ExpressionShortcuts.Call(() => EncodedTextWriter.From(writerParameter, (ITextEncoder)textEncoder));
            var parentContextArg        = ExpressionShortcuts.Var <BindingContext>("parentContext");

            var newBindingContext = ExpressionShortcuts.Call(
                () => BindingContext.Create(configuration, objectParameter, encodedWriterExpression, parentContextArg, templatePath, (IDictionary <string, Action <TextWriter, object> >)inlinePartialsParameter)
                );

            var shouldDispose = ExpressionShortcuts.Var <bool>("shouldDispose");

            Expression blockBuilder = ExpressionShortcuts.Block()
                                      .Parameter(bindingContext)
                                      .Parameter(shouldDispose)
                                      .Line(ExpressionShortcuts.Condition()
                                            .If(objectParameter.Is <BindingContext>(),
                                                bindingContext.Assign(objectParameter.As <BindingContext>())
                                                )
                                            .Else(block =>
            {
                block.Line(shouldDispose.Assign(true));
                block.Line(bindingContext.Assign(newBindingContext));
            })
                                            )
                                      .Line(ExpressionShortcuts.Try()
                                            .Body(block => block.Lines(((BlockExpression)body).Expressions))
                                            .Finally(ExpressionShortcuts.Condition()
                                                     .If(shouldDispose, bindingContext.Call(o => o.Dispose()))
                                                     )
                                            );

            return(Expression.Lambda <Action <BindingContext, TextWriter, object> >(blockBuilder, (ParameterExpression)parentContextArg.Expression, (ParameterExpression)writerParameter.Expression, (ParameterExpression)objectParameter.Expression));
        }