# HG changeset patch # User Yuya Nishihara # Date 1514624123 -32400 # Node ID beb667c9880f8a8b616c90c7c2b588a84cf228ae # Parent 58fda95a0202fc6327d1f5d9df26f7ff16538d57 revset: parse x^:: as (x^):: (issue5764) We have to make '::' a valid primary expression to parse 'x^::' as '(x)^(::)' first, but that doesn't change the language because a prefix operator '::y' precedes a primary '::'. I can't think of an intuitive meaning of '::', so it's just rejected. Given 'x::y' can be considered to default to {x = roots(), y = heads()}, '::' could be 'roots()::heads()', which seems not any useful. diff -r 58fda95a0202 -r beb667c9880f mercurial/revsetlang.py --- a/mercurial/revsetlang.py Fri Jan 05 21:48:29 2018 -0500 +++ b/mercurial/revsetlang.py Sat Dec 30 17:55:23 2017 +0900 @@ -27,8 +27,10 @@ "~": (18, None, None, ("ancestor", 18), None), "^": (18, None, None, ("parent", 18), "parentpost"), "-": (5, None, ("negate", 19), ("minus", 5), None), - "::": (17, None, ("dagrangepre", 17), ("dagrange", 17), "dagrangepost"), - "..": (17, None, ("dagrangepre", 17), ("dagrange", 17), "dagrangepost"), + "::": (17, "dagrangeall", ("dagrangepre", 17), ("dagrange", 17), + "dagrangepost"), + "..": (17, "dagrangeall", ("dagrangepre", 17), ("dagrange", 17), + "dagrangepost"), ":": (15, "rangeall", ("rangepre", 15), ("range", 15), "rangepost"), "not": (10, None, ("not", 10), None, None), "!": (10, None, ("not", 10), None, None), @@ -288,6 +290,8 @@ post = ('parentpost', x[1]) if x[2][0] == 'dagrangepre': return _fixops(('dagrange', post, x[2][1])) + elif x[2][0] == 'dagrangeall': + return _fixops(('dagrangepost', post)) elif x[2][0] == 'rangepre': return _fixops(('range', post, x[2][1])) elif x[2][0] == 'rangeall': @@ -313,6 +317,8 @@ return _analyze(_build('only(_, _)', *x[1:])) elif op == 'onlypost': return _analyze(_build('only(_)', x[1])) + elif op == 'dagrangeall': + raise error.ParseError(_("can't use '::' in this context")) elif op == 'dagrangepre': return _analyze(_build('ancestors(_)', x[1])) elif op == 'dagrangepost': diff -r 58fda95a0202 -r beb667c9880f tests/test-revset.t --- a/tests/test-revset.t Fri Jan 05 21:48:29 2018 -0500 +++ b/tests/test-revset.t Sat Dec 30 17:55:23 2017 +0900 @@ -792,7 +792,7 @@ * set: -infix/suffix resolution of ^ operator (issue2884): +infix/suffix resolution of ^ operator (issue2884, issue5764): x^:y means (x^):y @@ -818,6 +818,17 @@ 1 2 + $ try '1^..2' + (dagrange + (parentpost + (symbol '1')) + (symbol '2')) + * set: + + 0 + 1 + 2 + $ try '9^:' (rangepost (parentpost @@ -827,6 +838,24 @@ 8 9 + $ try '9^::' + (dagrangepost + (parentpost + (symbol '9'))) + * set: + + 8 + 9 + + $ try '9^..' + (dagrangepost + (parentpost + (symbol '9'))) + * set: + + 8 + 9 + x^:y should be resolved before omitting group operators $ try '1^(:2)' @@ -944,6 +973,14 @@ hg: parse error: ^ expects a number 0, 1, or 2 [255] +'::' itself isn't a valid expression + + $ try '::' + (dagrangeall + None) + hg: parse error: can't use '::' in this context + [255] + ancestor can accept 0 or more arguments $ log 'ancestor()'