Esempio n. 1
0
        public object reduce(TemplateScopeContext scope, object target, object expression, object scopeOptions)
        {
            var  items    = target.AssertEnumerable(nameof(reduce));
            Type itemType = null;

            if (!(expression is JsArrowFunctionExpression arrowExpr))
            {
                throw new NotSupportedException($"{nameof(reduce)} expects an arrow expression but was instead '{expression.GetType().Name}'");
            }

            if (arrowExpr.Params.Length != 2)
            {
                throw new NotSupportedException($"{nameof(reduce)} expects 2 params but was instead {arrowExpr.Params.Length}");
            }

            var accumulatorBinding = arrowExpr.Params[0].Name;
            var itemBinding        = arrowExpr.Params[1].Name;
            var expr = arrowExpr.Body;

            var scopedParams = scopeOptions as Dictionary <string, object> ?? new Dictionary <string, object>();

            var accumulator = scopedParams.TryGetValue("initialValue", out object initialValue)
                ? initialValue.ConvertTo <double>()
                : 1;

            var i = 0;

            foreach (var item in items)
            {
                if (item == null)
                {
                    continue;
                }

                scope.AddItemToScope(accumulatorBinding, accumulator);
                scope.AddItemToScope("index", i++);
                scope.AddItemToScope(itemBinding, item);

                var result = expr.Evaluate(scope);
                if (result == null)
                {
                    continue;
                }
                if (itemType == null)
                {
                    itemType = result.GetType();
                }

                accumulator = result.ConvertTo <double>();
            }

            return(itemType == null || itemType == typeof(double)
                ? accumulator
                : accumulator.ConvertTo(itemType));
        }
Esempio n. 2
0
        public object reduce(TemplateScopeContext scope, object target, object expression, object scopeOptions)
        {
            var  items    = target.AssertEnumerable(nameof(reduce));
            Type itemType = null;

            var literal      = scope.AssertExpression(nameof(reduce), expression);
            var scopedParams = scope.GetParamsWithItemBinding(nameof(reduce), scopeOptions, out string itemBinding);
            var accumulator  = scopedParams.TryGetValue("initialValue", out object initialValue)
                ? initialValue.ConvertTo <double>()
                : 1;

            var bindAccumlator = scopedParams.TryGetValue("accumulator", out object accumulatorName)
                ? (string)accumulatorName
                : "accumulator";

            literal.ToStringSegment().ParseNextToken(out object value, out JsBinding binding);
            var i = 0;

            foreach (var item in items)
            {
                if (item == null)
                {
                    continue;
                }

                scope.AddItemToScope(bindAccumlator, accumulator);
                scope.AddItemToScope("index", i++);
                scope.AddItemToScope(itemBinding, item);

                var result = scope.Evaluate(value, binding);
                if (result == null)
                {
                    continue;
                }
                if (itemType == null)
                {
                    itemType = result.GetType();
                }

                accumulator = result.ConvertTo <double>();
            }

            if (expression == null && itemType == null)
            {
                itemType = target.GetType().FirstGenericType()?.GetGenericArguments().FirstOrDefault();
            }

            return(itemType == null || itemType == typeof(double)
                ? accumulator
                : accumulator.ConvertTo(itemType));
        }
Esempio n. 3
0
        public IEnumerable <object> skipWhile(TemplateScopeContext scope, object target, object expression, object scopeOptions)
        {
            var items = target.AssertEnumerable(nameof(skipWhile));
            var expr  = scope.AssertExpression(nameof(skipWhile), expression, scopeOptions, out var itemBinding);

            var to           = new List <object>();
            var i            = 0;
            var keepSkipping = true;

            foreach (var item in items)
            {
                scope.AddItemToScope(itemBinding, item, i++);
                var result = expr.EvaluateToBool(scope);
                if (!result)
                {
                    keepSkipping = false;
                }

                if (!keepSkipping)
                {
                    to.Add(item);
                }
            }

            return(to);
        }
Esempio n. 4
0
        public IEnumerable <object> skipWhile(TemplateScopeContext scope, object target, object expression, object scopeOptions)
        {
            var items        = target.AssertEnumerable(nameof(skipWhile));
            var literal      = scope.AssertExpression(nameof(skipWhile), expression);
            var scopedParams = scope.GetParamsWithItemBinding(nameof(skipWhile), scopeOptions, out string itemBinding);

            var to = new List <object>();

            literal.ParseConditionExpression(out ConditionExpression expr);
            var i            = 0;
            var keepSkipping = true;

            foreach (var item in items)
            {
                scope.AddItemToScope(itemBinding, item, i++);
                var result = expr.Evaluate(scope);
                if (!result)
                {
                    keepSkipping = false;
                }

                if (!keepSkipping)
                {
                    to.Add(item);
                }
            }

            return(to);
        }
