コード例 #1
0
 public bool any(ScriptScopeContext scope, object target) => target.AssertEnumerable(nameof(any)).Any();
コード例 #2
0
 public bool all(ScriptScopeContext scope, object target, object expression) => all(scope, target, expression, null);
コード例 #3
0
        public override Task WriteAsync(ScriptScopeContext scope, PageBlockFragment block, CancellationToken token)
        {
            var invokerCtx = (Tuple <string, StaticMethodInvoker>)scope.Context.CacheMemory.GetOrAdd(block.Argument, key => {
                var literal = block.Argument.Span.ParseVarName(out var name);
                var strName = name.ToString();
                literal     = literal.AdvancePastWhitespace();

                literal  = literal.AdvancePastWhitespace();
                var args = TypeConstants.EmptyStringList;
                if (!literal.IsEmpty)
                {
                    literal = literal.ParseArgumentsList(out var argIdentifiers);
                    args    = argIdentifiers.Map(x => x.Name);
                }

                var strFragment = (PageStringFragment)block.Body[0];

                var script       = ScriptPreprocessors.TransformStatementBody(strFragment.ValueString);
                var parsedScript = scope.Context.OneTimePage(script);

                StaticMethodInvoker invoker = null;

                // Allow recursion by initializing lazy Delegate
                object LazyInvoker(object instance, object[] paramValues)
                {
                    if (invoker == null)
                    {
                        throw new NotSupportedException($"Uninitialized function '{strName}'");
                    }

                    return(invoker(instance, paramValues));
                }

                invoker = (paramValues) => {
                    scope.PageResult.StackDepth++;
                    try
                    {
                        var pageResult = new PageResult(parsedScript)
                        {
                            Args =
                            {
                                [strName] = (MethodInvoker)LazyInvoker
                            },
                            StackDepth = scope.PageResult.StackDepth
                        };

                        var len = Math.Min(paramValues.Length, args.Count);
                        for (int i = 0; i < len; i++)
                        {
                            var paramValue           = paramValues[i];
                            pageResult.Args[args[i]] = paramValue;
                        }

                        var discard = ScriptContextUtils.GetPageResultOutput(pageResult);
                        if (pageResult.ReturnValue == null)
                        {
                            throw new NotSupportedException(ScriptContextUtils.ErrorNoReturn);
                        }

                        return(pageResult.ReturnValue.Result);
                    }
                    finally
                    {
                        scope.PageResult.StackDepth--;
                    }
                };

                return(Tuple.Create(strName, invoker));
            });

            scope.PageResult.Args[invokerCtx.Item1] = invokerCtx.Item2;

            return(TypeConstants.EmptyTask);
        }
コード例 #4
0
 public object sum(ScriptScopeContext scope, object target, object expression, object scopeOptions) =>
 applyInternal(nameof(sum), scope, target, expression, scopeOptions, (a, b) => a + b);
コード例 #5
0
 public IEnumerable <object> thenByDescending(ScriptScopeContext scope, object target, object expression, object scopeOptions) =>
 thenByInternal(nameof(thenByDescending), scope, target, expression, scopeOptions);
コード例 #6
0
 public int count(ScriptScopeContext scope, object target) => target.AssertEnumerable(nameof(count)).Count();
コード例 #7
0
 public double average(ScriptScopeContext scope, object target, object expression, object scopeOptions) =>
 applyInternal(nameof(average), scope, target, expression, scopeOptions, (a, b) => a + b).ConvertTo <double>() / target.AssertEnumerable(nameof(average)).Count();
コード例 #8
0
 public IEnumerable <object> orderByDesc(ScriptScopeContext scope, object target, object expression) => orderByDesc(scope, target, expression, null);
コード例 #9
0
 public double average(ScriptScopeContext scope, object target) => average(scope, target, null, null);
コード例 #10
0
 public double average(ScriptScopeContext scope, object target, object expression) => average(scope, target, expression, null);
コード例 #11
0
 public object max(ScriptScopeContext scope, object target, object expression, object scopeOptions) =>
 applyInternal(nameof(max), scope, target, expression, scopeOptions, (a, b) => b > a ? b : a);
コード例 #12
0
 public object max(ScriptScopeContext scope, object target, object expression) => max(scope, target, expression, null);
コード例 #13
0
 public object max(ScriptScopeContext scope, object target) => max(scope, target, null, null);
