예제 #1
0
        public static SourceObject ResolvePartialExpression(PartialExpression pe)
        {
            if (pe == null)
            {
                return(null);
            }

            switch (pe.ExpressionType)
            {
            case PartialExpressionType.Namespace:
                return(((PartialNamespace)pe).Namespace);

            case PartialExpressionType.Type:
                return(((PartialType)pe).Type);

            case PartialExpressionType.Block:
                return(((PartialBlock)pe).Block);

            case PartialExpressionType.Value:
                return(((PartialValue)pe).Value);

            case PartialExpressionType.Variable:
                return(((PartialVariable)pe).Variable);

            case PartialExpressionType.Parameter:
            {
                var pp = (pe as PartialParameter);
                return(pp.Function.Match(f => f.Parameters, l => l.Parameters)[pp.Index]);
            }

            case PartialExpressionType.Field:
                return(((PartialField)pe).Field);

            case PartialExpressionType.Property:
                return(((PartialProperty)pe).Property);

            case PartialExpressionType.Event:
                return(((PartialEvent)pe).Event);

            case PartialExpressionType.Indexer:
                return(((PartialIndexer)pe).Indexer);

            case PartialExpressionType.ArrayElement:
                return(((PartialArrayElement)pe).Object);

            case PartialExpressionType.MethodGroup:
                // TODO: resolve overload based on argument list (if available) to resolve correct method;
                return(((PartialMethodGroup)pe).Methods[0]);

            default:
                return(null);
            }
        }
예제 #2
0
        protected override System.Linq.Expressions.Expression VisitPartialExpression(PartialExpression pex)
        {
            System.Linq.Expressions.Expression bindingContext = CompilationContext.BindingContext;
            if (pex.Argument != null)
            {
                bindingContext = System.Linq.Expressions.Expression.Call(
                    bindingContext,
                    typeof(BindingContext).GetMethod("CreateChildContext"),
                    pex.Argument);
            }

            var fb = new FunctionBuilder(CompilationContext.Configuration);
            var partialBlockTemplate =
                fb.Compile(pex.Fallback != null ? new[] { pex.Fallback } : Enumerable.Empty <System.Linq.Expressions.Expression>(), bindingContext);

            var partialInvocation = System.Linq.Expressions.Expression.Call(
#if netstandard
                new Func <string, BindingContext, HandlebarsConfiguration, Action <TextWriter, object>, bool>(InvokePartial).GetMethodInfo(),
#else
                new Func <string, BindingContext, HandlebarsConfiguration, Action <TextWriter, object>, bool>(InvokePartial).Method,
#endif
                System.Linq.Expressions.Expression.Convert(pex.PartialName, typeof(string)),
                bindingContext,
                System.Linq.Expressions.Expression.Constant(CompilationContext.Configuration),
                partialBlockTemplate);

            var fallback = pex.Fallback;

            if (fallback == null)
            {
                fallback = System.Linq.Expressions.Expression.Call(
#if netstandard
                    new Action <string>(HandleFailedInvocation).GetMethodInfo(),
#else
                    new Action <string>(HandleFailedInvocation).Method,
#endif
                    System.Linq.Expressions.Expression.Convert(pex.PartialName, typeof(string)));
            }

            return(System.Linq.Expressions.Expression.IfThen(
                       System.Linq.Expressions.Expression.Not(partialInvocation),
                       fallback));
        }
예제 #3
0
        protected override Expression VisitPartialExpression(PartialExpression pex)
        {
            Expression bindingContext = CompilationContext.BindingContext;

            if (pex.Argument != null)
            {
                bindingContext = Expression.Call(
                    bindingContext,
                    typeof(BindingContext).GetMethod("CreateChildContext"),
                    pex.Argument);
            }

            var partialInvocation = Expression.Call(
#if netstandard
                new Func <string, BindingContext, IHandlebarsEngine, bool>(InvokePartial).GetMethodInfo(),
#else
                new Func <string, BindingContext, IHandlebarsEngine, bool>(InvokePartial).Method,
#endif
                Expression.Convert(pex.PartialName, typeof(string)),
                bindingContext,
                Expression.Constant(CompilationContext.Engine));

            var fallback = pex.Fallback;

            if (fallback == null)
            {
                fallback = Expression.Call(
#if netstandard
                    new Action <string>(HandleFailedInvocation).GetMethodInfo(),
#else
                    new Action <string>(HandleFailedInvocation).Method,
#endif
                    Expression.Convert(pex.PartialName, typeof(string)));
            }

            return(Expression.IfThen(
                       Expression.Not(partialInvocation),
                       fallback));
        }
