# HG changeset patch # User Yuya Nishihara # Date 1470548103 -32400 # Node ID e4b4168a4f1ce0801f19cd366df1c1861294015d # Parent fe81c953f369cf350f48141092a7ac6f28342e4c revset: extract tree transformation from optimize() This patch separates the simple tree transformation from the optimization step, which is called as _analyze() since I'll extend this function to infer ordering flags. I want to avoid making _optimize() more complicated. This will also allow us to evaluate unoptimized tree. diff -r fe81c953f369 -r e4b4168a4f1c mercurial/revset.py --- a/mercurial/revset.py Sun Sep 04 17:19:44 2016 +0900 +++ b/mercurial/revset.py Sun Aug 07 14:35:03 2016 +0900 @@ -2342,7 +2342,68 @@ return (op,) + tuple(_fixops(y) for y in x[1:]) +def _analyze(x): + """Transform raw parsed tree to evaluatable tree which can be fed to + optimize() or getset() + + All pseudo operations should be mapped to real operations or functions + defined in methods or symbols table respectively. + """ + if x is None: + return x + + op = x[0] + if op == 'minus': + return _analyze(('and', x[1], ('not', x[2]))) + elif op == 'only': + t = ('func', ('symbol', 'only'), ('list', x[1], x[2])) + return _analyze(t) + elif op == 'onlypost': + return _analyze(('func', ('symbol', 'only'), x[1])) + elif op == 'dagrangepre': + return _analyze(('func', ('symbol', 'ancestors'), x[1])) + elif op == 'dagrangepost': + return _analyze(('func', ('symbol', 'descendants'), x[1])) + elif op == 'rangeall': + return _analyze(('range', ('string', '0'), ('string', 'tip'))) + elif op == 'rangepre': + return _analyze(('range', ('string', '0'), x[1])) + elif op == 'rangepost': + return _analyze(('range', x[1], ('string', 'tip'))) + elif op == 'negate': + s = getstring(x[1], _("can't negate that")) + return _analyze(('string', '-' + s)) + elif op in ('string', 'symbol'): + return x + elif op == 'and': + ta = _analyze(x[1]) + tb = _analyze(x[2]) + return (op, ta, tb) + elif op == 'or': + return (op,) + tuple(_analyze(y) for y in x[1:]) + elif op == 'not': + return (op, _analyze(x[1])) + elif op == 'parentpost': + return (op, _analyze(x[1])) + elif op == 'group': + return _analyze(x[1]) + elif op in ('dagrange', 'range', 'parent', 'ancestor'): + ta = _analyze(x[1]) + tb = _analyze(x[2]) + return (op, ta, tb) + elif op == 'list': + return (op,) + tuple(_analyze(y) for y in x[1:]) + elif op == 'keyvalue': + return (op, x[1], _analyze(x[2])) + elif op == 'func': + return (op, x[1], _analyze(x[2])) + raise ValueError('invalid operator %r' % op) + def _optimize(x, small): + """Optimize evaluatable tree + + All pseudo operations should be transformed beforehand. + """ if x is None: return 0, x @@ -2351,27 +2412,7 @@ smallbonus = .5 op = x[0] - if op == 'minus': - return _optimize(('and', x[1], ('not', x[2])), small) - elif op == 'only': - t = ('func', ('symbol', 'only'), ('list', x[1], x[2])) - return _optimize(t, small) - elif op == 'onlypost': - return _optimize(('func', ('symbol', 'only'), x[1]), small) - elif op == 'dagrangepre': - return _optimize(('func', ('symbol', 'ancestors'), x[1]), small) - elif op == 'dagrangepost': - return _optimize(('func', ('symbol', 'descendants'), x[1]), small) - elif op == 'rangeall': - return _optimize(('range', ('string', '0'), ('string', 'tip')), small) - elif op == 'rangepre': - return _optimize(('range', ('string', '0'), x[1]), small) - elif op == 'rangepost': - return _optimize(('range', x[1], ('string', 'tip')), small) - elif op == 'negate': - s = getstring(x[1], _("can't negate that")) - return _optimize(('string', '-' + s), small) - elif op in ('string', 'symbol'): + if op in ('string', 'symbol'): return smallbonus, x # single revisions are small elif op == 'and': wa, ta = _optimize(x[1], True) @@ -2432,8 +2473,6 @@ elif op == 'parentpost': o = _optimize(x[1], small) return o[0], (op, o[1]) - elif op == 'group': - return _optimize(x[1], small) elif op in ('dagrange', 'range', 'parent', 'ancestor'): wa, ta = _optimize(x[1], small) wb, tb = _optimize(x[2], small) @@ -2466,6 +2505,7 @@ raise ValueError('invalid operator %r' % op) def optimize(tree): + tree = _analyze(tree) _weight, newtree = _optimize(tree, small=True) return newtree