protected override Expression VisitPathExpression(PathExpression pex) { var context = ExpressionShortcuts.Arg <BindingContext>(CompilationContext.BindingContext); var pathInfo = pex.PathInfo; return(ExpressionShortcuts.Call(() => PathResolver.ResolvePath(context, ref pathInfo))); }
protected override Expression VisitIteratorExpression(IteratorExpression iex) { var context = ExpressionShortcuts.Arg <BindingContext>(CompilationContext.BindingContext); var sequence = ExpressionShortcuts.Var <object>("sequence"); var template = FunctionBuilder.CompileCore(new[] { iex.Template }, CompilationContext.Configuration); var ifEmpty = FunctionBuilder.CompileCore(new[] { iex.IfEmpty }, CompilationContext.Configuration); var compiledSequence = ExpressionShortcuts.Arg <object>(FunctionBuilder.Reduce(iex.Sequence, CompilationContext)); var blockParams = ExpressionShortcuts.Arg <BlockParam>(iex.BlockParams); var blockParamsProvider = ExpressionShortcuts.Call(() => BlockParamsValueProvider.Create(context, blockParams)); var blockParamsProviderVar = ExpressionShortcuts.Var <BlockParamsValueProvider>(); return(ExpressionShortcuts.Block() .Parameter(sequence, compiledSequence) .Parameter(blockParamsProviderVar, blockParamsProvider) .Line(blockParamsProviderVar.Using((self, builder) => { builder .Line(context.Call(o => o.RegisterValueProvider((IValueProvider)self))) .Line(ExpressionShortcuts.Try() .Body(ExpressionShortcuts.Call(() => Iterator.Iterate(context, self, sequence, template, ifEmpty) )) .Finally(context.Call(o => o.UnregisterValueProvider((IValueProvider)self))) ); }))); }
public void ClosureInCallTest() { var blockBuilder = ExpressionShortcuts.Block() .Line(ExpressionShortcuts.Call(() => _mock.MethodWithReturn())); Expression.Lambda <Func <string> >(blockBuilder).Compile().Invoke(); _mock.Received(1).MethodWithReturn(); }
protected override Expression VisitBoolishExpression(BoolishExpression bex) { var condition = Visit(bex.Condition); condition = FunctionBuilder.Reduce(condition, _compilationContext); var @object = ExpressionShortcuts.Arg <object>(condition); return(ExpressionShortcuts.Call(() => HandlebarsUtils.IsTruthyOrNonEmpty(@object))); }
public void MultipleCallsChainedTest() { _mock.MethodWithReturn().Returns(_faker.Random.String()); var blockBuilder = ExpressionShortcuts.Block() .Line(ExpressionShortcuts.Call(() => _mock.MethodWithReturn().ToUpperInvariant())); Expression.Lambda <Func <string> >(blockBuilder).Compile().Invoke(); _mock.Received(1).MethodWithReturn(); }
public void NestedCallsTest() { var expected = _faker.Random.String(); _mock.MethodWithReturn().Returns(expected); var blockBuilder = ExpressionShortcuts.Block() .Line(ExpressionShortcuts.Call(() => _mock.VoidMethodWithParameter(ExpressionShortcuts.Call(() => _mock.MethodWithReturn())) ) ); Expression.Lambda <Action>(blockBuilder).Compile().Invoke(); Received.InOrder(() => { _mock.MethodWithReturn(); _mock.VoidMethodWithParameter(expected); }); }
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)); }
protected override Expression VisitPartialExpression(PartialExpression pex) { var bindingContext = ExpressionShortcuts.Arg <BindingContext>(CompilationContext.BindingContext); var partialBlockTemplate = pex.Fallback != null ? FunctionBuilder.CompileCore(new[] { pex.Fallback }, CompilationContext.Configuration) : null; if (pex.Argument != null || partialBlockTemplate != null) { var value = ExpressionShortcuts.Arg <object>(FunctionBuilder.Reduce(pex.Argument, CompilationContext)); var partialTemplate = ExpressionShortcuts.Arg(partialBlockTemplate); bindingContext = bindingContext.Call(o => o.CreateChildContext(value, partialTemplate)); } var partialName = ExpressionShortcuts.Cast <string>(pex.PartialName); var configuration = ExpressionShortcuts.Arg(CompilationContext.Configuration); return(ExpressionShortcuts.Call(() => InvokePartialWithFallback(partialName, bindingContext, (ICompiledHandlebarsConfiguration)configuration) )); }
protected override Expression VisitHelperExpression(HelperExpression hex) { var helperName = hex.HelperName; var bindingContext = ExpressionShortcuts.Arg <BindingContext>(CompilationContext.BindingContext); var textWriter = bindingContext.Property(o => o.TextWriter); var arguments = hex.Arguments.Select(o => FunctionBuilder.Reduce(o, CompilationContext)); var args = ExpressionShortcuts.Array <object>(arguments); var configuration = CompilationContext.Configuration; if (configuration.Helpers.TryGetValue(helperName, out var helper)) { return(ExpressionShortcuts.Call(() => helper(textWriter, bindingContext, args))); } if (configuration.ReturnHelpers.TryGetValue(helperName, out var returnHelper)) { return(ExpressionShortcuts.Call(() => CaptureResult(textWriter, ExpressionShortcuts.Call(() => returnHelper(bindingContext, args))) )); } var pureHelperName = helperName.Substring(1); foreach (var resolver in configuration.HelperResolvers) { if (resolver.TryResolveReturnHelper(pureHelperName, typeof(object), out var resolvedHelper)) { return(ExpressionShortcuts.Call(() => CaptureResult(textWriter, ExpressionShortcuts.Call(() => resolvedHelper(bindingContext, args))) )); } } return(ExpressionShortcuts.Call(() => CaptureResult(textWriter, ExpressionShortcuts.Call(() => LateBindHelperExpression(bindingContext, helperName, args) )) )); }
public void FuncCallTest() { Func <IMock, string> func = m => m.MethodWithReturn(); var expected = _faker.Random.String(); _mock.MethodWithReturn().Returns(expected); var mock = ExpressionShortcuts.Arg(_mock); var data = ExpressionShortcuts.Var <IMock>(); var action = ExpressionShortcuts.Block() .Parameter(data, mock) .Line(ExpressionShortcuts.Call(() => func((IMock)data))) .Lambda <Func <string> >() .Compile(); _mock.DidNotReceive().MethodWithReturn(); var actual = action(); Assert.Equal(expected, actual); _mock.Received(1).MethodWithReturn(); }
protected override Expression VisitBlockHelperExpression(BlockHelperExpression bhex) { var isInlinePartial = bhex.HelperName == "#*inline"; var context = ExpressionShortcuts.Arg <BindingContext>(CompilationContext.BindingContext); var bindingContext = isInlinePartial ? context.Cast <object>() : context.Property(o => o.Value); var readerContext = ExpressionShortcuts.Arg(bhex.Context); var body = FunctionBuilder.CompileCore(((BlockExpression)bhex.Body).Expressions, CompilationContext.Configuration); var inverse = FunctionBuilder.CompileCore(((BlockExpression)bhex.Inversion).Expressions, CompilationContext.Configuration); var helperName = bhex.HelperName.TrimStart('#', '^'); var textWriter = context.Property(o => o.TextWriter); var arguments = ExpressionShortcuts.Array <object>(bhex.Arguments.Select(o => FunctionBuilder.Reduce(o, CompilationContext))); var configuration = ExpressionShortcuts.Arg(CompilationContext.Configuration); var reducerNew = ExpressionShortcuts.New(() => new LambdaReducer(context, body, inverse)); var reducer = ExpressionShortcuts.Var <LambdaReducer>(); var blockParamsProvider = ExpressionShortcuts.Var <BlockParamsValueProvider>(); var blockParamsExpression = ExpressionShortcuts.Call( () => BlockParamsValueProvider.Create(context, ExpressionShortcuts.Arg <BlockParam>(bhex.BlockParams)) ); var helperOptions = ExpressionShortcuts.New( () => new HelperOptions( reducer.Property(o => o.Direct), reducer.Property(o => o.Inverse), blockParamsProvider, configuration) ); var blockHelpers = CompilationContext.Configuration.BlockHelpers; if (blockHelpers.TryGetValue(helperName, out var helper)) { return(ExpressionShortcuts.Block() .Parameter(reducer, reducerNew) .Parameter(blockParamsProvider, blockParamsExpression) .Line(blockParamsProvider.Using((self, builder) => { builder .Line(context.Call(o => o.RegisterValueProvider((IValueProvider)self))) .Line(ExpressionShortcuts.Try() .Body(ExpressionShortcuts.Call( () => helper(textWriter, helperOptions, bindingContext, arguments) )) .Finally(context.Call(o => o.UnregisterValueProvider((IValueProvider)self))) ); }))); } foreach (var resolver in CompilationContext.Configuration.HelperResolvers) { if (resolver.TryResolveBlockHelper(helperName, out helper)) { return(ExpressionShortcuts.Block() .Parameter(reducer, reducerNew) .Parameter(blockParamsProvider, blockParamsExpression) .Line(blockParamsProvider.Using((self, builder) => { builder .Line(context.Call(o => o.RegisterValueProvider((IValueProvider)self))) .Line(ExpressionShortcuts.Try() .Body(ExpressionShortcuts.Call( () => helper(textWriter, helperOptions, bindingContext, arguments) )) .Finally(context.Call(o => o.UnregisterValueProvider((IValueProvider)self))) ); }))); } } var helperPrefix = bhex.HelperName[0]; return(ExpressionShortcuts.Block() .Parameter(reducer, reducerNew) .Parameter(blockParamsProvider, blockParamsExpression) .Line(blockParamsProvider.Using((self, builder) => { builder .Line(context.Call(o => o.RegisterValueProvider((IValueProvider)self))) .Line(ExpressionShortcuts.Try() .Body(ExpressionShortcuts.Call( () => LateBoundCall( helperName, helperPrefix, context, (IReaderContext)readerContext, textWriter, helperOptions, body, inverse, bindingContext, self, arguments ) )) .Finally(context.Call(o => o.UnregisterValueProvider((IValueProvider)self))) ); }))); }