Esempio n. 5
0
        public IEnumerable <object> takeWhile(
            TemplateScopeContext scope,
            object target,
            object expression,
            object scopeOptions)
        {
            var items        = target.AssertEnumerable(nameof(takeWhile));
            var literal      = scope.AssertExpression(nameof(takeWhile), expression);
            var scopedParams = scope.GetParamsWithItemBinding(nameof(takeWhile), scopeOptions, out var itemBinding);

            var to = new List <object>();

            literal.ParseConditionExpression(out var expr);
            var i = 0;

            foreach (var item in items)
            {
                scope.AddItemToScope(itemBinding, item, i++);
                var result = expr.Evaluate(scope);
                if (result)
                {
                    to.Add(item);
                }
                else
                {
                    return(to);
                }
            }

            return(to);
        }
Esempio n. 6
0
        public List <object[]> zip(TemplateScopeContext scope, IEnumerable original, object itemsOrBinding)
        {
            var    to        = new List <object[]>();
            string literal   = itemsOrBinding as string;
            var    arrowExpr = itemsOrBinding as JsArrowFunctionExpression;

            if (literal != null || arrowExpr != null)
            {
                var token = literal != null
                    ? literal.GetCachedJsExpression(scope)
                    : arrowExpr.Body;

                var binding = arrowExpr != null
                    ? arrowExpr.Params[0].Name
                    : "it";

                var i = 0;
                foreach (var a in original)
                {
                    scope.AddItemToScope(binding, a, i++);
                    var bindValue = token.Evaluate(scope);
                    if (bindValue is IEnumerable current)
                    {
                        foreach (var b in current)
                        {
                            to.Add(new[] { a, b });
                        }
                    }
                    else if (bindValue != null)
                    {
                        throw new ArgumentException($"{nameof(zip)} in '{scope.Page.VirtualPath}' requires '{literal}' to evaluate to an IEnumerable, but evaluated to a '{bindValue.GetType().Name}' instead");
                    }
                }
            }
            else if (itemsOrBinding is IEnumerable current)
            {
                var currentArray = current.Cast <object>().ToArray();
                foreach (var a in original)
                {
                    foreach (var b in currentArray)
                    {
                        to.Add(new[] { a, b });
                    }
                }
            }

            return(to);
        }
Esempio n. 7
0
        public bool all(TemplateScopeContext scope, object target, object expression, object scopeOptions)
        {
            var items = target.AssertEnumerable(nameof(all));
            var expr  = scope.AssertExpression(nameof(all), expression, scopeOptions, out var itemBinding);

            var i = 0;

            foreach (var item in items)
            {
                scope.AddItemToScope(itemBinding, item, i++);
                var result = expr.EvaluateToBool(scope);
                if (!result)
                {
                    return(false);
                }
            }

            return(true);
        }
Esempio n. 8
0
        public int count(TemplateScopeContext scope, object target, object expression, object scopeOptions)
        {
            var items = target.AssertEnumerable(nameof(count));
            var expr  = scope.AssertExpression(nameof(count), expression, scopeOptions, out var itemBinding);

            var total = 0;
            var i     = 0;

            foreach (var item in items)
            {
                scope.AddItemToScope(itemBinding, item, i++);
                var result = expr.EvaluateToBool(scope);
                if (result)
                {
                    total++;
                }
            }

            return(total);
        }
Esempio n. 9
0
        public List <object[]> zip(TemplateScopeContext scope, IEnumerable original, object itemsOrBinding)
        {
            var to = new List <object[]>();

            if (itemsOrBinding is string literal)
            {
                literal.ToStringSegment().ParseNextToken(out var value, out var binding);

                var i = 0;
                foreach (var a in original)
                {
                    scope.AddItemToScope("it", a, i++);
                    var bindValue = scope.Evaluate(value, binding);
                    if (bindValue is IEnumerable current)
                    {
                        foreach (var b in current)
                        {
                            to.Add(new[] { a, b });
                        }
                    }
                    else if (bindValue != null)
                    {
                        throw new ArgumentException(
                                  $"{nameof(zip)} in '{scope.Page.VirtualPath}' requires '{literal}' to evaluate to an IEnumerable, but evaluated to a '{bindValue.GetType().Name}' instead");
                    }
                }
            }
            else if (itemsOrBinding is IEnumerable current)
            {
                var currentArray = current.Cast <object>().ToArray();
                foreach (var a in original)
                {
                    foreach (var b in currentArray)
                    {
                        to.Add(new[] { a, b });
                    }
                }
            }

            return(to);
        }
