Mercurial > public > mercurial-scm > hg
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 |