예제 #4
0
 protected virtual Expression VisitPartialExpression(PartialExpression pex)
 {
     return(pex);
 }
예제 #5
0
 public PartialBlockAccumulatorContext(Expression startingNode)
 {
     _startingNode = ConvertToPartialExpression(UnwrapStatement(startingNode));
 }
예제 #6
0
        public Expression CompilePartial(PartialExpression pe)
        {
            switch (pe.ExpressionType)
            {
            case PartialExpressionType.This:
                return(CompileThis(pe.Source));

            case PartialExpressionType.Value:
            {
                var p = pe as PartialValue;
                return(p.Value);
            }

            case PartialExpressionType.ArrayElement:
            {
                var p = pe as PartialArrayElement;
                return(new LoadElement(p.Source, p.Object, p.Index));
            }

            case PartialExpressionType.Variable:
            {
                var p = pe as PartialVariable;

                if (p.Variable.ValueType is FixedArrayType)
                {
                    return(new AddressOf(new LoadLocal(p.Source, p.Variable)));
                }

                return(new LoadLocal(p.Source, p.Variable));
            }

            case PartialExpressionType.Parameter:
            {
                var p = pe as PartialParameter;

                if (p.Parameter.Type is FixedArrayType)
                {
                    return(new AddressOf(new LoadArgument(p.Source, p.Function, p.Index), p.Parameter.Modifier == ParameterModifier.Const ? AddressType.Const : 0));
                }

                return(new LoadArgument(p.Source, p.Function, p.Index));
            }

            case PartialExpressionType.Field:
            {
                var p = pe as PartialField;

                if (p.Field.ReturnType is FixedArrayType)
                {
                    return(new AddressOf(new LoadField(p.Source, p.Object, p.Field)));
                }

                return(new LoadField(p.Source, p.Object, p.Field));
            }

            case PartialExpressionType.Event:
            {
                var e = pe as PartialEvent;

                if (e.Event.ImplicitField == null)
                {
                    return(Error(e.Source, ErrorCode.E2056, "The event " + e.Event.Quote() + " has no implicit field and can only be used before '+=' or '-='"));
                }

                return(new LoadField(e.Source, e.Object, e.Event.ImplicitField));
            }

            case PartialExpressionType.Property:
            {
                var p = pe as PartialProperty;

                if (p.Property.GetMethod == null)
                {
                    return(Error(p.Source, ErrorCode.E2057, "The property " + p.Property.Quote() + " has no getter accessor"));
                }

                var obj = p.Object;
                if (obj != null)
                {
                    Transforms.TryCreateReadonlyValueFieldIndirection(Namescope, ref obj);
                }

                return(new GetProperty(p.Source, obj, p.Property));
            }

            case PartialExpressionType.Indexer:
            {
                var p = pe as PartialIndexer;

                if (p.Indexer.GetMethod == null)
                {
                    return(Error(p.Source, ErrorCode.E2058, "The indexer " + p.Indexer.Quote() + " has no getter accessor"));
                }

                var obj = p.Object;

                if (obj != null)
                {
                    Transforms.TryCreateReadonlyValueFieldIndirection(Namescope, ref obj);
                }

                return(new GetProperty(p.Source, obj, p.Indexer, p.Arguments));
            }

            case PartialExpressionType.MethodGroup:
            {
                var p   = pe as PartialMethodGroup;
                var obj = p.Object;

                if (obj != null)
                {
                    Transforms.TryCreateReadonlyValueFieldIndirection(Namescope, ref obj);
                }

                return(new MethodGroup(p.Source, obj, p.IsQualified, p.Methods));
            }

            case PartialExpressionType.ExtensionGroup:
            {
                var p = pe as PartialExtensionGroup;
                return(new ExtensionGroup(p.Source, p.Object, p.Methods));
            }

            case PartialExpressionType.Namespace:
            {
                var p = pe as PartialNamespace;
                return(Error(pe.Source, ErrorCode.E2059, "The namespace " + p.Namespace.Quote() + " is not a value"));
            }

            case PartialExpressionType.Block:
            {
                var p = pe as PartialBlock;
                return(Error(p.Source, ErrorCode.E2060, "The block " + p.Block.Quote() + " is not a value"));
            }

            case PartialExpressionType.Type:
            {
                var p = pe as PartialType;
                return(Error(p.Source, ErrorCode.E2061, "The type " + p.Type.Quote() + " is not a value"));
            }

            default:
            {
                return(Error(pe.Source, ErrorCode.E2062, "<" + pe.ExpressionType + ">  is not a value"));
            }
            }
        }
예제 #7
0
 protected virtual System.Linq.Expressions.Expression VisitPartialExpression(PartialExpression pex)
 {
     return(pex);
 }