Esempio n. 10
0
        public bool all(TemplateScopeContext scope, object target, object expression, object scopeOptions)
        {
            var items        = target.AssertEnumerable(nameof(all));
            var literal      = scope.AssertExpression(nameof(all), expression);
            var scopedParams = scope.GetParamsWithItemBinding(nameof(where), scopeOptions, out string itemBinding);

            literal.ParseConditionExpression(out ConditionExpression expr);
            var i = 0;

            foreach (var item in items)
            {
                scope.AddItemToScope(itemBinding, item, i++);
                var result = expr.Evaluate(scope);
                if (!result)
                {
                    return(false);
                }
            }

            return(true);
        }
Esempio n. 11
0
        public object first(TemplateScopeContext scope, object target, object expression, object scopeOptions)
        {
            var items        = target.AssertEnumerable(nameof(first));
            var literal      = scope.AssertExpression(nameof(first), expression);
            var scopedParams = scope.GetParamsWithItemBinding(nameof(first), scopeOptions, out var itemBinding);

            literal.ParseConditionExpression(out var expr);
            var i = 0;

            foreach (var item in items)
            {
                scope.AddItemToScope(itemBinding, item, i++);
                var result = expr.Evaluate(scope);
                if (result)
                {
                    return(item);
                }
            }

            return(null);
        }
Esempio n. 12
0
        public IEnumerable <object> where (TemplateScopeContext scope, object target, object expression, object scopeOptions)
        {
            var items        = target.AssertEnumerable(nameof(where));
            var literal      = scope.AssertExpression(nameof(where), expression);
            var scopedParams = scope.GetParamsWithItemBinding(nameof(where), scopeOptions, out string itemBinding);

            var to   = new List <object>();
            var expr = literal.GetCachedJsExpression(scope);
            var i    = 0;
            foreach (var item in items)
            {
                scope.AddItemToScope(itemBinding, item, i++);
                var result = expr.EvaluateToBool(scope);
                if (result)
                {
                    to.Add(item);
                }
            }

            return(to);
        }
Esempio n. 13
0
        public bool any(TemplateScopeContext scope, object target, object expression, object scopeOptions)
        {
            var items        = target.AssertEnumerable(nameof(any));
            var literal      = scope.AssertExpression(nameof(any), expression);
            var scopedParams = scope.GetParamsWithItemBinding(nameof(any), scopeOptions, out string itemBinding);

            var expr = literal.GetCachedJsExpression(scope);
            var i    = 0;

            foreach (var item in items)
            {
                scope.AddItemToScope(itemBinding, item, i++);
                var result = expr.EvaluateToBool(scope);
                if (result)
                {
                    return(true);
                }
            }

            return(false);
        }
Esempio n. 14
0
 public static TemplateScopeContext AddItemToScope(this TemplateScopeContext scope, string itemBinding, object item, int index)
 {
     scope.ScopedParams[TemplateConstants.Index] = index;
     return(scope.AddItemToScope(itemBinding, item));
 }
Esempio n. 15
0
        private object applyInternal(string filterName, TemplateScopeContext scope, object target, object expression, object scopeOptions,
                                     Func <double, double, double> fn)
        {
            if (target is double d)
            {
                return(fn(d, expression.ConvertTo <double>()));
            }
            if (target is int i)
            {
                return((int)fn(i, expression.ConvertTo <double>()));
            }
            if (target is long l)
            {
                return((long)fn(l, expression.ConvertTo <double>()));
            }

            var items = target.AssertEnumerable(filterName);
            var total = filterName == nameof(min)
                ? double.MaxValue
                : 0;
            Type itemType = null;

            if (expression != null)
            {
                var expr = scope.AssertExpression(filterName, expression, scopeOptions, out var itemBinding);

                foreach (var item in items)
                {
                    if (item == null)
                    {
                        continue;
                    }

                    scope.AddItemToScope(itemBinding, item);
                    var result = expr.Evaluate(scope);
                    if (result == null)
                    {
                        continue;
                    }
                    if (itemType == null)
                    {
                        itemType = result.GetType();
                    }

                    total = fn(total, result.ConvertTo <double>());
                }
            }
            else
            {
                foreach (var item in items)
                {
                    if (item == null)
                    {
                        continue;
                    }
                    if (itemType == null)
                    {
                        itemType = item.GetType();
                    }
                    total = fn(total, item.ConvertTo <double>());
                }
            }

            if (filterName == nameof(min) && itemType == null)
            {
                return(0);
            }

            if (expression == null && itemType == null)
            {
                itemType = target.GetType().FirstGenericType()?.GetGenericArguments().FirstOrDefault();
            }

            return(itemType == null || itemType == typeof(double)
                ? total
                : total.ConvertTo(itemType));
        }