comparison mercurial/revset.py @ 29769:abe4eecc3253

revset: resolve ambiguity of x^:y before alias expansion This is purely a parsing problem, which should be resolved before alias expansion.
author Yuya Nishihara <yuya@tcha.org>
date Sat, 06 Aug 2016 20:21:00 +0900
parents e5b794063fd4
children 9c51a5de76db
comparison
equal deleted inserted replaced
29768:8e4841944e68 29769:abe4eecc3253
2312 and bases[0] == 'not' 2312 and bases[0] == 'not'
2313 and bases[1][0] == 'func' 2313 and bases[1][0] == 'func'
2314 and getsymbol(bases[1][1]) == 'ancestors'): 2314 and getsymbol(bases[1][1]) == 'ancestors'):
2315 return ('list', revs[2], bases[1][2]) 2315 return ('list', revs[2], bases[1][2])
2316 2316
2317 def _fixops(x):
2318 """Rewrite raw parsed tree to resolve ambiguous syntax which cannot be
2319 handled well by our simple top-down parser"""
2320 if not isinstance(x, tuple):
2321 return x
2322
2323 op = x[0]
2324 if op == 'parent':
2325 # x^:y means (x^) : y, not x ^ (:y)
2326 post = ('parentpost', x[1])
2327 if x[2][0] == 'dagrangepre':
2328 return _fixops(('dagrange', post, x[2][1]))
2329 elif x[2][0] == 'rangepre':
2330 return _fixops(('range', post, x[2][1]))
2331
2332 return (op,) + tuple(_fixops(y) for y in x[1:])
2333
2317 def _optimize(x, small): 2334 def _optimize(x, small):
2318 if x is None: 2335 if x is None:
2319 return 0, x 2336 return 0, x
2320 2337
2321 smallbonus = 1 2338 smallbonus = 1
2405 o = _optimize(x[1], small) 2422 o = _optimize(x[1], small)
2406 return o[0], (op, o[1]) 2423 return o[0], (op, o[1])
2407 elif op == 'group': 2424 elif op == 'group':
2408 return _optimize(x[1], small) 2425 return _optimize(x[1], small)
2409 elif op in 'dagrange range parent ancestorspec': 2426 elif op in 'dagrange range parent ancestorspec':
2410 if op == 'parent':
2411 # x^:y means (x^) : y, not x ^ (:y)
2412 post = ('parentpost', x[1])
2413 if x[2][0] == 'dagrangepre':
2414 return _optimize(('dagrange', post, x[2][1]), small)
2415 elif x[2][0] == 'rangepre':
2416 return _optimize(('range', post, x[2][1]), small)
2417
2418 wa, ta = _optimize(x[1], small) 2427 wa, ta = _optimize(x[1], small)
2419 wb, tb = _optimize(x[2], small) 2428 wb, tb = _optimize(x[2], small)
2420 return wa + wb, (op, ta, tb) 2429 return wa + wb, (op, ta, tb)
2421 elif op == 'list': 2430 elif op == 'list':
2422 ws, ts = zip(*(_optimize(y, small) for y in x[1:])) 2431 ws, ts = zip(*(_optimize(y, small) for y in x[1:]))
2468 p = parser.parser(elements) 2477 p = parser.parser(elements)
2469 tree, pos = p.parse(tokenize(spec, lookup=lookup, 2478 tree, pos = p.parse(tokenize(spec, lookup=lookup,
2470 syminitletters=syminitletters)) 2479 syminitletters=syminitletters))
2471 if pos != len(spec): 2480 if pos != len(spec):
2472 raise error.ParseError(_('invalid token'), pos) 2481 raise error.ParseError(_('invalid token'), pos)
2473 return parser.simplifyinfixops(tree, ('list', 'or')) 2482 return _fixops(parser.simplifyinfixops(tree, ('list', 'or')))
2474 2483
2475 class _aliasrules(parser.basealiasrules): 2484 class _aliasrules(parser.basealiasrules):
2476 """Parsing and expansion rule set of revset aliases""" 2485 """Parsing and expansion rule set of revset aliases"""
2477 _section = _('revset alias') 2486 _section = _('revset alias')
2478 2487