Mercurial > public > mercurial-scm > hg-stable
diff mercurial/revset.py @ 29933:b3845cab4ddc
revset: wrap arguments of 'or' by 'list' node
This makes the number of 'or' arguments deterministic so we can attach
additional ordering flag to all operator nodes. See the next patch.
We rewrite the tree immediately after chained 'or' operations are flattened
by simplifyinfixops(), so we don't need to care if arguments are stored in
x[1] or x[1:].
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Sun, 07 Aug 2016 17:04:05 +0900 |
parents | ae933e3e2226 |
children | 90455e7bf543 |
line wrap: on
line diff
--- a/mercurial/revset.py Tue Sep 13 20:30:19 2016 +0200 +++ b/mercurial/revset.py Sun Aug 07 17:04:05 2016 +0900 @@ -397,15 +397,18 @@ def differenceset(repo, subset, x, y): return getset(repo, subset, x) - getset(repo, subset, y) -def orset(repo, subset, *xs): +def _orsetlist(repo, subset, xs): assert xs if len(xs) == 1: return getset(repo, subset, xs[0]) p = len(xs) // 2 - a = orset(repo, subset, *xs[:p]) - b = orset(repo, subset, *xs[p:]) + a = _orsetlist(repo, subset, xs[:p]) + b = _orsetlist(repo, subset, xs[p:]) return a + b +def orset(repo, subset, x): + return _orsetlist(repo, subset, getlist(x)) + def notset(repo, subset, x): return subset - getset(repo, subset, x) @@ -2339,6 +2342,10 @@ return _fixops(('range', post, x[2][1])) elif x[2][0] == 'rangeall': return _fixops(('rangepost', post)) + elif op == 'or': + # make number of arguments deterministic: + # x + y + z -> (or x y z) -> (or (list x y z)) + return (op, _fixops(('list',) + x[1:])) return (op,) + tuple(_fixops(y) for y in x[1:]) @@ -2374,7 +2381,7 @@ tb = _analyze(x[2]) return (op, ta, tb) elif op == 'or': - return (op,) + tuple(_analyze(y) for y in x[1:]) + return (op, _analyze(x[1])) elif op == 'not': return (op, _analyze(x[1])) elif op == 'parentpost': @@ -2445,7 +2452,7 @@ ws.append(w) ts.append(t) del ss[:] - for y in x[1:]: + for y in getlist(x[1]): w, t = _optimize(y, False) if t is not None and (t[0] == 'string' or t[0] == 'symbol'): ss.append((w, t)) @@ -2459,7 +2466,7 @@ # we can't reorder trees by weight because it would change the order. # ("sort(a + b)" == "sort(b + a)", but "a + b" != "b + a") # ts = tuple(t for w, t in sorted(zip(ws, ts), key=lambda wt: wt[0])) - return max(ws), (op,) + tuple(ts) + return max(ws), (op, ('list',) + tuple(ts)) elif op == 'not': # Optimize not public() to _notpublic() because we have a fast version if x[1] == ('func', ('symbol', 'public'), None): @@ -2613,7 +2620,7 @@ if len(specs) == 1: tree = parse(specs[0], lookup) else: - tree = ('or',) + tuple(parse(s, lookup) for s in specs) + tree = ('or', ('list',) + tuple(parse(s, lookup) for s in specs)) if ui: tree = expandaliases(ui, tree)