--- a/mercurial/revsetlang.py Fri Jan 04 05:26:13 2019 +0100
+++ b/mercurial/revsetlang.py Fri Jan 04 13:41:21 2019 +0100
@@ -333,7 +333,7 @@
elif op == 'negate':
s = getstring(x[1], _("can't negate that"))
return _analyze(('string', '-' + s))
- elif op in ('string', 'symbol'):
+ elif op in ('string', 'symbol', 'smartset'):
return x
elif op == 'rangeall':
return (op, None)
@@ -373,7 +373,7 @@
return 0, x
op = x[0]
- if op in ('string', 'symbol'):
+ if op in ('string', 'symbol', 'smartset'):
return 0.5, x # single revisions are small
elif op == 'and':
wa, ta = _optimize(x[1])
@@ -535,7 +535,8 @@
def foldconcat(tree):
"""Fold elements to be concatenated by `##`
"""
- if not isinstance(tree, tuple) or tree[0] in ('string', 'symbol'):
+ if (not isinstance(tree, tuple)
+ or tree[0] in ('string', 'symbol', 'smartset')):
return tree
if tree[0] == '_concat':
pending = [tree]
@@ -691,6 +692,28 @@
raise error.ProgrammingError("unknown revspec item type: %r" % t)
return b''.join(ret)
+def spectree(expr, *args):
+ """similar to formatspec but return a parsed and optimized tree"""
+ parsed = _parseargs(expr, args)
+ ret = []
+ inputs = []
+ for t, arg in parsed:
+ if t is None:
+ ret.append(arg)
+ elif t == 'baseset':
+ newtree = ('smartset', smartset.baseset(arg))
+ inputs.append(newtree)
+ ret.append("$")
+ else:
+ raise error.ProgrammingError("unknown revspec item type: %r" % t)
+ expr = b''.join(ret)
+ tree = _parsewith(expr, syminitletters=_aliassyminitletters)
+ tree = parser.buildtree(tree, ('symbol', '$'), *inputs)
+ tree = foldconcat(tree)
+ tree = analyze(tree)
+ tree = optimize(tree)
+ return tree
+
def _parseargs(expr, args):
"""parse the expression and replace all inexpensive args