Show More
@@ -151,6 +151,15 b' def orset(repo, subset, x, order):' | |||||
151 | def notset(repo, subset, x, order): |
|
151 | def notset(repo, subset, x, order): | |
152 | return subset - getset(repo, subset, x) |
|
152 | return subset - getset(repo, subset, x) | |
153 |
|
153 | |||
|
154 | def relationset(repo, subset, x, y, order): | |||
|
155 | raise error.ParseError(_("can't use a relation in this context")) | |||
|
156 | ||||
|
157 | def relsubscriptset(repo, subset, x, y, z, order): | |||
|
158 | raise error.ParseError(_("can't use a relation in this context")) | |||
|
159 | ||||
|
160 | def subscriptset(repo, subset, x, y, order): | |||
|
161 | raise error.ParseError(_("can't use a subscript in this context")) | |||
|
162 | ||||
154 | def listset(repo, subset, *xs): |
|
163 | def listset(repo, subset, *xs): | |
155 | raise error.ParseError(_("can't use a list in this context"), |
|
164 | raise error.ParseError(_("can't use a list in this context"), | |
156 | hint=_('see hg help "revsets.x or y"')) |
|
165 | hint=_('see hg help "revsets.x or y"')) | |
@@ -2004,6 +2013,9 b' methods = {' | |||||
2004 | "or": orset, |
|
2013 | "or": orset, | |
2005 | "not": notset, |
|
2014 | "not": notset, | |
2006 | "difference": differenceset, |
|
2015 | "difference": differenceset, | |
|
2016 | "relation": relationset, | |||
|
2017 | "relsubscript": relsubscriptset, | |||
|
2018 | "subscript": subscriptset, | |||
2007 | "list": listset, |
|
2019 | "list": listset, | |
2008 | "keyvalue": keyvaluepair, |
|
2020 | "keyvalue": keyvaluepair, | |
2009 | "func": func, |
|
2021 | "func": func, |
@@ -21,6 +21,8 b' from . import (' | |||||
21 | elements = { |
|
21 | elements = { | |
22 | # token-type: binding-strength, primary, prefix, infix, suffix |
|
22 | # token-type: binding-strength, primary, prefix, infix, suffix | |
23 | "(": (21, None, ("group", 1, ")"), ("func", 1, ")"), None), |
|
23 | "(": (21, None, ("group", 1, ")"), ("func", 1, ")"), None), | |
|
24 | "[": (21, None, None, ("subscript", 1, "]"), None), | |||
|
25 | "#": (21, None, None, ("relation", 21), None), | |||
24 | "##": (20, None, None, ("_concat", 20), None), |
|
26 | "##": (20, None, None, ("_concat", 20), None), | |
25 | "~": (18, None, None, ("ancestor", 18), None), |
|
27 | "~": (18, None, None, ("ancestor", 18), None), | |
26 | "^": (18, None, None, ("parent", 18), "parentpost"), |
|
28 | "^": (18, None, None, ("parent", 18), "parentpost"), | |
@@ -39,6 +41,7 b' elements = {' | |||||
39 | "=": (3, None, None, ("keyvalue", 3), None), |
|
41 | "=": (3, None, None, ("keyvalue", 3), None), | |
40 | ",": (2, None, None, ("list", 2), None), |
|
42 | ",": (2, None, None, ("list", 2), None), | |
41 | ")": (0, None, None, None, None), |
|
43 | ")": (0, None, None, None, None), | |
|
44 | "]": (0, None, None, None, None), | |||
42 | "symbol": (0, "symbol", None, None, None), |
|
45 | "symbol": (0, "symbol", None, None, None), | |
43 | "string": (0, "string", None, None, None), |
|
46 | "string": (0, "string", None, None, None), | |
44 | "end": (0, None, None, None, None), |
|
47 | "end": (0, None, None, None, None), | |
@@ -47,7 +50,7 b' elements = {' | |||||
47 | keywords = {'and', 'or', 'not'} |
|
50 | keywords = {'and', 'or', 'not'} | |
48 |
|
51 | |||
49 | _quoteletters = {'"', "'"} |
|
52 | _quoteletters = {'"', "'"} | |
50 | _simpleopletters = set(pycompat.iterbytestr("():=,-|&+!~^%")) |
|
53 | _simpleopletters = set(pycompat.iterbytestr("()[]#:=,-|&+!~^%")) | |
51 |
|
54 | |||
52 | # default set of valid characters for the initial letter of symbols |
|
55 | # default set of valid characters for the initial letter of symbols | |
53 | _syminitletters = set(pycompat.iterbytestr( |
|
56 | _syminitletters = set(pycompat.iterbytestr( | |
@@ -331,6 +334,9 b' def _fixops(x):' | |||||
331 | # make number of arguments deterministic: |
|
334 | # make number of arguments deterministic: | |
332 | # x + y + z -> (or x y z) -> (or (list x y z)) |
|
335 | # x + y + z -> (or x y z) -> (or (list x y z)) | |
333 | return (op, _fixops(('list',) + x[1:])) |
|
336 | return (op, _fixops(('list',) + x[1:])) | |
|
337 | elif op == 'subscript' and x[1][0] == 'relation': | |||
|
338 | # x#y[z] ternary | |||
|
339 | return _fixops(('relsubscript', x[1][1], x[1][2], x[2])) | |||
334 |
|
340 | |||
335 | return (op,) + tuple(_fixops(y) for y in x[1:]) |
|
341 | return (op,) + tuple(_fixops(y) for y in x[1:]) | |
336 |
|
342 | |||
@@ -369,10 +375,16 b' def _analyze(x, order):' | |||||
369 | return (op, _analyze(x[1], defineorder), order) |
|
375 | return (op, _analyze(x[1], defineorder), order) | |
370 | elif op == 'group': |
|
376 | elif op == 'group': | |
371 | return _analyze(x[1], order) |
|
377 | return _analyze(x[1], order) | |
372 |
elif op in ('dagrange', 'range', 'parent', 'ancestor' |
|
378 | elif op in ('dagrange', 'range', 'parent', 'ancestor', 'relation', | |
|
379 | 'subscript'): | |||
373 | ta = _analyze(x[1], defineorder) |
|
380 | ta = _analyze(x[1], defineorder) | |
374 | tb = _analyze(x[2], defineorder) |
|
381 | tb = _analyze(x[2], defineorder) | |
375 | return (op, ta, tb, order) |
|
382 | return (op, ta, tb, order) | |
|
383 | elif op == 'relsubscript': | |||
|
384 | ta = _analyze(x[1], defineorder) | |||
|
385 | tb = _analyze(x[2], defineorder) | |||
|
386 | tc = _analyze(x[3], defineorder) | |||
|
387 | return (op, ta, tb, tc, order) | |||
376 | elif op == 'list': |
|
388 | elif op == 'list': | |
377 | return (op,) + tuple(_analyze(y, order) for y in x[1:]) |
|
389 | return (op,) + tuple(_analyze(y, order) for y in x[1:]) | |
378 | elif op == 'keyvalue': |
|
390 | elif op == 'keyvalue': | |
@@ -481,10 +493,14 b' def _optimize(x, small):' | |||||
481 | wb, tb = _optimize(x[2], small) |
|
493 | wb, tb = _optimize(x[2], small) | |
482 | order = x[3] |
|
494 | order = x[3] | |
483 | return wa + wb, (op, ta, tb, order) |
|
495 | return wa + wb, (op, ta, tb, order) | |
484 | elif op in ('parent', 'ancestor'): |
|
496 | elif op in ('parent', 'ancestor', 'relation', 'subscript'): | |
485 | w, t = _optimize(x[1], small) |
|
497 | w, t = _optimize(x[1], small) | |
486 | order = x[3] |
|
498 | order = x[3] | |
487 | return w, (op, t, x[2], order) |
|
499 | return w, (op, t, x[2], order) | |
|
500 | elif op == 'relsubscript': | |||
|
501 | w, t = _optimize(x[1], small) | |||
|
502 | order = x[4] | |||
|
503 | return w, (op, t, x[2], x[3], order) | |||
488 | elif op == 'list': |
|
504 | elif op == 'list': | |
489 | ws, ts = zip(*(_optimize(y, small) for y in x[1:])) |
|
505 | ws, ts = zip(*(_optimize(y, small) for y in x[1:])) | |
490 | return sum(ws), (op,) + ts |
|
506 | return sum(ws), (op,) + ts |
@@ -812,7 +812,7 b' check error cases' | |||||
812 | abort: line range exceeds file size |
|
812 | abort: line range exceeds file size | |
813 | [255] |
|
813 | [255] | |
814 | $ hg log -r 'followlines(baz, 2:4, startrev=20, descend=[1])' |
|
814 | $ hg log -r 'followlines(baz, 2:4, startrev=20, descend=[1])' | |
815 | hg: parse error at 43: syntax error in revset 'followlines(baz, 2:4, startrev=20, descend=[1])' |
|
815 | hg: parse error at 43: not a prefix: [ | |
816 | [255] |
|
816 | [255] | |
817 | $ hg log -r 'followlines(baz, 2:4, startrev=20, descend=a)' |
|
817 | $ hg log -r 'followlines(baz, 2:4, startrev=20, descend=a)' | |
818 | hg: parse error: descend argument must be a boolean |
|
818 | hg: parse error: descend argument must be a boolean |
@@ -500,6 +500,151 b' keyword arguments' | |||||
500 | hg: parse error: can't use a key-value pair in this context |
|
500 | hg: parse error: can't use a key-value pair in this context | |
501 | [255] |
|
501 | [255] | |
502 |
|
502 | |||
|
503 | relation-subscript operator has the highest binding strength (as function call): | |||
|
504 | ||||
|
505 | $ hg debugrevspec -p parsed 'tip:tip^#generations[-1]' | |||
|
506 | * parsed: | |||
|
507 | (range | |||
|
508 | ('symbol', 'tip') | |||
|
509 | (relsubscript | |||
|
510 | (parentpost | |||
|
511 | ('symbol', 'tip')) | |||
|
512 | ('symbol', 'generations') | |||
|
513 | (negate | |||
|
514 | ('symbol', '1')))) | |||
|
515 | hg: parse error: can't use a relation in this context | |||
|
516 | [255] | |||
|
517 | ||||
|
518 | $ hg debugrevspec -p parsed --no-show-revs 'not public()#generations[0]' | |||
|
519 | * parsed: | |||
|
520 | (not | |||
|
521 | (relsubscript | |||
|
522 | (func | |||
|
523 | ('symbol', 'public') | |||
|
524 | None) | |||
|
525 | ('symbol', 'generations') | |||
|
526 | ('symbol', '0'))) | |||
|
527 | hg: parse error: can't use a relation in this context | |||
|
528 | [255] | |||
|
529 | ||||
|
530 | left-hand side of relation-subscript operator should be optimized recursively: | |||
|
531 | ||||
|
532 | $ hg debugrevspec -p analyzed -p optimized --no-show-revs \ | |||
|
533 | > '(not public())#generations[0]' | |||
|
534 | * analyzed: | |||
|
535 | (relsubscript | |||
|
536 | (not | |||
|
537 | (func | |||
|
538 | ('symbol', 'public') | |||
|
539 | None | |||
|
540 | any) | |||
|
541 | define) | |||
|
542 | ('symbol', 'generations') | |||
|
543 | ('symbol', '0') | |||
|
544 | define) | |||
|
545 | * optimized: | |||
|
546 | (relsubscript | |||
|
547 | (func | |||
|
548 | ('symbol', '_notpublic') | |||
|
549 | None | |||
|
550 | any) | |||
|
551 | ('symbol', 'generations') | |||
|
552 | ('symbol', '0') | |||
|
553 | define) | |||
|
554 | hg: parse error: can't use a relation in this context | |||
|
555 | [255] | |||
|
556 | ||||
|
557 | resolution of subscript and relation-subscript ternary operators: | |||
|
558 | ||||
|
559 | $ hg debugrevspec -p analyzed 'tip[0]' | |||
|
560 | * analyzed: | |||
|
561 | (subscript | |||
|
562 | ('symbol', 'tip') | |||
|
563 | ('symbol', '0') | |||
|
564 | define) | |||
|
565 | hg: parse error: can't use a subscript in this context | |||
|
566 | [255] | |||
|
567 | ||||
|
568 | $ hg debugrevspec -p analyzed 'tip#rel[0]' | |||
|
569 | * analyzed: | |||
|
570 | (relsubscript | |||
|
571 | ('symbol', 'tip') | |||
|
572 | ('symbol', 'rel') | |||
|
573 | ('symbol', '0') | |||
|
574 | define) | |||
|
575 | hg: parse error: can't use a relation in this context | |||
|
576 | [255] | |||
|
577 | ||||
|
578 | $ hg debugrevspec -p analyzed '(tip#rel)[0]' | |||
|
579 | * analyzed: | |||
|
580 | (subscript | |||
|
581 | (relation | |||
|
582 | ('symbol', 'tip') | |||
|
583 | ('symbol', 'rel') | |||
|
584 | define) | |||
|
585 | ('symbol', '0') | |||
|
586 | define) | |||
|
587 | hg: parse error: can't use a subscript in this context | |||
|
588 | [255] | |||
|
589 | ||||
|
590 | $ hg debugrevspec -p analyzed 'tip#rel[0][1]' | |||
|
591 | * analyzed: | |||
|
592 | (subscript | |||
|
593 | (relsubscript | |||
|
594 | ('symbol', 'tip') | |||
|
595 | ('symbol', 'rel') | |||
|
596 | ('symbol', '0') | |||
|
597 | define) | |||
|
598 | ('symbol', '1') | |||
|
599 | define) | |||
|
600 | hg: parse error: can't use a subscript in this context | |||
|
601 | [255] | |||
|
602 | ||||
|
603 | $ hg debugrevspec -p analyzed 'tip#rel0#rel1[1]' | |||
|
604 | * analyzed: | |||
|
605 | (relsubscript | |||
|
606 | (relation | |||
|
607 | ('symbol', 'tip') | |||
|
608 | ('symbol', 'rel0') | |||
|
609 | define) | |||
|
610 | ('symbol', 'rel1') | |||
|
611 | ('symbol', '1') | |||
|
612 | define) | |||
|
613 | hg: parse error: can't use a relation in this context | |||
|
614 | [255] | |||
|
615 | ||||
|
616 | $ hg debugrevspec -p analyzed 'tip#rel0[0]#rel1[1]' | |||
|
617 | * analyzed: | |||
|
618 | (relsubscript | |||
|
619 | (relsubscript | |||
|
620 | ('symbol', 'tip') | |||
|
621 | ('symbol', 'rel0') | |||
|
622 | ('symbol', '0') | |||
|
623 | define) | |||
|
624 | ('symbol', 'rel1') | |||
|
625 | ('symbol', '1') | |||
|
626 | define) | |||
|
627 | hg: parse error: can't use a relation in this context | |||
|
628 | [255] | |||
|
629 | ||||
|
630 | parse errors of relation, subscript and relation-subscript operators: | |||
|
631 | ||||
|
632 | $ hg debugrevspec '[0]' | |||
|
633 | hg: parse error at 0: not a prefix: [ | |||
|
634 | [255] | |||
|
635 | $ hg debugrevspec '.#' | |||
|
636 | hg: parse error at 2: not a prefix: end | |||
|
637 | [255] | |||
|
638 | $ hg debugrevspec '#rel' | |||
|
639 | hg: parse error at 0: not a prefix: # | |||
|
640 | [255] | |||
|
641 | $ hg debugrevspec '.#rel[0' | |||
|
642 | hg: parse error at 7: unexpected token: end | |||
|
643 | [255] | |||
|
644 | $ hg debugrevspec '.]' | |||
|
645 | hg: parse error at 1: invalid token | |||
|
646 | [255] | |||
|
647 | ||||
503 | parsed tree at stages: |
|
648 | parsed tree at stages: | |
504 |
|
649 | |||
505 | $ hg debugrevspec -p all '()' |
|
650 | $ hg debugrevspec -p all '()' |
General Comments 0
You need to be logged in to leave comments.
Login now