コード例 #1
0
 internal SearchExpressionContext(SearchExpressionRuntime runtime, SearchExpression expression, SearchExpression[] args, SearchExpressionExecutionFlags flags)
 {
     this.runtime    = runtime;
     this.expression = expression;
     this.flags      = flags;
     this.args       = args;
 }
コード例 #2
0
        public SearchExpressionRuntime(SearchContext searchContext, SearchExpressionExecutionFlags flags)
        {
            search = searchContext;
            frames = new Stack <SearchExpressionContext>();
            state  = new ExecutionState();
            items  = new Stack <SearchItem>();

            frames.Push(new SearchExpressionContext(this, null, null, SearchExpressionExecutionFlags.Root | flags));
        }
コード例 #3
0
        internal IEnumerable <SearchItem> Execute(SearchContext searchContext, SearchExpressionExecutionFlags executionFlags)
        {
            var runtime = new SearchExpressionRuntime(searchContext, executionFlags);

            if (executionFlags.HasFlag(SearchExpressionExecutionFlags.ThreadedEvaluation))
            {
                return(TaskEvaluatorManager.Evaluate(runtime.current, this));
            }
            return(Execute(runtime.current, executionFlags));
        }
コード例 #4
0
        internal IEnumerable <SearchItem> Execute(SearchExpressionContext c, SearchExpressionExecutionFlags executionFlags)
        {
            if (!evaluator.valid || evaluator.execute == null)
            {
                c.ThrowError("Invalid expression evaluator");
            }
            try
            {
                if (!evaluator.hints.HasFlag(SearchExpressionEvaluationHints.ThreadNotSupported))
                {
                    return(Evaluate(c, executionFlags));
                }

                // We cannot only return the IEnumerable of the evaluator, as the iteration itself needs to be
                // done on the main thread. If we return the IEnumerable itself, we will unroll the items and call the evaluator
                // in the evaluation thread.
                return(TaskEvaluatorManager.EvaluateMainThreadUnroll(() => Evaluate(c, executionFlags)));
            }
            catch (SearchExpressionEvaluatorException ex)
            {
                ExceptionDispatchInfo.Capture(ex).Throw();
                return(null); // To stop visual studio complaining about not all code path return a value
            }
        }
コード例 #5
0
 public bool HasFlag(SearchExpressionExecutionFlags checkFlag)
 {
     return(flags.HasFlag(checkFlag));
 }
コード例 #6
0
 public IDisposable Push(SearchExpression searchExpression, IEnumerable <SearchExpression> args, SearchExpressionExecutionFlags flags)
 {
     flags |= frames.Peek().flags & SearchExpressionExecutionFlags.TransferedFlags;
     frames.Push(new SearchExpressionContext(this, searchExpression, args.ToArray(), flags));
     return(new PushPopScope <SearchExpressionContext>(frames));
 }
コード例 #7
0
        private IEnumerable <SearchItem> Evaluate(SearchExpressionContext c, SearchExpressionExecutionFlags flags)
        {
            var args = new List <SearchExpression>();

            foreach (var p in parameters)
            {
                var evalHints = p.evaluator.hints;
                if (evalHints.HasFlag(SearchExpressionEvaluationHints.AlwaysExpand) ||
                    (p.types.HasFlag(SearchExpressionType.Expandable) && evalHints.HasFlag(SearchExpressionEvaluationHints.ExpandSupported)))
                {
                    foreach (var exprItem in p.Execute(c, SearchExpressionExecutionFlags.Expand))
                    {
                        if (exprItem != null)
                        {
                            if (exprItem.data is SearchExpression expr)
                            {
                                args.Add(expr);
                            }
                            else
                            {
                                c.ThrowError($"cannot expand {p}");
                            }
                        }
                        else
                        {
                            yield return(null);
                        }
                    }
                }
                else if (p.types.HasFlag(SearchExpressionType.Expandable))
                {
                    foreach (var exprItem in p.Execute(c))
                    {
                        if (exprItem == null)
                        {
                            yield return(null);

                            continue;
                        }

                        if (exprItem.value != null)
                        {
                            if (Utils.TryGetNumber(exprItem.value, out var d))
                            {
                                args.Add(new SearchExpression(SearchExpressionType.Number, d.ToString().GetStringView(), Parsers.ConstantEvaluator));
                            }
                            else if (exprItem.value is string s)
                            {
                                args.Add(new SearchExpression(SearchExpressionType.Text, s.GetStringView(), Parsers.ConstantEvaluator));
                            }
                            else
                            {
                                c.ThrowError("Cannot expand parameters");
                            }
                        }
                        else
                        {
                            c.ThrowError("Cannot expand null value");
                        }
                    }
                }
                else
                {
                    args.Add(p);
                }
            }

            using (c.runtime.Push(this, args, flags))
            {
                var skipNull       = c.HasFlag(SearchExpressionExecutionFlags.ThreadedEvaluation) && !c.HasFlag(SearchExpressionExecutionFlags.PassNull);
                var executeContext = c.runtime.current;
                var timeoutWatch   = new System.Diagnostics.Stopwatch();
                timeoutWatch.Start();
                foreach (var r in evaluator.execute(executeContext))
                {
                    if (r != null)
                    {
                        timeoutWatch.Restart();
                        yield return(r);
                    }
                    else if (!skipNull)
                    {
                        if (timeoutWatch.Elapsed.TotalSeconds > 3.0d)
                        {
                            c.ThrowError("Timeout");
                        }
                        yield return(null);
                    }
                }
            }
        }