Exemplo n.º 1
0
        public override void Visit(ChainExpr expr)
        {
            if (ReferencesRootVariableVisitor.ReferencesRootVariable(expr))
            {
                _needsAsync = true;
                return;
            }

            // Some things can't be simplified by themselves, but they can be in the
            // context of a chain. If this chain doesn't need to be asynchronous, then
            // the next key or index won't need it either.
            if (NeedsAsyncByItselfVisitor.NeedsAsyncByItself(expr.Next))
            {
                _needsAsync = true;
                return;
            }
        }
Exemplo n.º 2
0
        private Expr ParseChainRemainder(Expr prev)
        {
            var  token = GetToken();
            Expr first = null;

            if (token.Kind == ".")
            {
                Match(".");
                first = ParseKeyExpr(prev);
            }
            else if (token.Kind == "[?")
            {
                first = ParseFilterExpr(prev);
            }
            else if (token.Kind == "[")
            {
                first = ParseIndexExpr(prev);
            }
            else if (token.Kind == "(")
            {
                // Super gross; in retrospect, all expressions should just be self-contained, or this
                // should at least work the same as the other chain expressions.
                first = ParseIndexedLookup(prev);
            }
            else if (token.Kind == "{")
            {
                var map = ParseMapProjectionExpr(null);
                first = new ChainExpr(prev, map, ChainBehavior.ToMultipleIfArray);
            }

            var nextToken = GetToken();

            if (nextToken.Kind == "." || nextToken.Kind == "[" || nextToken.Kind == "(" || nextToken.Kind == "{" || nextToken.Kind == "[?")
            {
                return(ParseChainRemainder(first));
            }
            else
            {
                return(first);
            }
        }
Exemplo n.º 3
0
 public virtual void Visit(ChainExpr expr)
 {
 }
Exemplo n.º 4
0
        private Expr ParseMapProjectionExpr(Expr prev)
        {
            var bracket = Match("{");

            var projections = new List <Expr>();

            while (true)
            {
                var token = GetToken();

                if (token.Kind == "}")
                {
                    Match("}");
                    break;
                }

                string id = null;
                Expr   projection;

                if (token.Kind == "}")
                {
                    Match("}");
                    break;
                }

                if (token.Kind == "...")
                {
                    var ellipsis = Match("...");
                    var next     = GetToken();
                    projection = new SpreadExpr(GetLocation(ellipsis), ParseExpr());
                }
                else if (token.Kind == "$")
                {
                    var dollar         = Match("$");
                    var dollarLocation = GetLocation(dollar);
                    id         = Match("ID").Text;
                    projection = new KeyValuePairExpr(dollarLocation, id, new VariableExpr(dollarLocation, id));
                }
                else
                {
                    var idToken    = MatchAny(new [] { "STRING", "ID" });
                    var idLocation = GetLocation(idToken);
                    id = idToken.Text;
                    var curr = GetToken();
                    if (curr.Kind == ":")
                    {
                        Match(":");
                        projection = new KeyValuePairExpr(idLocation, id, ParseExpr());
                    }
                    else if (curr.Kind == "{")
                    {
                        // These are all equivalent:
                        // foo: foo | { a, b, c }
                        // foo | { a, b, c }
                        // foo { a, b, c }
                        MatchOptional("|");

                        var rhs = new ChainExpr(
                            new KeyExpr(idLocation, prev, id),
                            ParseExpr(),
                            ChainBehavior.ToMultipleIfArray);

                        projection = new KeyValuePairExpr(idLocation, id, rhs);
                    }
                    else if (curr.Kind == "(")
                    {
                        // key(a: 123)  =>  key: key(a:123)
                        var keyExpr = new KeyExpr(idLocation, prev, id);
                        var rhs     = ParseChainRemainder(keyExpr);

                        projection = new KeyValuePairExpr(idLocation, id, rhs);
                    }
                    else if (curr.Kind == "[?")
                    {
                        // x[? filter] => x: x[? filter]
                        var keyExpr = new KeyExpr(idLocation, prev, id);
                        var rhs     = ParseChainRemainder(keyExpr);

                        projection = new KeyValuePairExpr(idLocation, id, rhs);
                    }
                    else if (curr.Kind == "[")
                    {
                        // x[5] => x: x[5]
                        var keyExpr = new KeyExpr(idLocation, prev, id);
                        var rhs     = ParseChainRemainder(keyExpr);

                        projection = new KeyValuePairExpr(idLocation, id, rhs);
                    }
                    else if (curr.Kind == "|")
                    {
                        // These are all equivalent:
                        // foo: foo | { a, b, c }
                        // foo | { a, b, c }
                        // foo { a, b, c }
                        MatchOptional("|");

                        var rhs = new ChainExpr(
                            new KeyExpr(idLocation, prev, id),
                            ParseExpr(),
                            ChainBehavior.OneToOne);

                        projection = new KeyValuePairExpr(idLocation, id, rhs);
                    }
                    else if (curr.Kind == "|<")
                    {
                        // This is another shorthand for filtring an array of objects. These are equivalent:
                        /// foo: foo |< { a, b, c }
                        /// foo |< { a, b, c}
                        Match("|<");

                        var rhs = new ChainExpr(
                            new KeyExpr(idLocation, prev, id),
                            ParseExpr(),
                            ChainBehavior.ToMultiple);

                        projection = new KeyValuePairExpr(idLocation, id, rhs);
                    }
                    else
                    {
                        projection = new KeyValuePairExpr(idLocation, id, new KeyExpr(idLocation, null, id));
                    }
                }

                projections.Add(projection);

                var tok = MatchAny(new [] { ",", "}" });
                if (tok.Kind == "}")
                {
                    break;
                }
            }

            return(new MapProjectionExpr(GetLocation(bracket), prev, projections));
        }