コード例 #14
0
 public IEnumerable <object> skipWhile(ScriptScopeContext scope, object target, object expression) => skipWhile(scope, target, expression, null);
コード例 #15
0
        private object applyInternal(string filterName, ScriptScopeContext 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));
        }
コード例 #16
0
 public IEnumerable <object> orderBy(ScriptScopeContext scope, object target, object expression, object scopeOptions) =>
 orderByInternal(nameof(orderBy), scope, target, expression, scopeOptions);
コード例 #17
0
 public object reduce(ScriptScopeContext scope, object target, object expression) => reduce(scope, target, expression, null);
コード例 #18
0
 public IEnumerable <object> thenByDescending(ScriptScopeContext scope, object target, object expression) => thenByDescending(scope, target, expression, null);
コード例 #19
0
        public object let(ScriptScopeContext scope, object target, object scopeBindings) //from filter
        {
            if (target is IEnumerable objs)
            {
                string itemBinding;
                Dictionary <string, object> scopedParams = null;

                var arrowExpr = scopeBindings as JsArrowFunctionExpression;
                if (arrowExpr != null)
                {
                    itemBinding = arrowExpr.Params[0].Name;
                }
                else
                {
                    scopedParams = scope.GetParamsWithItemBindingOnly(nameof(@let), null, scopeBindings, out itemBinding);
                }

                var to = new List <ScopeVars>();
                var i  = 0;
                foreach (var item in objs)
                {
                    scope.ScopedParams[ScriptConstants.Index] = i++;
                    scope.ScopedParams[itemBinding]           = item;

                    // Copy over previous let bindings into new let bindings
                    var itemBindings = new ScopeVars();
                    if (item is object[] tuple)
                    {
                        foreach (var a in tuple)
                        {
                            if (a is IDictionary <string, object> aArgs)
                            {
                                foreach (var entry in aArgs)
                                {
                                    itemBindings[entry.Key] = entry.Value;
                                }
                            }
                        }
                    }

                    if (arrowExpr != null)
                    {
                        var value = arrowExpr.Body.Evaluate(scope);
                        if (value is Dictionary <string, object> bindingVars)
                        {
                            foreach (var bindingVar in bindingVars)
                            {
                                itemBindings[bindingVar.Key] = bindingVar.Value;
                            }
                        }
                    }
                    else
                    {
                        foreach (var entry in scopedParams)
                        {
                            var bindTo = entry.Key;
                            if (!(entry.Value is string bindToLiteral))
                            {
                                throw new NotSupportedException($"'{nameof(let)}' in '{scope.Page.VirtualPath}' expects a string Expression for its value but received '{entry.Value}' instead");
                            }

                            bindToLiteral.ParseJsExpression(out JsToken token);

                            try
                            {
                                var bindValue = token.Evaluate(scope);
                                scope.ScopedParams[bindTo] = bindValue;
                                itemBindings[bindTo]       = bindValue;
                            }
                            catch (Exception exception)
                            {
                                Console.WriteLine(exception);
                            }
                        }
                    }

                    to.Add(itemBindings);
                }

                return(to);
            }
            if (target != null)
            {
                throw new NotSupportedException($"'{nameof(let)}' in '{scope.Page.VirtualPath}' requires an IEnumerable but received a '{target.GetType()?.Name}' instead");
            }

            return(null);
        }
コード例 #20
0
 public IEnumerable <object> skip(ScriptScopeContext scope, IEnumerable <object> original, object countOrBinding) =>
 original.Skip(scope.GetValueOrEvaluateBinding <int>(countOrBinding));
コード例 #21
0
 public object first(ScriptScopeContext scope, object target, object expression) => first(scope, target, expression, null);
コード例 #22
0
 public int count(ScriptScopeContext scope, object target, object expression) => count(scope, target, expression, null);
コード例 #23
0
 public object last(ScriptScopeContext scope, object target) => target.AssertEnumerable(nameof(last)).LastOrDefault();
コード例 #24
0
ファイル: NoopScriptBlock.cs プロジェクト: yerz/ServiceStack
 public override Task WriteAsync(ScriptScopeContext scope, PageBlockFragment block, CancellationToken token) =>
 TypeConstants.EmptyTask;
コード例 #25
0
 public object sum(ScriptScopeContext scope, object target) => sum(scope, target, null, null);