3internal static class IntermediateQueryHelpers
 
    5    public static QueryExpr Expr(
string fql) =>
 
    6        new QueryExpr(
new List<IQueryFragment> { 
new QueryLiteral(fql) });
 
    8    public static QueryVal Const(
object? v) => 
new QueryVal(v);
 
   10    private static readonly 
Query _larr = Expr(
"[");
 
   11    private static readonly 
Query _rarr = Expr(
"]");
 
   12    public static Query Array(
Query inner) => _larr.Concat(inner).Concat(_rarr);
 
   13    public static Query Array(IEnumerable<Query> inners) => Join(inners, _larr, 
",", _rarr);
 
   15    private static readonly 
Query _lparen = Expr(
"(");
 
   16    private static readonly 
Query _rparen = Expr(
")");
 
   17    public static Query Parens(
Query inner) => _lparen.Concat(inner).Concat(_rparen);
 
   18    public static Query Parens(IEnumerable<Query> inners) => Join(inners, _lparen, 
",", _rparen);
 
   20    private static readonly 
Query _lbrace = Expr(
"{");
 
   21    private static readonly 
Query _rbrace = Expr(
"}");
 
   22    public static Query Block(
Query inner) => _lbrace.Concat(inner).Concat(
"}");
 
   23    public static Query Block(IEnumerable<Query> inners) => Join(inners, _lbrace, 
";", _rbrace);
 
   24    public static Query Obj(
Query inner) => _lbrace.Concat(inner).Concat(
"}");
 
   25    public static Query Obj(IEnumerable<Query> inners) => Join(inners, _lbrace, 
",", _rbrace);
 
   28        a.Concat(Expr(op)).Concat(b);
 
   30    public static Query FieldAccess(
Query callee, 
string f) =>
 
   31        callee.Concat($
".{f}");
 
   33    public static Query FnCall(
string m) =>
 
   36    public static Query FnCall(
string m, 
Query arg) =>
 
   37        Expr($
"{m}(").Concat(arg).Concat(_rparen);
 
   39    public static Query FnCall(
string m, IEnumerable<Query> args) =>
 
   40        Join(args, Expr($
"{m}("), 
",", _rparen);
 
   42    public static Query MethodCall(
Query callee, 
string m) =>
 
   43        callee.Concat($
".{m}()");
 
   46        callee.Concat($
".{m}(").Concat(a1).Concat(_rparen);
 
   49        callee.Concat($
".{m}(").Concat(a1).Concat(
",").Concat(a2).Concat(_rparen);
 
   51    public static Query MethodCall(
Query callee, 
string m, IEnumerable<Query> args) =>
 
   52        Join(args, callee.Concat($
".{m}("), 
",", _rparen);
 
   54    public static Query Join(IEnumerable<Query> ies, 
Query l, 
string sep, 
Query r)
 
   58        foreach (var ie 
in ies)
 
   60            if (init) init = 
false; 
else ret = ret.Concat(sep);
 
   67    public static Query CollectionAll(DataContext.Collection col) =>
 
   68        MethodCall(Expr(col.Name), 
"all");
 
   70    public static Query CollectionIndex(DataContext.Index idx) =>
 
   71        MethodCall(Expr(idx.Collection.Name), idx.Name, idx.Args.Select(Const));
 
   73    public static QueryExpr Concat(
this Query q1, 
string str)
 
   75        var frags = 
new List<IQueryFragment>();
 
   77        if (q1 is QueryExpr e1)
 
   79            if (e1.Fragments.Last() is QueryLiteral l1)
 
   81                frags.AddRange(e1.Fragments.SkipLast(1));
 
   82                frags.Add(
new QueryLiteral(l1.Unwrap + str));
 
   86                frags.AddRange(e1.Fragments);
 
   87                frags.Add(
new QueryLiteral(str));
 
   93            frags.Add(
new QueryLiteral(str));
 
   96        return new QueryExpr(frags);
 
   99    public static QueryExpr Concat(
this Query q1, 
Query q2)
 
  101        var frags = 
new List<IQueryFragment>();
 
  103        if (q1 is QueryExpr e1)
 
  105            if (q2 is QueryExpr e2)
 
  107                if (e1.Fragments.Last() is QueryLiteral l1 &&
 
  108                    e2.Fragments.First() is QueryLiteral l2)
 
  110                    frags.AddRange(e1.Fragments.SkipLast(1));
 
  111                    frags.Add(
new QueryLiteral(l1.Unwrap + l2.Unwrap));
 
  112                    frags.AddRange(e2.Fragments.Skip(1));
 
  116                    frags.AddRange(e1.Fragments);
 
  117                    frags.AddRange(e2.Fragments);
 
  122                frags.AddRange(e1.Fragments);
 
  128            if (q2 is QueryExpr e2)
 
  131                frags.AddRange(e2.Fragments);
 
  140        return new QueryExpr(frags);