Mercurial > hg
annotate mercurial/revsetlang.py @ 32405:bdc4861ffe59
fsmonitor: fix silly "*kwargs" bug in merge.update() override
Everyone knows that it's supposed to be spelled with two asterisks.
It started failing in fad5e299cfc7 (update: accept --merge to allow
merging across topo branches (issue5125), 2017-02-13) because until
then there was only one argument that was covered by the kwargs, so
*kwargs or **kwargs both worked (or at least that's what I think with
my limited understanding of Python).
author | Martin von Zweigbergk <martinvonz@google.com> |
---|---|
date | Mon, 22 May 2017 10:41:32 -0700 |
parents | bd872f64a8ba |
children | c808507cfbf0 |
rev | line source |
---|---|
31024
0b8356705de6
revset: split language services to revsetlang module (API)
Yuya Nishihara <yuya@tcha.org>
parents:
31017
diff
changeset
|
1 # revsetlang.py - parser, tokenizer and utility for revision set language |
11275 | 2 # |
3 # Copyright 2010 Matt Mackall <mpm@selenic.com> | |
4 # | |
5 # This software may be used and distributed according to the terms of the | |
6 # GNU General Public License version 2 or any later version. | |
7 | |
25971
e9cd028f2dff
revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25929
diff
changeset
|
8 from __future__ import absolute_import |
e9cd028f2dff
revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25929
diff
changeset
|
9 |
30071
2def3d55b1b9
revset: build _syminitletters from a saner source: the string module
Augie Fackler <augie@google.com>
parents:
30056
diff
changeset
|
10 import string |
25971
e9cd028f2dff
revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25929
diff
changeset
|
11 |
e9cd028f2dff
revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25929
diff
changeset
|
12 from .i18n import _ |
e9cd028f2dff
revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25929
diff
changeset
|
13 from . import ( |
e9cd028f2dff
revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25929
diff
changeset
|
14 error, |
e9cd028f2dff
revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25929
diff
changeset
|
15 node, |
e9cd028f2dff
revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25929
diff
changeset
|
16 parser, |
30071
2def3d55b1b9
revset: build _syminitletters from a saner source: the string module
Augie Fackler <augie@google.com>
parents:
30056
diff
changeset
|
17 pycompat, |
31606
0b3eb280564b
revsetlang: perform quoting using ui.escapestr instead of repr()
Augie Fackler <augie@google.com>
parents:
31605
diff
changeset
|
18 util, |
25971
e9cd028f2dff
revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25929
diff
changeset
|
19 ) |
11275 | 20 |
21 elements = { | |
25815
e71e5629e006
parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents:
25801
diff
changeset
|
22 # token-type: binding-strength, primary, prefix, infix, suffix |
e71e5629e006
parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents:
25801
diff
changeset
|
23 "(": (21, None, ("group", 1, ")"), ("func", 1, ")"), None), |
e71e5629e006
parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents:
25801
diff
changeset
|
24 "##": (20, None, None, ("_concat", 20), None), |
e71e5629e006
parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents:
25801
diff
changeset
|
25 "~": (18, None, None, ("ancestor", 18), None), |
29767
e5b794063fd4
parser: remove unused binding parameter from suffix action
Yuya Nishihara <yuya@tcha.org>
parents:
29646
diff
changeset
|
26 "^": (18, None, None, ("parent", 18), "parentpost"), |
25815
e71e5629e006
parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents:
25801
diff
changeset
|
27 "-": (5, None, ("negate", 19), ("minus", 5), None), |
29767
e5b794063fd4
parser: remove unused binding parameter from suffix action
Yuya Nishihara <yuya@tcha.org>
parents:
29646
diff
changeset
|
28 "::": (17, None, ("dagrangepre", 17), ("dagrange", 17), "dagrangepost"), |
e5b794063fd4
parser: remove unused binding parameter from suffix action
Yuya Nishihara <yuya@tcha.org>
parents:
29646
diff
changeset
|
29 "..": (17, None, ("dagrangepre", 17), ("dagrange", 17), "dagrangepost"), |
e5b794063fd4
parser: remove unused binding parameter from suffix action
Yuya Nishihara <yuya@tcha.org>
parents:
29646
diff
changeset
|
30 ":": (15, "rangeall", ("rangepre", 15), ("range", 15), "rangepost"), |
25815
e71e5629e006
parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents:
25801
diff
changeset
|
31 "not": (10, None, ("not", 10), None, None), |
e71e5629e006
parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents:
25801
diff
changeset
|
32 "!": (10, None, ("not", 10), None, None), |
e71e5629e006
parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents:
25801
diff
changeset
|
33 "and": (5, None, None, ("and", 5), None), |
e71e5629e006
parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents:
25801
diff
changeset
|
34 "&": (5, None, None, ("and", 5), None), |
29767
e5b794063fd4
parser: remove unused binding parameter from suffix action
Yuya Nishihara <yuya@tcha.org>
parents:
29646
diff
changeset
|
35 "%": (5, None, None, ("only", 5), "onlypost"), |
25815
e71e5629e006
parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents:
25801
diff
changeset
|
36 "or": (4, None, None, ("or", 4), None), |
e71e5629e006
parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents:
25801
diff
changeset
|
37 "|": (4, None, None, ("or", 4), None), |
e71e5629e006
parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents:
25801
diff
changeset
|
38 "+": (4, None, None, ("or", 4), None), |
e71e5629e006
parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents:
25801
diff
changeset
|
39 "=": (3, None, None, ("keyvalue", 3), None), |
e71e5629e006
parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents:
25801
diff
changeset
|
40 ",": (2, None, None, ("list", 2), None), |
e71e5629e006
parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents:
25801
diff
changeset
|
41 ")": (0, None, None, None, None), |
e71e5629e006
parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents:
25801
diff
changeset
|
42 "symbol": (0, "symbol", None, None, None), |
e71e5629e006
parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents:
25801
diff
changeset
|
43 "string": (0, "string", None, None, None), |
e71e5629e006
parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents:
25801
diff
changeset
|
44 "end": (0, None, None, None, None), |
11275 | 45 } |
46 | |
32291
bd872f64a8ba
cleanup: use set literals
Martin von Zweigbergk <martinvonz@google.com>
parents:
31997
diff
changeset
|
47 keywords = {'and', 'or', 'not'} |
11275 | 48 |
32291
bd872f64a8ba
cleanup: use set literals
Martin von Zweigbergk <martinvonz@google.com>
parents:
31997
diff
changeset
|
49 _quoteletters = {'"', "'"} |
31384
fac5cd3b8673
py3: make set of revset operators and quotes in bytes
Yuya Nishihara <yuya@tcha.org>
parents:
31383
diff
changeset
|
50 _simpleopletters = set(pycompat.iterbytestr("():=,-|&+!~^%")) |
fac5cd3b8673
py3: make set of revset operators and quotes in bytes
Yuya Nishihara <yuya@tcha.org>
parents:
31383
diff
changeset
|
51 |
23842
91dbb98b3513
revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23836
diff
changeset
|
52 # default set of valid characters for the initial letter of symbols |
31383
7556fe09cc48
py3: convert set of revset initial symbols back to bytes
Yuya Nishihara <yuya@tcha.org>
parents:
31355
diff
changeset
|
53 _syminitletters = set(pycompat.iterbytestr( |
7556fe09cc48
py3: convert set of revset initial symbols back to bytes
Yuya Nishihara <yuya@tcha.org>
parents:
31355
diff
changeset
|
54 string.ascii_letters.encode('ascii') + |
7556fe09cc48
py3: convert set of revset initial symbols back to bytes
Yuya Nishihara <yuya@tcha.org>
parents:
31355
diff
changeset
|
55 string.digits.encode('ascii') + |
7556fe09cc48
py3: convert set of revset initial symbols back to bytes
Yuya Nishihara <yuya@tcha.org>
parents:
31355
diff
changeset
|
56 '._@')) | set(map(pycompat.bytechr, xrange(128, 256))) |
23842
91dbb98b3513
revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23836
diff
changeset
|
57 |
91dbb98b3513
revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23836
diff
changeset
|
58 # default set of valid characters for non-initial letters of symbols |
31383
7556fe09cc48
py3: convert set of revset initial symbols back to bytes
Yuya Nishihara <yuya@tcha.org>
parents:
31355
diff
changeset
|
59 _symletters = _syminitletters | set(pycompat.iterbytestr('-/')) |
23842
91dbb98b3513
revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23836
diff
changeset
|
60 |
91dbb98b3513
revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23836
diff
changeset
|
61 def tokenize(program, lookup=None, syminitletters=None, symletters=None): |
17886
d8905e2c1301
revset: accept @ in unquoted symbols (issue3686)
Matt Mackall <mpm@selenic.com>
parents:
17829
diff
changeset
|
62 ''' |
d8905e2c1301
revset: accept @ in unquoted symbols (issue3686)
Matt Mackall <mpm@selenic.com>
parents:
17829
diff
changeset
|
63 Parse a revset statement into a stream of tokens |
d8905e2c1301
revset: accept @ in unquoted symbols (issue3686)
Matt Mackall <mpm@selenic.com>
parents:
17829
diff
changeset
|
64 |
23842
91dbb98b3513
revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23836
diff
changeset
|
65 ``syminitletters`` is the set of valid characters for the initial |
91dbb98b3513
revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23836
diff
changeset
|
66 letter of symbols. |
91dbb98b3513
revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23836
diff
changeset
|
67 |
91dbb98b3513
revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23836
diff
changeset
|
68 By default, character ``c`` is recognized as valid for initial |
91dbb98b3513
revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23836
diff
changeset
|
69 letter of symbols, if ``c.isalnum() or c in '._@' or ord(c) > 127``. |
91dbb98b3513
revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23836
diff
changeset
|
70 |
91dbb98b3513
revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23836
diff
changeset
|
71 ``symletters`` is the set of valid characters for non-initial |
91dbb98b3513
revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23836
diff
changeset
|
72 letters of symbols. |
91dbb98b3513
revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23836
diff
changeset
|
73 |
91dbb98b3513
revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23836
diff
changeset
|
74 By default, character ``c`` is recognized as valid for non-initial |
91dbb98b3513
revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23836
diff
changeset
|
75 letters of symbols, if ``c.isalnum() or c in '-._/@' or ord(c) > 127``. |
91dbb98b3513
revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23836
diff
changeset
|
76 |
17886
d8905e2c1301
revset: accept @ in unquoted symbols (issue3686)
Matt Mackall <mpm@selenic.com>
parents:
17829
diff
changeset
|
77 Check that @ is a valid unquoted token character (issue3686): |
d8905e2c1301
revset: accept @ in unquoted symbols (issue3686)
Matt Mackall <mpm@selenic.com>
parents:
17829
diff
changeset
|
78 >>> list(tokenize("@::")) |
d8905e2c1301
revset: accept @ in unquoted symbols (issue3686)
Matt Mackall <mpm@selenic.com>
parents:
17829
diff
changeset
|
79 [('symbol', '@', 0), ('::', None, 1), ('end', None, 3)] |
d8905e2c1301
revset: accept @ in unquoted symbols (issue3686)
Matt Mackall <mpm@selenic.com>
parents:
17829
diff
changeset
|
80 |
d8905e2c1301
revset: accept @ in unquoted symbols (issue3686)
Matt Mackall <mpm@selenic.com>
parents:
17829
diff
changeset
|
81 ''' |
31441
80c8a6db450d
py3: use bytestr wrapper in revsetlang.tokenize()
Yuya Nishihara <yuya@tcha.org>
parents:
31440
diff
changeset
|
82 program = pycompat.bytestr(program) |
23842
91dbb98b3513
revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23836
diff
changeset
|
83 if syminitletters is None: |
91dbb98b3513
revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23836
diff
changeset
|
84 syminitletters = _syminitletters |
91dbb98b3513
revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23836
diff
changeset
|
85 if symletters is None: |
91dbb98b3513
revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23836
diff
changeset
|
86 symletters = _symletters |
17886
d8905e2c1301
revset: accept @ in unquoted symbols (issue3686)
Matt Mackall <mpm@selenic.com>
parents:
17829
diff
changeset
|
87 |
25902
5214cbdc37e5
revset: port parsing rule of old-style ranges from scmutil.revrange()
Yuya Nishihara <yuya@tcha.org>
parents:
25819
diff
changeset
|
88 if program and lookup: |
5214cbdc37e5
revset: port parsing rule of old-style ranges from scmutil.revrange()
Yuya Nishihara <yuya@tcha.org>
parents:
25819
diff
changeset
|
89 # attempt to parse old-style ranges first to deal with |
5214cbdc37e5
revset: port parsing rule of old-style ranges from scmutil.revrange()
Yuya Nishihara <yuya@tcha.org>
parents:
25819
diff
changeset
|
90 # things like old-tag which contain query metacharacters |
5214cbdc37e5
revset: port parsing rule of old-style ranges from scmutil.revrange()
Yuya Nishihara <yuya@tcha.org>
parents:
25819
diff
changeset
|
91 parts = program.split(':', 1) |
5214cbdc37e5
revset: port parsing rule of old-style ranges from scmutil.revrange()
Yuya Nishihara <yuya@tcha.org>
parents:
25819
diff
changeset
|
92 if all(lookup(sym) for sym in parts if sym): |
5214cbdc37e5
revset: port parsing rule of old-style ranges from scmutil.revrange()
Yuya Nishihara <yuya@tcha.org>
parents:
25819
diff
changeset
|
93 if parts[0]: |
5214cbdc37e5
revset: port parsing rule of old-style ranges from scmutil.revrange()
Yuya Nishihara <yuya@tcha.org>
parents:
25819
diff
changeset
|
94 yield ('symbol', parts[0], 0) |
5214cbdc37e5
revset: port parsing rule of old-style ranges from scmutil.revrange()
Yuya Nishihara <yuya@tcha.org>
parents:
25819
diff
changeset
|
95 if len(parts) > 1: |
5214cbdc37e5
revset: port parsing rule of old-style ranges from scmutil.revrange()
Yuya Nishihara <yuya@tcha.org>
parents:
25819
diff
changeset
|
96 s = len(parts[0]) |
5214cbdc37e5
revset: port parsing rule of old-style ranges from scmutil.revrange()
Yuya Nishihara <yuya@tcha.org>
parents:
25819
diff
changeset
|
97 yield (':', None, s) |
5214cbdc37e5
revset: port parsing rule of old-style ranges from scmutil.revrange()
Yuya Nishihara <yuya@tcha.org>
parents:
25819
diff
changeset
|
98 if parts[1]: |
5214cbdc37e5
revset: port parsing rule of old-style ranges from scmutil.revrange()
Yuya Nishihara <yuya@tcha.org>
parents:
25819
diff
changeset
|
99 yield ('symbol', parts[1], s + 1) |
5214cbdc37e5
revset: port parsing rule of old-style ranges from scmutil.revrange()
Yuya Nishihara <yuya@tcha.org>
parents:
25819
diff
changeset
|
100 yield ('end', None, len(program)) |
5214cbdc37e5
revset: port parsing rule of old-style ranges from scmutil.revrange()
Yuya Nishihara <yuya@tcha.org>
parents:
25819
diff
changeset
|
101 return |
5214cbdc37e5
revset: port parsing rule of old-style ranges from scmutil.revrange()
Yuya Nishihara <yuya@tcha.org>
parents:
25819
diff
changeset
|
102 |
11275 | 103 pos, l = 0, len(program) |
104 while pos < l: | |
31441
80c8a6db450d
py3: use bytestr wrapper in revsetlang.tokenize()
Yuya Nishihara <yuya@tcha.org>
parents:
31440
diff
changeset
|
105 c = program[pos] |
11275 | 106 if c.isspace(): # skip inter-token whitespace |
107 pass | |
11278
7df88cdf47fd
revset: add support for prefix and suffix versions of : and ::
Matt Mackall <mpm@selenic.com>
parents:
11275
diff
changeset
|
108 elif c == ':' and program[pos:pos + 2] == '::': # look ahead carefully |
11289
4215ce511134
revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents:
11284
diff
changeset
|
109 yield ('::', None, pos) |
11278
7df88cdf47fd
revset: add support for prefix and suffix versions of : and ::
Matt Mackall <mpm@selenic.com>
parents:
11275
diff
changeset
|
110 pos += 1 # skip ahead |
11275 | 111 elif c == '.' and program[pos:pos + 2] == '..': # look ahead carefully |
11289
4215ce511134
revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents:
11284
diff
changeset
|
112 yield ('..', None, pos) |
11275 | 113 pos += 1 # skip ahead |
23742
3a4d8a6ce432
revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23729
diff
changeset
|
114 elif c == '#' and program[pos:pos + 2] == '##': # look ahead carefully |
3a4d8a6ce432
revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23729
diff
changeset
|
115 yield ('##', None, pos) |
3a4d8a6ce432
revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23729
diff
changeset
|
116 pos += 1 # skip ahead |
31384
fac5cd3b8673
py3: make set of revset operators and quotes in bytes
Yuya Nishihara <yuya@tcha.org>
parents:
31383
diff
changeset
|
117 elif c in _simpleopletters: # handle simple operators |
11289
4215ce511134
revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents:
11284
diff
changeset
|
118 yield (c, None, pos) |
31384
fac5cd3b8673
py3: make set of revset operators and quotes in bytes
Yuya Nishihara <yuya@tcha.org>
parents:
31383
diff
changeset
|
119 elif (c in _quoteletters or c == 'r' and |
12408
78a97859b90d
revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents:
12401
diff
changeset
|
120 program[pos:pos + 2] in ("r'", 'r"')): # handle quoted strings |
78a97859b90d
revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents:
12401
diff
changeset
|
121 if c == 'r': |
78a97859b90d
revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents:
12401
diff
changeset
|
122 pos += 1 |
31441
80c8a6db450d
py3: use bytestr wrapper in revsetlang.tokenize()
Yuya Nishihara <yuya@tcha.org>
parents:
31440
diff
changeset
|
123 c = program[pos] |
12408
78a97859b90d
revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents:
12401
diff
changeset
|
124 decode = lambda x: x |
78a97859b90d
revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents:
12401
diff
changeset
|
125 else: |
26232
43f9976346e9
revset: handle error of string unescaping
Yuya Nishihara <yuya@tcha.org>
parents:
26212
diff
changeset
|
126 decode = parser.unescapestr |
11275 | 127 pos += 1 |
128 s = pos | |
129 while pos < l: # find closing quote | |
31441
80c8a6db450d
py3: use bytestr wrapper in revsetlang.tokenize()
Yuya Nishihara <yuya@tcha.org>
parents:
31440
diff
changeset
|
130 d = program[pos] |
11275 | 131 if d == '\\': # skip over escaped characters |
132 pos += 2 | |
133 continue | |
134 if d == c: | |
12408
78a97859b90d
revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents:
12401
diff
changeset
|
135 yield ('string', decode(program[s:pos]), s) |
11275 | 136 break |
137 pos += 1 | |
138 else: | |
11383
de544774ebea
revset: all your error messages are belong to _
Martin Geisler <mg@lazybytes.net>
parents:
11349
diff
changeset
|
139 raise error.ParseError(_("unterminated string"), s) |
16683 | 140 # gather up a symbol/keyword |
23842
91dbb98b3513
revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23836
diff
changeset
|
141 elif c in syminitletters: |
11275 | 142 s = pos |
143 pos += 1 | |
144 while pos < l: # find end of symbol | |
31441
80c8a6db450d
py3: use bytestr wrapper in revsetlang.tokenize()
Yuya Nishihara <yuya@tcha.org>
parents:
31440
diff
changeset
|
145 d = program[pos] |
23842
91dbb98b3513
revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23836
diff
changeset
|
146 if d not in symletters: |
11275 | 147 break |
31441
80c8a6db450d
py3: use bytestr wrapper in revsetlang.tokenize()
Yuya Nishihara <yuya@tcha.org>
parents:
31440
diff
changeset
|
148 if d == '.' and program[pos - 1] == '.': # special case for .. |
11275 | 149 pos -= 1 |
150 break | |
151 pos += 1 | |
152 sym = program[s:pos] | |
153 if sym in keywords: # operator keywords | |
11289
4215ce511134
revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents:
11284
diff
changeset
|
154 yield (sym, None, s) |
20780
403f1f73d30f
revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents:
20779
diff
changeset
|
155 elif '-' in sym: |
403f1f73d30f
revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents:
20779
diff
changeset
|
156 # some jerk gave us foo-bar-baz, try to check if it's a symbol |
403f1f73d30f
revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents:
20779
diff
changeset
|
157 if lookup and lookup(sym): |
403f1f73d30f
revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents:
20779
diff
changeset
|
158 # looks like a real symbol |
403f1f73d30f
revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents:
20779
diff
changeset
|
159 yield ('symbol', sym, s) |
403f1f73d30f
revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents:
20779
diff
changeset
|
160 else: |
403f1f73d30f
revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents:
20779
diff
changeset
|
161 # looks like an expression |
403f1f73d30f
revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents:
20779
diff
changeset
|
162 parts = sym.split('-') |
403f1f73d30f
revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents:
20779
diff
changeset
|
163 for p in parts[:-1]: |
403f1f73d30f
revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents:
20779
diff
changeset
|
164 if p: # possible consecutive - |
403f1f73d30f
revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents:
20779
diff
changeset
|
165 yield ('symbol', p, s) |
403f1f73d30f
revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents:
20779
diff
changeset
|
166 s += len(p) |
403f1f73d30f
revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents:
20779
diff
changeset
|
167 yield ('-', None, pos) |
403f1f73d30f
revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents:
20779
diff
changeset
|
168 s += 1 |
403f1f73d30f
revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents:
20779
diff
changeset
|
169 if parts[-1]: # possible trailing - |
403f1f73d30f
revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents:
20779
diff
changeset
|
170 yield ('symbol', parts[-1], s) |
11275 | 171 else: |
11289
4215ce511134
revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents:
11284
diff
changeset
|
172 yield ('symbol', sym, s) |
11275 | 173 pos -= 1 |
174 else: | |
24708
fb47816e1a9c
revsets: more informative syntax error message
Ryan McElroy <rmcelroy@fb.com>
parents:
24518
diff
changeset
|
175 raise error.ParseError(_("syntax error in revset '%s'") % |
fb47816e1a9c
revsets: more informative syntax error message
Ryan McElroy <rmcelroy@fb.com>
parents:
24518
diff
changeset
|
176 program, pos) |
11275 | 177 pos += 1 |
11289
4215ce511134
revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents:
11284
diff
changeset
|
178 yield ('end', None, pos) |
11275 | 179 |
180 # helpers | |
181 | |
30802
5eb3e4568c94
revset: add default value to getinteger() helper
Yuya Nishihara <yuya@tcha.org>
parents:
30801
diff
changeset
|
182 _notset = object() |
5eb3e4568c94
revset: add default value to getinteger() helper
Yuya Nishihara <yuya@tcha.org>
parents:
30801
diff
changeset
|
183 |
29441
9e8d258708bb
revset: check invalid function syntax "func-name"() explicitly
Yuya Nishihara <yuya@tcha.org>
parents:
29425
diff
changeset
|
184 def getsymbol(x): |
9e8d258708bb
revset: check invalid function syntax "func-name"() explicitly
Yuya Nishihara <yuya@tcha.org>
parents:
29425
diff
changeset
|
185 if x and x[0] == 'symbol': |
9e8d258708bb
revset: check invalid function syntax "func-name"() explicitly
Yuya Nishihara <yuya@tcha.org>
parents:
29425
diff
changeset
|
186 return x[1] |
9e8d258708bb
revset: check invalid function syntax "func-name"() explicitly
Yuya Nishihara <yuya@tcha.org>
parents:
29425
diff
changeset
|
187 raise error.ParseError(_('not a symbol')) |
9e8d258708bb
revset: check invalid function syntax "func-name"() explicitly
Yuya Nishihara <yuya@tcha.org>
parents:
29425
diff
changeset
|
188 |
11275 | 189 def getstring(x, err): |
11406
42408cd43f55
revset: fix up contains/getstring when no args passed
Matt Mackall <mpm@selenic.com>
parents:
11404
diff
changeset
|
190 if x and (x[0] == 'string' or x[0] == 'symbol'): |
11275 | 191 return x[1] |
11289
4215ce511134
revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents:
11284
diff
changeset
|
192 raise error.ParseError(err) |
11275 | 193 |
30802
5eb3e4568c94
revset: add default value to getinteger() helper
Yuya Nishihara <yuya@tcha.org>
parents:
30801
diff
changeset
|
194 def getinteger(x, err, default=_notset): |
5eb3e4568c94
revset: add default value to getinteger() helper
Yuya Nishihara <yuya@tcha.org>
parents:
30801
diff
changeset
|
195 if not x and default is not _notset: |
5eb3e4568c94
revset: add default value to getinteger() helper
Yuya Nishihara <yuya@tcha.org>
parents:
30801
diff
changeset
|
196 return default |
30801
67ee7874e53b
revset: factor out getinteger() helper
Yuya Nishihara <yuya@tcha.org>
parents:
30800
diff
changeset
|
197 try: |
67ee7874e53b
revset: factor out getinteger() helper
Yuya Nishihara <yuya@tcha.org>
parents:
30800
diff
changeset
|
198 return int(getstring(x, err)) |
67ee7874e53b
revset: factor out getinteger() helper
Yuya Nishihara <yuya@tcha.org>
parents:
30800
diff
changeset
|
199 except ValueError: |
67ee7874e53b
revset: factor out getinteger() helper
Yuya Nishihara <yuya@tcha.org>
parents:
30800
diff
changeset
|
200 raise error.ParseError(err) |
67ee7874e53b
revset: factor out getinteger() helper
Yuya Nishihara <yuya@tcha.org>
parents:
30800
diff
changeset
|
201 |
31997
11f501f0a213
revsetlang: add a getboolean helper function
Denis Laxalde <denis@laxalde.org>
parents:
31800
diff
changeset
|
202 def getboolean(x, err): |
11f501f0a213
revsetlang: add a getboolean helper function
Denis Laxalde <denis@laxalde.org>
parents:
31800
diff
changeset
|
203 value = util.parsebool(getsymbol(x)) |
11f501f0a213
revsetlang: add a getboolean helper function
Denis Laxalde <denis@laxalde.org>
parents:
31800
diff
changeset
|
204 if value is not None: |
11f501f0a213
revsetlang: add a getboolean helper function
Denis Laxalde <denis@laxalde.org>
parents:
31800
diff
changeset
|
205 return value |
11f501f0a213
revsetlang: add a getboolean helper function
Denis Laxalde <denis@laxalde.org>
parents:
31800
diff
changeset
|
206 raise error.ParseError(err) |
11f501f0a213
revsetlang: add a getboolean helper function
Denis Laxalde <denis@laxalde.org>
parents:
31800
diff
changeset
|
207 |
11275 | 208 def getlist(x): |
209 if not x: | |
210 return [] | |
211 if x[0] == 'list': | |
27987
b19d8d5d6b51
revset: flatten chained 'list' operations (aka function args) (issue5072)
Yuya Nishihara <yuya@tcha.org>
parents:
27945
diff
changeset
|
212 return list(x[1:]) |
11275 | 213 return [x] |
214 | |
30804
4227f80f72b2
revset: abuse x:y syntax to specify line range of followlines()
Yuya Nishihara <yuya@tcha.org>
parents:
30803
diff
changeset
|
215 def getrange(x, err): |
4227f80f72b2
revset: abuse x:y syntax to specify line range of followlines()
Yuya Nishihara <yuya@tcha.org>
parents:
30803
diff
changeset
|
216 if not x: |
4227f80f72b2
revset: abuse x:y syntax to specify line range of followlines()
Yuya Nishihara <yuya@tcha.org>
parents:
30803
diff
changeset
|
217 raise error.ParseError(err) |
4227f80f72b2
revset: abuse x:y syntax to specify line range of followlines()
Yuya Nishihara <yuya@tcha.org>
parents:
30803
diff
changeset
|
218 op = x[0] |
4227f80f72b2
revset: abuse x:y syntax to specify line range of followlines()
Yuya Nishihara <yuya@tcha.org>
parents:
30803
diff
changeset
|
219 if op == 'range': |
4227f80f72b2
revset: abuse x:y syntax to specify line range of followlines()
Yuya Nishihara <yuya@tcha.org>
parents:
30803
diff
changeset
|
220 return x[1], x[2] |
4227f80f72b2
revset: abuse x:y syntax to specify line range of followlines()
Yuya Nishihara <yuya@tcha.org>
parents:
30803
diff
changeset
|
221 elif op == 'rangepre': |
4227f80f72b2
revset: abuse x:y syntax to specify line range of followlines()
Yuya Nishihara <yuya@tcha.org>
parents:
30803
diff
changeset
|
222 return None, x[1] |
4227f80f72b2
revset: abuse x:y syntax to specify line range of followlines()
Yuya Nishihara <yuya@tcha.org>
parents:
30803
diff
changeset
|
223 elif op == 'rangepost': |
4227f80f72b2
revset: abuse x:y syntax to specify line range of followlines()
Yuya Nishihara <yuya@tcha.org>
parents:
30803
diff
changeset
|
224 return x[1], None |
4227f80f72b2
revset: abuse x:y syntax to specify line range of followlines()
Yuya Nishihara <yuya@tcha.org>
parents:
30803
diff
changeset
|
225 elif op == 'rangeall': |
4227f80f72b2
revset: abuse x:y syntax to specify line range of followlines()
Yuya Nishihara <yuya@tcha.org>
parents:
30803
diff
changeset
|
226 return None, None |
4227f80f72b2
revset: abuse x:y syntax to specify line range of followlines()
Yuya Nishihara <yuya@tcha.org>
parents:
30803
diff
changeset
|
227 raise error.ParseError(err) |
4227f80f72b2
revset: abuse x:y syntax to specify line range of followlines()
Yuya Nishihara <yuya@tcha.org>
parents:
30803
diff
changeset
|
228 |
11339
744d5b73f776
revset: improve filter argument handling
Matt Mackall <mpm@selenic.com>
parents:
11304
diff
changeset
|
229 def getargs(x, min, max, err): |
11275 | 230 l = getlist(x) |
16161
5a627b49b4d9
graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents:
16096
diff
changeset
|
231 if len(l) < min or (max >= 0 and len(l) > max): |
11289
4215ce511134
revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents:
11284
diff
changeset
|
232 raise error.ParseError(err) |
11275 | 233 return l |
234 | |
25767
026105c442d7
revset: rename getkwargs() to getargsdict()
Yuya Nishihara <yuya@tcha.org>
parents:
25766
diff
changeset
|
235 def getargsdict(x, funcname, keys): |
30753
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30719
diff
changeset
|
236 return parser.buildargsdict(getlist(x), funcname, parser.splitargspec(keys), |
25705
48919d246a47
revset: add function to build dict of positional and keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents:
25704
diff
changeset
|
237 keyvaluenode='keyvalue', keynode='symbol') |
48919d246a47
revset: add function to build dict of positional and keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents:
25704
diff
changeset
|
238 |
29930
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
239 # Constants for ordering requirement, used in _analyze(): |
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
240 # |
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
241 # If 'define', any nested functions and operations can change the ordering of |
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
242 # the entries in the set. If 'follow', any nested functions and operations |
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
243 # should take the ordering specified by the first operand to the '&' operator. |
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
244 # |
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
245 # For instance, |
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
246 # |
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
247 # X & (Y | Z) |
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
248 # ^ ^^^^^^^ |
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
249 # | follow |
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
250 # define |
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
251 # |
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
252 # will be evaluated as 'or(y(x()), z(x()))', where 'x()' can change the order |
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
253 # of the entries in the set, but 'y()', 'z()' and 'or()' shouldn't. |
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
254 # |
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
255 # 'any' means the order doesn't matter. For instance, |
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
256 # |
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
257 # X & !Y |
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
258 # ^ |
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
259 # any |
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
260 # |
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
261 # 'y()' can either enforce its ordering requirement or take the ordering |
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
262 # specified by 'x()' because 'not()' doesn't care the order. |
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
263 # |
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
264 # Transition of ordering requirement: |
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
265 # |
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
266 # 1. starts with 'define' |
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
267 # 2. shifts to 'follow' by 'x & y' |
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
268 # 3. changes back to 'define' on function call 'f(x)' or function-like |
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
269 # operation 'x (f) y' because 'f' may have its own ordering requirement |
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
270 # for 'x' and 'y' (e.g. 'first(x)') |
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
271 # |
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
272 anyorder = 'any' # don't care the order |
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
273 defineorder = 'define' # should define the order |
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
274 followorder = 'follow' # must follow the current order |
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
275 |
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
276 # transition table for 'x & y', from the current expression 'x' to 'y' |
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
277 _tofolloworder = { |
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
278 anyorder: anyorder, |
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
279 defineorder: followorder, |
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
280 followorder: followorder, |
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
281 } |
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
282 |
29117
7828cadd2873
revset: construct arguments of only() against matched tree
Yuya Nishihara <yuya@tcha.org>
parents:
29116
diff
changeset
|
283 def _matchonly(revs, bases): |
7828cadd2873
revset: construct arguments of only() against matched tree
Yuya Nishihara <yuya@tcha.org>
parents:
29116
diff
changeset
|
284 """ |
7828cadd2873
revset: construct arguments of only() against matched tree
Yuya Nishihara <yuya@tcha.org>
parents:
29116
diff
changeset
|
285 >>> f = lambda *args: _matchonly(*map(parse, args)) |
7828cadd2873
revset: construct arguments of only() against matched tree
Yuya Nishihara <yuya@tcha.org>
parents:
29116
diff
changeset
|
286 >>> f('ancestors(A)', 'not ancestors(B)') |
7828cadd2873
revset: construct arguments of only() against matched tree
Yuya Nishihara <yuya@tcha.org>
parents:
29116
diff
changeset
|
287 ('list', ('symbol', 'A'), ('symbol', 'B')) |
7828cadd2873
revset: construct arguments of only() against matched tree
Yuya Nishihara <yuya@tcha.org>
parents:
29116
diff
changeset
|
288 """ |
7828cadd2873
revset: construct arguments of only() against matched tree
Yuya Nishihara <yuya@tcha.org>
parents:
29116
diff
changeset
|
289 if (revs is not None |
29116
0c9b05dae010
revset: unnest isonly() closure from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29098
diff
changeset
|
290 and revs[0] == 'func' |
29441
9e8d258708bb
revset: check invalid function syntax "func-name"() explicitly
Yuya Nishihara <yuya@tcha.org>
parents:
29425
diff
changeset
|
291 and getsymbol(revs[1]) == 'ancestors' |
29116
0c9b05dae010
revset: unnest isonly() closure from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29098
diff
changeset
|
292 and bases is not None |
0c9b05dae010
revset: unnest isonly() closure from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29098
diff
changeset
|
293 and bases[0] == 'not' |
0c9b05dae010
revset: unnest isonly() closure from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29098
diff
changeset
|
294 and bases[1][0] == 'func' |
29441
9e8d258708bb
revset: check invalid function syntax "func-name"() explicitly
Yuya Nishihara <yuya@tcha.org>
parents:
29425
diff
changeset
|
295 and getsymbol(bases[1][1]) == 'ancestors'): |
29117
7828cadd2873
revset: construct arguments of only() against matched tree
Yuya Nishihara <yuya@tcha.org>
parents:
29116
diff
changeset
|
296 return ('list', revs[2], bases[1][2]) |
29116
0c9b05dae010
revset: unnest isonly() closure from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29098
diff
changeset
|
297 |
29769
abe4eecc3253
revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents:
29767
diff
changeset
|
298 def _fixops(x): |
abe4eecc3253
revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents:
29767
diff
changeset
|
299 """Rewrite raw parsed tree to resolve ambiguous syntax which cannot be |
abe4eecc3253
revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents:
29767
diff
changeset
|
300 handled well by our simple top-down parser""" |
abe4eecc3253
revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents:
29767
diff
changeset
|
301 if not isinstance(x, tuple): |
abe4eecc3253
revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents:
29767
diff
changeset
|
302 return x |
abe4eecc3253
revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents:
29767
diff
changeset
|
303 |
abe4eecc3253
revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents:
29767
diff
changeset
|
304 op = x[0] |
abe4eecc3253
revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents:
29767
diff
changeset
|
305 if op == 'parent': |
abe4eecc3253
revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents:
29767
diff
changeset
|
306 # x^:y means (x^) : y, not x ^ (:y) |
29770
9c51a5de76db
revset: also parse x^: as (x^):
Yuya Nishihara <yuya@tcha.org>
parents:
29769
diff
changeset
|
307 # x^: means (x^) :, not x ^ (:) |
29769
abe4eecc3253
revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents:
29767
diff
changeset
|
308 post = ('parentpost', x[1]) |
abe4eecc3253
revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents:
29767
diff
changeset
|
309 if x[2][0] == 'dagrangepre': |
abe4eecc3253
revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents:
29767
diff
changeset
|
310 return _fixops(('dagrange', post, x[2][1])) |
abe4eecc3253
revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents:
29767
diff
changeset
|
311 elif x[2][0] == 'rangepre': |
abe4eecc3253
revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents:
29767
diff
changeset
|
312 return _fixops(('range', post, x[2][1])) |
29770
9c51a5de76db
revset: also parse x^: as (x^):
Yuya Nishihara <yuya@tcha.org>
parents:
29769
diff
changeset
|
313 elif x[2][0] == 'rangeall': |
9c51a5de76db
revset: also parse x^: as (x^):
Yuya Nishihara <yuya@tcha.org>
parents:
29769
diff
changeset
|
314 return _fixops(('rangepost', post)) |
29929
b3845cab4ddc
revset: wrap arguments of 'or' by 'list' node
Yuya Nishihara <yuya@tcha.org>
parents:
29922
diff
changeset
|
315 elif op == 'or': |
b3845cab4ddc
revset: wrap arguments of 'or' by 'list' node
Yuya Nishihara <yuya@tcha.org>
parents:
29922
diff
changeset
|
316 # make number of arguments deterministic: |
b3845cab4ddc
revset: wrap arguments of 'or' by 'list' node
Yuya Nishihara <yuya@tcha.org>
parents:
29922
diff
changeset
|
317 # x + y + z -> (or x y z) -> (or (list x y z)) |
b3845cab4ddc
revset: wrap arguments of 'or' by 'list' node
Yuya Nishihara <yuya@tcha.org>
parents:
29922
diff
changeset
|
318 return (op, _fixops(('list',) + x[1:])) |
29769
abe4eecc3253
revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents:
29767
diff
changeset
|
319 |
abe4eecc3253
revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents:
29767
diff
changeset
|
320 return (op,) + tuple(_fixops(y) for y in x[1:]) |
abe4eecc3253
revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents:
29767
diff
changeset
|
321 |
29930
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
322 def _analyze(x, order): |
29904
e4b4168a4f1c
revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29898
diff
changeset
|
323 if x is None: |
e4b4168a4f1c
revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29898
diff
changeset
|
324 return x |
e4b4168a4f1c
revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29898
diff
changeset
|
325 |
e4b4168a4f1c
revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29898
diff
changeset
|
326 op = x[0] |
e4b4168a4f1c
revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29898
diff
changeset
|
327 if op == 'minus': |
29930
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
328 return _analyze(('and', x[1], ('not', x[2])), order) |
29904
e4b4168a4f1c
revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29898
diff
changeset
|
329 elif op == 'only': |
e4b4168a4f1c
revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29898
diff
changeset
|
330 t = ('func', ('symbol', 'only'), ('list', x[1], x[2])) |
29930
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
331 return _analyze(t, order) |
29904
e4b4168a4f1c
revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29898
diff
changeset
|
332 elif op == 'onlypost': |
29930
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
333 return _analyze(('func', ('symbol', 'only'), x[1]), order) |
29904
e4b4168a4f1c
revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29898
diff
changeset
|
334 elif op == 'dagrangepre': |
29930
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
335 return _analyze(('func', ('symbol', 'ancestors'), x[1]), order) |
29904
e4b4168a4f1c
revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29898
diff
changeset
|
336 elif op == 'dagrangepost': |
29930
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
337 return _analyze(('func', ('symbol', 'descendants'), x[1]), order) |
29904
e4b4168a4f1c
revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29898
diff
changeset
|
338 elif op == 'negate': |
e4b4168a4f1c
revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29898
diff
changeset
|
339 s = getstring(x[1], _("can't negate that")) |
29930
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
340 return _analyze(('string', '-' + s), order) |
29904
e4b4168a4f1c
revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29898
diff
changeset
|
341 elif op in ('string', 'symbol'): |
e4b4168a4f1c
revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29898
diff
changeset
|
342 return x |
e4b4168a4f1c
revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29898
diff
changeset
|
343 elif op == 'and': |
29930
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
344 ta = _analyze(x[1], order) |
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
345 tb = _analyze(x[2], _tofolloworder[order]) |
29932
09a84e747c88
revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents:
29931
diff
changeset
|
346 return (op, ta, tb, order) |
29904
e4b4168a4f1c
revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29898
diff
changeset
|
347 elif op == 'or': |
29932
09a84e747c88
revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents:
29931
diff
changeset
|
348 return (op, _analyze(x[1], order), order) |
29904
e4b4168a4f1c
revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29898
diff
changeset
|
349 elif op == 'not': |
29932
09a84e747c88
revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents:
29931
diff
changeset
|
350 return (op, _analyze(x[1], anyorder), order) |
30803
d389f19f14aa
revset: do not transform range* operators in parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
30802
diff
changeset
|
351 elif op == 'rangeall': |
d389f19f14aa
revset: do not transform range* operators in parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
30802
diff
changeset
|
352 return (op, None, order) |
d389f19f14aa
revset: do not transform range* operators in parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
30802
diff
changeset
|
353 elif op in ('rangepre', 'rangepost', 'parentpost'): |
29932
09a84e747c88
revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents:
29931
diff
changeset
|
354 return (op, _analyze(x[1], defineorder), order) |
29904
e4b4168a4f1c
revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29898
diff
changeset
|
355 elif op == 'group': |
29930
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
356 return _analyze(x[1], order) |
29904
e4b4168a4f1c
revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29898
diff
changeset
|
357 elif op in ('dagrange', 'range', 'parent', 'ancestor'): |
29930
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
358 ta = _analyze(x[1], defineorder) |
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
359 tb = _analyze(x[2], defineorder) |
29932
09a84e747c88
revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents:
29931
diff
changeset
|
360 return (op, ta, tb, order) |
29904
e4b4168a4f1c
revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29898
diff
changeset
|
361 elif op == 'list': |
29930
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
362 return (op,) + tuple(_analyze(y, order) for y in x[1:]) |
29904
e4b4168a4f1c
revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29898
diff
changeset
|
363 elif op == 'keyvalue': |
29930
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
364 return (op, x[1], _analyze(x[2], order)) |
29904
e4b4168a4f1c
revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29898
diff
changeset
|
365 elif op == 'func': |
29943
80c86b9bb40b
revset: forward ordering requirement to argument of present()
Yuya Nishihara <yuya@tcha.org>
parents:
29935
diff
changeset
|
366 f = getsymbol(x[1]) |
80c86b9bb40b
revset: forward ordering requirement to argument of present()
Yuya Nishihara <yuya@tcha.org>
parents:
29935
diff
changeset
|
367 d = defineorder |
80c86b9bb40b
revset: forward ordering requirement to argument of present()
Yuya Nishihara <yuya@tcha.org>
parents:
29935
diff
changeset
|
368 if f == 'present': |
80c86b9bb40b
revset: forward ordering requirement to argument of present()
Yuya Nishihara <yuya@tcha.org>
parents:
29935
diff
changeset
|
369 # 'present(set)' is known to return the argument set with no |
80c86b9bb40b
revset: forward ordering requirement to argument of present()
Yuya Nishihara <yuya@tcha.org>
parents:
29935
diff
changeset
|
370 # modification, so forward the current order to its argument |
80c86b9bb40b
revset: forward ordering requirement to argument of present()
Yuya Nishihara <yuya@tcha.org>
parents:
29935
diff
changeset
|
371 d = order |
80c86b9bb40b
revset: forward ordering requirement to argument of present()
Yuya Nishihara <yuya@tcha.org>
parents:
29935
diff
changeset
|
372 return (op, x[1], _analyze(x[2], d), order) |
29904
e4b4168a4f1c
revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29898
diff
changeset
|
373 raise ValueError('invalid operator %r' % op) |
e4b4168a4f1c
revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29898
diff
changeset
|
374 |
29930
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
375 def analyze(x, order=defineorder): |
29905
371c2a39eead
revset: make analyze() a separate step from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29904
diff
changeset
|
376 """Transform raw parsed tree to evaluatable tree which can be fed to |
371c2a39eead
revset: make analyze() a separate step from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29904
diff
changeset
|
377 optimize() or getset() |
371c2a39eead
revset: make analyze() a separate step from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29904
diff
changeset
|
378 |
371c2a39eead
revset: make analyze() a separate step from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29904
diff
changeset
|
379 All pseudo operations should be mapped to real operations or functions |
371c2a39eead
revset: make analyze() a separate step from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29904
diff
changeset
|
380 defined in methods or symbols table respectively. |
29930
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
381 |
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
382 'order' specifies how the current expression 'x' is ordered (see the |
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
383 constants defined above.) |
29905
371c2a39eead
revset: make analyze() a separate step from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29904
diff
changeset
|
384 """ |
29930
90455e7bf543
revset: infer ordering flag to teach if operation should define/follow order
Yuya Nishihara <yuya@tcha.org>
parents:
29929
diff
changeset
|
385 return _analyze(x, order) |
29905
371c2a39eead
revset: make analyze() a separate step from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29904
diff
changeset
|
386 |
29119
a032ebea4e97
revset: factor out public optimize() function from recursion
Yuya Nishihara <yuya@tcha.org>
parents:
29118
diff
changeset
|
387 def _optimize(x, small): |
13031
3da456d0c885
code style: prefer 'is' and 'is not' tests with singletons
Martin Geisler <mg@aragost.com>
parents:
12936
diff
changeset
|
388 if x is None: |
11279
62ccf4cd6e7f
revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents:
11278
diff
changeset
|
389 return 0, x |
62ccf4cd6e7f
revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents:
11278
diff
changeset
|
390 |
11275 | 391 smallbonus = 1 |
392 if small: | |
393 smallbonus = .5 | |
394 | |
395 op = x[0] | |
29904
e4b4168a4f1c
revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29898
diff
changeset
|
396 if op in ('string', 'symbol'): |
11279
62ccf4cd6e7f
revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents:
11278
diff
changeset
|
397 return smallbonus, x # single revisions are small |
16859
eeb464ed7275
revset: drop unreachable code
Bryan O'Sullivan <bryano@fb.com>
parents:
16838
diff
changeset
|
398 elif op == 'and': |
29119
a032ebea4e97
revset: factor out public optimize() function from recursion
Yuya Nishihara <yuya@tcha.org>
parents:
29118
diff
changeset
|
399 wa, ta = _optimize(x[1], True) |
a032ebea4e97
revset: factor out public optimize() function from recursion
Yuya Nishihara <yuya@tcha.org>
parents:
29118
diff
changeset
|
400 wb, tb = _optimize(x[2], True) |
29932
09a84e747c88
revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents:
29931
diff
changeset
|
401 order = x[3] |
29116
0c9b05dae010
revset: unnest isonly() closure from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29098
diff
changeset
|
402 w = min(wa, wb) |
20499
2efd608473fb
revset: optimize missing ancestor expressions
Siddharth Agarwal <sid0@fb.com>
parents:
20498
diff
changeset
|
403 |
2efd608473fb
revset: optimize missing ancestor expressions
Siddharth Agarwal <sid0@fb.com>
parents:
20498
diff
changeset
|
404 # (::x and not ::y)/(not ::y and ::x) have a fast path |
29117
7828cadd2873
revset: construct arguments of only() against matched tree
Yuya Nishihara <yuya@tcha.org>
parents:
29116
diff
changeset
|
405 tm = _matchonly(ta, tb) or _matchonly(tb, ta) |
7828cadd2873
revset: construct arguments of only() against matched tree
Yuya Nishihara <yuya@tcha.org>
parents:
29116
diff
changeset
|
406 if tm: |
29932
09a84e747c88
revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents:
29931
diff
changeset
|
407 return w, ('func', ('symbol', 'only'), tm, order) |
20499
2efd608473fb
revset: optimize missing ancestor expressions
Siddharth Agarwal <sid0@fb.com>
parents:
20498
diff
changeset
|
408 |
28217
d2ac8b57a75d
revset: use smartset minus operator
Durham Goode <durham@fb.com>
parents:
28139
diff
changeset
|
409 if tb is not None and tb[0] == 'not': |
29932
09a84e747c88
revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents:
29931
diff
changeset
|
410 return wa, ('difference', ta, tb[1], order) |
28217
d2ac8b57a75d
revset: use smartset minus operator
Durham Goode <durham@fb.com>
parents:
28139
diff
changeset
|
411 |
11279
62ccf4cd6e7f
revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents:
11278
diff
changeset
|
412 if wa > wb: |
29932
09a84e747c88
revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents:
29931
diff
changeset
|
413 return w, (op, tb, ta, order) |
09a84e747c88
revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents:
29931
diff
changeset
|
414 return w, (op, ta, tb, order) |
11279
62ccf4cd6e7f
revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents:
11278
diff
changeset
|
415 elif op == 'or': |
25343
7fbef7932af9
revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents:
25342
diff
changeset
|
416 # fast path for machine-generated expression, that is likely to have |
7fbef7932af9
revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents:
25342
diff
changeset
|
417 # lots of trivial revisions: 'a + b + c()' to '_list(a b) + c()' |
29932
09a84e747c88
revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents:
29931
diff
changeset
|
418 order = x[2] |
25343
7fbef7932af9
revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents:
25342
diff
changeset
|
419 ws, ts, ss = [], [], [] |
7fbef7932af9
revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents:
25342
diff
changeset
|
420 def flushss(): |
7fbef7932af9
revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents:
25342
diff
changeset
|
421 if not ss: |
7fbef7932af9
revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents:
25342
diff
changeset
|
422 return |
7fbef7932af9
revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents:
25342
diff
changeset
|
423 if len(ss) == 1: |
7fbef7932af9
revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents:
25342
diff
changeset
|
424 w, t = ss[0] |
7fbef7932af9
revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents:
25342
diff
changeset
|
425 else: |
7fbef7932af9
revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents:
25342
diff
changeset
|
426 s = '\0'.join(t[1] for w, t in ss) |
29932
09a84e747c88
revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents:
29931
diff
changeset
|
427 y = ('func', ('symbol', '_list'), ('string', s), order) |
29119
a032ebea4e97
revset: factor out public optimize() function from recursion
Yuya Nishihara <yuya@tcha.org>
parents:
29118
diff
changeset
|
428 w, t = _optimize(y, False) |
25343
7fbef7932af9
revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents:
25342
diff
changeset
|
429 ws.append(w) |
7fbef7932af9
revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents:
25342
diff
changeset
|
430 ts.append(t) |
7fbef7932af9
revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents:
25342
diff
changeset
|
431 del ss[:] |
29929
b3845cab4ddc
revset: wrap arguments of 'or' by 'list' node
Yuya Nishihara <yuya@tcha.org>
parents:
29922
diff
changeset
|
432 for y in getlist(x[1]): |
29119
a032ebea4e97
revset: factor out public optimize() function from recursion
Yuya Nishihara <yuya@tcha.org>
parents:
29118
diff
changeset
|
433 w, t = _optimize(y, False) |
25996
b12e00a05d57
revset: prevent crash caused by empty group expression while optimizing "or"
Yuya Nishihara <yuya@tcha.org>
parents:
25995
diff
changeset
|
434 if t is not None and (t[0] == 'string' or t[0] == 'symbol'): |
25343
7fbef7932af9
revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents:
25342
diff
changeset
|
435 ss.append((w, t)) |
7fbef7932af9
revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents:
25342
diff
changeset
|
436 continue |
7fbef7932af9
revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents:
25342
diff
changeset
|
437 flushss() |
7fbef7932af9
revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents:
25342
diff
changeset
|
438 ws.append(w) |
7fbef7932af9
revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents:
25342
diff
changeset
|
439 ts.append(t) |
7fbef7932af9
revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents:
25342
diff
changeset
|
440 flushss() |
7fbef7932af9
revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents:
25342
diff
changeset
|
441 if len(ts) == 1: |
7fbef7932af9
revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents:
25342
diff
changeset
|
442 return ws[0], ts[0] # 'or' operation is fully optimized out |
31800
c63cb2d10d6d
revsetlang: enable optimization of 'x + y' expression
Yuya Nishihara <yuya@tcha.org>
parents:
31636
diff
changeset
|
443 if order != defineorder: |
c63cb2d10d6d
revsetlang: enable optimization of 'x + y' expression
Yuya Nishihara <yuya@tcha.org>
parents:
31636
diff
changeset
|
444 # reorder by weight only when f(a + b) == f(b + a) |
c63cb2d10d6d
revsetlang: enable optimization of 'x + y' expression
Yuya Nishihara <yuya@tcha.org>
parents:
31636
diff
changeset
|
445 ts = [wt[1] for wt in sorted(zip(ws, ts), key=lambda wt: wt[0])] |
29932
09a84e747c88
revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents:
29931
diff
changeset
|
446 return max(ws), (op, ('list',) + tuple(ts), order) |
11275 | 447 elif op == 'not': |
25191
08d1ef09ed37
revset: optimize not public revset
Laurent Charignon <lcharignon@fb.com>
parents:
25149
diff
changeset
|
448 # Optimize not public() to _notpublic() because we have a fast version |
29932
09a84e747c88
revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents:
29931
diff
changeset
|
449 if x[1][:3] == ('func', ('symbol', 'public'), None): |
09a84e747c88
revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents:
29931
diff
changeset
|
450 order = x[1][3] |
09a84e747c88
revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents:
29931
diff
changeset
|
451 newsym = ('func', ('symbol', '_notpublic'), None, order) |
29119
a032ebea4e97
revset: factor out public optimize() function from recursion
Yuya Nishihara <yuya@tcha.org>
parents:
29118
diff
changeset
|
452 o = _optimize(newsym, not small) |
25191
08d1ef09ed37
revset: optimize not public revset
Laurent Charignon <lcharignon@fb.com>
parents:
25149
diff
changeset
|
453 return o[0], o[1] |
08d1ef09ed37
revset: optimize not public revset
Laurent Charignon <lcharignon@fb.com>
parents:
25149
diff
changeset
|
454 else: |
29119
a032ebea4e97
revset: factor out public optimize() function from recursion
Yuya Nishihara <yuya@tcha.org>
parents:
29118
diff
changeset
|
455 o = _optimize(x[1], not small) |
29932
09a84e747c88
revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents:
29931
diff
changeset
|
456 order = x[2] |
09a84e747c88
revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents:
29931
diff
changeset
|
457 return o[0], (op, o[1], order) |
30803
d389f19f14aa
revset: do not transform range* operators in parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
30802
diff
changeset
|
458 elif op == 'rangeall': |
d389f19f14aa
revset: do not transform range* operators in parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
30802
diff
changeset
|
459 return smallbonus, x |
d389f19f14aa
revset: do not transform range* operators in parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
30802
diff
changeset
|
460 elif op in ('rangepre', 'rangepost', 'parentpost'): |
29119
a032ebea4e97
revset: factor out public optimize() function from recursion
Yuya Nishihara <yuya@tcha.org>
parents:
29118
diff
changeset
|
461 o = _optimize(x[1], small) |
29932
09a84e747c88
revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents:
29931
diff
changeset
|
462 order = x[2] |
09a84e747c88
revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents:
29931
diff
changeset
|
463 return o[0], (op, o[1], order) |
29898
7203400f91b0
revset: do not partial-match operator and function names in optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29897
diff
changeset
|
464 elif op in ('dagrange', 'range', 'parent', 'ancestor'): |
29119
a032ebea4e97
revset: factor out public optimize() function from recursion
Yuya Nishihara <yuya@tcha.org>
parents:
29118
diff
changeset
|
465 wa, ta = _optimize(x[1], small) |
a032ebea4e97
revset: factor out public optimize() function from recursion
Yuya Nishihara <yuya@tcha.org>
parents:
29118
diff
changeset
|
466 wb, tb = _optimize(x[2], small) |
29932
09a84e747c88
revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents:
29931
diff
changeset
|
467 order = x[3] |
09a84e747c88
revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents:
29931
diff
changeset
|
468 return wa + wb, (op, ta, tb, order) |
27987
b19d8d5d6b51
revset: flatten chained 'list' operations (aka function args) (issue5072)
Yuya Nishihara <yuya@tcha.org>
parents:
27945
diff
changeset
|
469 elif op == 'list': |
29119
a032ebea4e97
revset: factor out public optimize() function from recursion
Yuya Nishihara <yuya@tcha.org>
parents:
29118
diff
changeset
|
470 ws, ts = zip(*(_optimize(y, small) for y in x[1:])) |
27987
b19d8d5d6b51
revset: flatten chained 'list' operations (aka function args) (issue5072)
Yuya Nishihara <yuya@tcha.org>
parents:
27945
diff
changeset
|
471 return sum(ws), (op,) + ts |
29766
5004ef47f437
revset: fix keyword arguments to go through optimization process
Yuya Nishihara <yuya@tcha.org>
parents:
29646
diff
changeset
|
472 elif op == 'keyvalue': |
5004ef47f437
revset: fix keyword arguments to go through optimization process
Yuya Nishihara <yuya@tcha.org>
parents:
29646
diff
changeset
|
473 w, t = _optimize(x[2], small) |
5004ef47f437
revset: fix keyword arguments to go through optimization process
Yuya Nishihara <yuya@tcha.org>
parents:
29646
diff
changeset
|
474 return w, (op, x[1], t) |
11275 | 475 elif op == 'func': |
29441
9e8d258708bb
revset: check invalid function syntax "func-name"() explicitly
Yuya Nishihara <yuya@tcha.org>
parents:
29425
diff
changeset
|
476 f = getsymbol(x[1]) |
29119
a032ebea4e97
revset: factor out public optimize() function from recursion
Yuya Nishihara <yuya@tcha.org>
parents:
29118
diff
changeset
|
477 wa, ta = _optimize(x[2], small) |
29898
7203400f91b0
revset: do not partial-match operator and function names in optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29897
diff
changeset
|
478 if f in ('author', 'branch', 'closed', 'date', 'desc', 'file', 'grep', |
30205
b4074417b661
revset: optimize for destination() being "inefficient"
Mads Kiilerich <madski@unity3d.com>
parents:
30179
diff
changeset
|
479 'keyword', 'outgoing', 'user', 'destination'): |
11279
62ccf4cd6e7f
revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents:
11278
diff
changeset
|
480 w = 10 # slow |
29898
7203400f91b0
revset: do not partial-match operator and function names in optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29897
diff
changeset
|
481 elif f in ('modifies', 'adds', 'removes'): |
11279
62ccf4cd6e7f
revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents:
11278
diff
changeset
|
482 w = 30 # slower |
11275 | 483 elif f == "contains": |
11279
62ccf4cd6e7f
revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents:
11278
diff
changeset
|
484 w = 100 # very slow |
11275 | 485 elif f == "ancestor": |
11279
62ccf4cd6e7f
revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents:
11278
diff
changeset
|
486 w = 1 * smallbonus |
30700
323f0c4b43f4
revset: categorize wdir() as very fast function
Yuya Nishihara <yuya@tcha.org>
parents:
30699
diff
changeset
|
487 elif f in ('reverse', 'limit', 'first', 'wdir', '_intlist'): |
11279
62ccf4cd6e7f
revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents:
11278
diff
changeset
|
488 w = 0 |
29898
7203400f91b0
revset: do not partial-match operator and function names in optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29897
diff
changeset
|
489 elif f == "sort": |
11279
62ccf4cd6e7f
revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents:
11278
diff
changeset
|
490 w = 10 # assume most sorts look at changelog |
11275 | 491 else: |
11279
62ccf4cd6e7f
revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents:
11278
diff
changeset
|
492 w = 1 |
29932
09a84e747c88
revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents:
29931
diff
changeset
|
493 order = x[3] |
09a84e747c88
revset: pass around ordering flags to operations
Yuya Nishihara <yuya@tcha.org>
parents:
29931
diff
changeset
|
494 return w + wa, (op, x[1], ta, order) |
29896
104914b03b83
revset: make optimize() reject unknown operators
Yuya Nishihara <yuya@tcha.org>
parents:
29814
diff
changeset
|
495 raise ValueError('invalid operator %r' % op) |
11275 | 496 |
29119
a032ebea4e97
revset: factor out public optimize() function from recursion
Yuya Nishihara <yuya@tcha.org>
parents:
29118
diff
changeset
|
497 def optimize(tree): |
29905
371c2a39eead
revset: make analyze() a separate step from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29904
diff
changeset
|
498 """Optimize evaluatable tree |
371c2a39eead
revset: make analyze() a separate step from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29904
diff
changeset
|
499 |
371c2a39eead
revset: make analyze() a separate step from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29904
diff
changeset
|
500 All pseudo operations should be transformed beforehand. |
371c2a39eead
revset: make analyze() a separate step from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29904
diff
changeset
|
501 """ |
29119
a032ebea4e97
revset: factor out public optimize() function from recursion
Yuya Nishihara <yuya@tcha.org>
parents:
29118
diff
changeset
|
502 _weight, newtree = _optimize(tree, small=True) |
a032ebea4e97
revset: factor out public optimize() function from recursion
Yuya Nishihara <yuya@tcha.org>
parents:
29118
diff
changeset
|
503 return newtree |
a032ebea4e97
revset: factor out public optimize() function from recursion
Yuya Nishihara <yuya@tcha.org>
parents:
29118
diff
changeset
|
504 |
23845
0a7fd54d4e60
revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23844
diff
changeset
|
505 # the set of valid characters for the initial letter of symbols in |
0a7fd54d4e60
revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23844
diff
changeset
|
506 # alias declarations and definitions |
30071
2def3d55b1b9
revset: build _syminitletters from a saner source: the string module
Augie Fackler <augie@google.com>
parents:
30056
diff
changeset
|
507 _aliassyminitletters = _syminitletters | set(pycompat.sysstr('$')) |
23845
0a7fd54d4e60
revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23844
diff
changeset
|
508 |
29073
81bac118f9e2
revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents:
29072
diff
changeset
|
509 def _parsewith(spec, lookup=None, syminitletters=None): |
81bac118f9e2
revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents:
29072
diff
changeset
|
510 """Generate a parse tree of given spec with given tokenizing options |
81bac118f9e2
revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents:
29072
diff
changeset
|
511 |
81bac118f9e2
revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents:
29072
diff
changeset
|
512 >>> _parsewith('foo($1)', syminitletters=_aliassyminitletters) |
81bac118f9e2
revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents:
29072
diff
changeset
|
513 ('func', ('symbol', 'foo'), ('symbol', '$1')) |
81bac118f9e2
revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents:
29072
diff
changeset
|
514 >>> _parsewith('$1') |
81bac118f9e2
revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents:
29072
diff
changeset
|
515 Traceback (most recent call last): |
81bac118f9e2
revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents:
29072
diff
changeset
|
516 ... |
81bac118f9e2
revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents:
29072
diff
changeset
|
517 ParseError: ("syntax error in revset '$1'", 0) |
81bac118f9e2
revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents:
29072
diff
changeset
|
518 >>> _parsewith('foo bar') |
81bac118f9e2
revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents:
29072
diff
changeset
|
519 Traceback (most recent call last): |
81bac118f9e2
revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents:
29072
diff
changeset
|
520 ... |
81bac118f9e2
revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents:
29072
diff
changeset
|
521 ParseError: ('invalid token', 4) |
81bac118f9e2
revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents:
29072
diff
changeset
|
522 """ |
81bac118f9e2
revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents:
29072
diff
changeset
|
523 p = parser.parser(elements) |
81bac118f9e2
revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents:
29072
diff
changeset
|
524 tree, pos = p.parse(tokenize(spec, lookup=lookup, |
81bac118f9e2
revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents:
29072
diff
changeset
|
525 syminitletters=syminitletters)) |
81bac118f9e2
revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents:
29072
diff
changeset
|
526 if pos != len(spec): |
81bac118f9e2
revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents:
29072
diff
changeset
|
527 raise error.ParseError(_('invalid token'), pos) |
29769
abe4eecc3253
revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents:
29767
diff
changeset
|
528 return _fixops(parser.simplifyinfixops(tree, ('list', 'or'))) |
29073
81bac118f9e2
revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents:
29072
diff
changeset
|
529 |
28870
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28869
diff
changeset
|
530 class _aliasrules(parser.basealiasrules): |
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28869
diff
changeset
|
531 """Parsing and expansion rule set of revset aliases""" |
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28869
diff
changeset
|
532 _section = _('revset alias') |
29074
e7c679738503
revset: define _parsealias() in _aliasrules class
Yuya Nishihara <yuya@tcha.org>
parents:
29073
diff
changeset
|
533 |
e7c679738503
revset: define _parsealias() in _aliasrules class
Yuya Nishihara <yuya@tcha.org>
parents:
29073
diff
changeset
|
534 @staticmethod |
e7c679738503
revset: define _parsealias() in _aliasrules class
Yuya Nishihara <yuya@tcha.org>
parents:
29073
diff
changeset
|
535 def _parse(spec): |
e7c679738503
revset: define _parsealias() in _aliasrules class
Yuya Nishihara <yuya@tcha.org>
parents:
29073
diff
changeset
|
536 """Parse alias declaration/definition ``spec`` |
e7c679738503
revset: define _parsealias() in _aliasrules class
Yuya Nishihara <yuya@tcha.org>
parents:
29073
diff
changeset
|
537 |
e7c679738503
revset: define _parsealias() in _aliasrules class
Yuya Nishihara <yuya@tcha.org>
parents:
29073
diff
changeset
|
538 This allows symbol names to use also ``$`` as an initial letter |
e7c679738503
revset: define _parsealias() in _aliasrules class
Yuya Nishihara <yuya@tcha.org>
parents:
29073
diff
changeset
|
539 (for backward compatibility), and callers of this function should |
e7c679738503
revset: define _parsealias() in _aliasrules class
Yuya Nishihara <yuya@tcha.org>
parents:
29073
diff
changeset
|
540 examine whether ``$`` is used also for unexpected symbols or not. |
e7c679738503
revset: define _parsealias() in _aliasrules class
Yuya Nishihara <yuya@tcha.org>
parents:
29073
diff
changeset
|
541 """ |
e7c679738503
revset: define _parsealias() in _aliasrules class
Yuya Nishihara <yuya@tcha.org>
parents:
29073
diff
changeset
|
542 return _parsewith(spec, syminitletters=_aliassyminitletters) |
28910
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
543 |
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
544 @staticmethod |
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
545 def _trygetfunc(tree): |
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
546 if tree[0] == 'func' and tree[1][0] == 'symbol': |
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
547 return tree[1][1], getlist(tree[2]) |
28870
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28869
diff
changeset
|
548 |
29922
ae933e3e2226
revset: remove showwarning option from expandaliases()
Yuya Nishihara <yuya@tcha.org>
parents:
29906
diff
changeset
|
549 def expandaliases(ui, tree): |
28893
ee11167fe1da
parser: extract helper that creates a dict of aliases
Yuya Nishihara <yuya@tcha.org>
parents:
28892
diff
changeset
|
550 aliases = _aliasrules.buildmap(ui.configitems('revsetalias')) |
28895
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28894
diff
changeset
|
551 tree = _aliasrules.expand(aliases, tree) |
29922
ae933e3e2226
revset: remove showwarning option from expandaliases()
Yuya Nishihara <yuya@tcha.org>
parents:
29906
diff
changeset
|
552 # warn about problematic (but not referred) aliases |
ae933e3e2226
revset: remove showwarning option from expandaliases()
Yuya Nishihara <yuya@tcha.org>
parents:
29906
diff
changeset
|
553 for name, alias in sorted(aliases.iteritems()): |
ae933e3e2226
revset: remove showwarning option from expandaliases()
Yuya Nishihara <yuya@tcha.org>
parents:
29906
diff
changeset
|
554 if alias.error and not alias.warned: |
ae933e3e2226
revset: remove showwarning option from expandaliases()
Yuya Nishihara <yuya@tcha.org>
parents:
29906
diff
changeset
|
555 ui.warn(_('warning: %s\n') % (alias.error)) |
ae933e3e2226
revset: remove showwarning option from expandaliases()
Yuya Nishihara <yuya@tcha.org>
parents:
29906
diff
changeset
|
556 alias.warned = True |
23725
6a81f88758aa
revset: delay showing parse error for the revset alias until it is referred
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23720
diff
changeset
|
557 return tree |
14098
9f5a0acb0056
revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents:
14073
diff
changeset
|
558 |
23742
3a4d8a6ce432
revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23729
diff
changeset
|
559 def foldconcat(tree): |
3a4d8a6ce432
revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23729
diff
changeset
|
560 """Fold elements to be concatenated by `##` |
3a4d8a6ce432
revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23729
diff
changeset
|
561 """ |
3a4d8a6ce432
revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23729
diff
changeset
|
562 if not isinstance(tree, tuple) or tree[0] in ('string', 'symbol'): |
3a4d8a6ce432
revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23729
diff
changeset
|
563 return tree |
3a4d8a6ce432
revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23729
diff
changeset
|
564 if tree[0] == '_concat': |
3a4d8a6ce432
revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23729
diff
changeset
|
565 pending = [tree] |
3a4d8a6ce432
revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23729
diff
changeset
|
566 l = [] |
3a4d8a6ce432
revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23729
diff
changeset
|
567 while pending: |
3a4d8a6ce432
revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23729
diff
changeset
|
568 e = pending.pop() |
3a4d8a6ce432
revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23729
diff
changeset
|
569 if e[0] == '_concat': |
3a4d8a6ce432
revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23729
diff
changeset
|
570 pending.extend(reversed(e[1:])) |
3a4d8a6ce432
revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23729
diff
changeset
|
571 elif e[0] in ('string', 'symbol'): |
3a4d8a6ce432
revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23729
diff
changeset
|
572 l.append(e[1]) |
3a4d8a6ce432
revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23729
diff
changeset
|
573 else: |
3a4d8a6ce432
revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23729
diff
changeset
|
574 msg = _("\"##\" can't concatenate \"%s\" element") % (e[0]) |
3a4d8a6ce432
revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23729
diff
changeset
|
575 raise error.ParseError(msg) |
3a4d8a6ce432
revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23729
diff
changeset
|
576 return ('string', ''.join(l)) |
3a4d8a6ce432
revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23729
diff
changeset
|
577 else: |
3a4d8a6ce432
revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23729
diff
changeset
|
578 return tuple(foldconcat(t) for t in tree) |
14098
9f5a0acb0056
revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents:
14073
diff
changeset
|
579 |
20779
ffc2295c6b80
revset: pass a lookup function to the tokenizer
Matt Mackall <mpm@selenic.com>
parents:
20754
diff
changeset
|
580 def parse(spec, lookup=None): |
29073
81bac118f9e2
revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents:
29072
diff
changeset
|
581 return _parsewith(spec, lookup=lookup) |
20779
ffc2295c6b80
revset: pass a lookup function to the tokenizer
Matt Mackall <mpm@selenic.com>
parents:
20754
diff
changeset
|
582 |
31604
7eac6fcf2ffa
revsetlang: move quoting function to not be a closure
Augie Fackler <augie@google.com>
parents:
31603
diff
changeset
|
583 def _quote(s): |
31605
0b94c19b641c
revsetlang: add docstring with some tests to _quote
Augie Fackler <augie@google.com>
parents:
31604
diff
changeset
|
584 r"""Quote a value in order to make it safe for the revset engine. |
0b94c19b641c
revsetlang: add docstring with some tests to _quote
Augie Fackler <augie@google.com>
parents:
31604
diff
changeset
|
585 |
0b94c19b641c
revsetlang: add docstring with some tests to _quote
Augie Fackler <augie@google.com>
parents:
31604
diff
changeset
|
586 >>> _quote('asdf') |
0b94c19b641c
revsetlang: add docstring with some tests to _quote
Augie Fackler <augie@google.com>
parents:
31604
diff
changeset
|
587 "'asdf'" |
0b94c19b641c
revsetlang: add docstring with some tests to _quote
Augie Fackler <augie@google.com>
parents:
31604
diff
changeset
|
588 >>> _quote("asdf'\"") |
0b94c19b641c
revsetlang: add docstring with some tests to _quote
Augie Fackler <augie@google.com>
parents:
31604
diff
changeset
|
589 '\'asdf\\\'"\'' |
0b94c19b641c
revsetlang: add docstring with some tests to _quote
Augie Fackler <augie@google.com>
parents:
31604
diff
changeset
|
590 >>> _quote('asdf\'') |
31606
0b3eb280564b
revsetlang: perform quoting using ui.escapestr instead of repr()
Augie Fackler <augie@google.com>
parents:
31605
diff
changeset
|
591 "'asdf\\''" |
31605
0b94c19b641c
revsetlang: add docstring with some tests to _quote
Augie Fackler <augie@google.com>
parents:
31604
diff
changeset
|
592 >>> _quote(1) |
0b94c19b641c
revsetlang: add docstring with some tests to _quote
Augie Fackler <augie@google.com>
parents:
31604
diff
changeset
|
593 "'1'" |
0b94c19b641c
revsetlang: add docstring with some tests to _quote
Augie Fackler <augie@google.com>
parents:
31604
diff
changeset
|
594 """ |
31636
f3b151278655
revsetlang: fix _quote on int on python3
Augie Fackler <raf@durin42.com>
parents:
31606
diff
changeset
|
595 return "'%s'" % util.escapestr(pycompat.bytestr(s)) |
31604
7eac6fcf2ffa
revsetlang: move quoting function to not be a closure
Augie Fackler <augie@google.com>
parents:
31603
diff
changeset
|
596 |
14901
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
597 def formatspec(expr, *args): |
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
598 ''' |
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
599 This is a convenience function for using revsets internally, and |
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
600 escapes arguments appropriately. Aliases are intentionally ignored |
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
601 so that intended expression behavior isn't accidentally subverted. |
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
602 |
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
603 Supported arguments: |
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
604 |
15266
8bea39ca9acb
revset: add %r for embedded revset support to formatspec
Matt Mackall <mpm@selenic.com>
parents:
15153
diff
changeset
|
605 %r = revset expression, parenthesized |
14901
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
606 %d = int(arg), no quoting |
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
607 %s = string(arg), escaped and single-quoted |
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
608 %b = arg.branch(), escaped and single-quoted |
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
609 %n = hex(arg), single-quoted |
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
610 %% = a literal '%' |
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
611 |
15266
8bea39ca9acb
revset: add %r for embedded revset support to formatspec
Matt Mackall <mpm@selenic.com>
parents:
15153
diff
changeset
|
612 Prefixing the type with 'l' specifies a parenthesized list of that type. |
15140
353a1ba928f6
revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents:
15138
diff
changeset
|
613 |
15268
bd5103819c2e
revset: fix %r handling in formatspec
Matt Mackall <mpm@selenic.com>
parents:
15266
diff
changeset
|
614 >>> formatspec('%r:: and %lr', '10 or 11', ("this()", "that()")) |
bd5103819c2e
revset: fix %r handling in formatspec
Matt Mackall <mpm@selenic.com>
parents:
15266
diff
changeset
|
615 '(10 or 11):: and ((this()) or (that()))' |
14901
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
616 >>> formatspec('%d:: and not %d::', 10, 20) |
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
617 '10:: and not 20::' |
15325
cdf1daa3b83f
revset: deal with empty lists in formatspec
Matt Mackall <mpm@selenic.com>
parents:
15268
diff
changeset
|
618 >>> formatspec('%ld or %ld', [], [1]) |
15898
6902e13ddd03
revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents:
15837
diff
changeset
|
619 "_list('') or 1" |
14901
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
620 >>> formatspec('keyword(%s)', 'foo\\xe9') |
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
621 "keyword('foo\\\\xe9')" |
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
622 >>> b = lambda: 'default' |
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
623 >>> b.branch = b |
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
624 >>> formatspec('branch(%b)', b) |
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
625 "branch('default')" |
15140
353a1ba928f6
revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents:
15138
diff
changeset
|
626 >>> formatspec('root(%ls)', ['a', 'b', 'c', 'd']) |
15898
6902e13ddd03
revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents:
15837
diff
changeset
|
627 "root(_list('a\\x00b\\x00c\\x00d'))" |
14901
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
628 ''' |
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
629 |
15140
353a1ba928f6
revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents:
15138
diff
changeset
|
630 def argtype(c, arg): |
353a1ba928f6
revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents:
15138
diff
changeset
|
631 if c == 'd': |
31603
fbe8502c4480
revsetlang: portably bytestring-ify another pair of int() calls
Augie Fackler <augie@google.com>
parents:
31565
diff
changeset
|
632 return '%d' % int(arg) |
15140
353a1ba928f6
revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents:
15138
diff
changeset
|
633 elif c == 's': |
31604
7eac6fcf2ffa
revsetlang: move quoting function to not be a closure
Augie Fackler <augie@google.com>
parents:
31603
diff
changeset
|
634 return _quote(arg) |
15266
8bea39ca9acb
revset: add %r for embedded revset support to formatspec
Matt Mackall <mpm@selenic.com>
parents:
15153
diff
changeset
|
635 elif c == 'r': |
8bea39ca9acb
revset: add %r for embedded revset support to formatspec
Matt Mackall <mpm@selenic.com>
parents:
15153
diff
changeset
|
636 parse(arg) # make sure syntax errors are confined |
8bea39ca9acb
revset: add %r for embedded revset support to formatspec
Matt Mackall <mpm@selenic.com>
parents:
15153
diff
changeset
|
637 return '(%s)' % arg |
15140
353a1ba928f6
revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents:
15138
diff
changeset
|
638 elif c == 'n': |
31604
7eac6fcf2ffa
revsetlang: move quoting function to not be a closure
Augie Fackler <augie@google.com>
parents:
31603
diff
changeset
|
639 return _quote(node.hex(arg)) |
15140
353a1ba928f6
revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents:
15138
diff
changeset
|
640 elif c == 'b': |
31604
7eac6fcf2ffa
revsetlang: move quoting function to not be a closure
Augie Fackler <augie@google.com>
parents:
31603
diff
changeset
|
641 return _quote(arg.branch()) |
15140
353a1ba928f6
revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents:
15138
diff
changeset
|
642 |
15595
a585d78e7b2f
revset: balance %l or-expressions (issue3129)
Matt Mackall <mpm@selenic.com>
parents:
15532
diff
changeset
|
643 def listexp(s, t): |
a585d78e7b2f
revset: balance %l or-expressions (issue3129)
Matt Mackall <mpm@selenic.com>
parents:
15532
diff
changeset
|
644 l = len(s) |
a585d78e7b2f
revset: balance %l or-expressions (issue3129)
Matt Mackall <mpm@selenic.com>
parents:
15532
diff
changeset
|
645 if l == 0: |
15898
6902e13ddd03
revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents:
15837
diff
changeset
|
646 return "_list('')" |
6902e13ddd03
revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents:
15837
diff
changeset
|
647 elif l == 1: |
15595
a585d78e7b2f
revset: balance %l or-expressions (issue3129)
Matt Mackall <mpm@selenic.com>
parents:
15532
diff
changeset
|
648 return argtype(t, s[0]) |
15898
6902e13ddd03
revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents:
15837
diff
changeset
|
649 elif t == 'd': |
31565
553ad16b274f
revsetlang: portably turn int into bytestring
Augie Fackler <augie@google.com>
parents:
31441
diff
changeset
|
650 return "_intlist('%s')" % "\0".join('%d' % int(a) for a in s) |
15898
6902e13ddd03
revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents:
15837
diff
changeset
|
651 elif t == 's': |
6902e13ddd03
revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents:
15837
diff
changeset
|
652 return "_list('%s')" % "\0".join(s) |
6902e13ddd03
revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents:
15837
diff
changeset
|
653 elif t == 'n': |
20569
0d4be103c734
revset: added _hexlist method to replace _list for %ln
Lucas Moscovicz <lmoscovicz@fb.com>
parents:
20566
diff
changeset
|
654 return "_hexlist('%s')" % "\0".join(node.hex(a) for a in s) |
15898
6902e13ddd03
revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents:
15837
diff
changeset
|
655 elif t == 'b': |
6902e13ddd03
revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents:
15837
diff
changeset
|
656 return "_list('%s')" % "\0".join(a.branch() for a in s) |
6902e13ddd03
revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents:
15837
diff
changeset
|
657 |
15791
a814f8fcc65a
Use explicit integer division
Martin Geisler <mg@aragost.com>
parents:
15726
diff
changeset
|
658 m = l // 2 |
15595
a585d78e7b2f
revset: balance %l or-expressions (issue3129)
Matt Mackall <mpm@selenic.com>
parents:
15532
diff
changeset
|
659 return '(%s or %s)' % (listexp(s[:m], t), listexp(s[m:], t)) |
a585d78e7b2f
revset: balance %l or-expressions (issue3129)
Matt Mackall <mpm@selenic.com>
parents:
15532
diff
changeset
|
660 |
31440
f784ba187089
py3: use bytestr wrapper in revsetlang.formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
31385
diff
changeset
|
661 expr = pycompat.bytestr(expr) |
14901
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
662 ret = '' |
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
663 pos = 0 |
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
664 arg = 0 |
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
665 while pos < len(expr): |
31440
f784ba187089
py3: use bytestr wrapper in revsetlang.formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
31385
diff
changeset
|
666 c = expr[pos] |
14901
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
667 if c == '%': |
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
668 pos += 1 |
31440
f784ba187089
py3: use bytestr wrapper in revsetlang.formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
31385
diff
changeset
|
669 d = expr[pos] |
14901
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
670 if d == '%': |
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
671 ret += d |
15268
bd5103819c2e
revset: fix %r handling in formatspec
Matt Mackall <mpm@selenic.com>
parents:
15266
diff
changeset
|
672 elif d in 'dsnbr': |
15140
353a1ba928f6
revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents:
15138
diff
changeset
|
673 ret += argtype(d, args[arg]) |
14901
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
674 arg += 1 |
15140
353a1ba928f6
revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents:
15138
diff
changeset
|
675 elif d == 'l': |
353a1ba928f6
revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents:
15138
diff
changeset
|
676 # a list of some type |
353a1ba928f6
revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents:
15138
diff
changeset
|
677 pos += 1 |
31440
f784ba187089
py3: use bytestr wrapper in revsetlang.formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
31385
diff
changeset
|
678 d = expr[pos] |
15596 | 679 ret += listexp(list(args[arg]), d) |
14901
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
680 arg += 1 |
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
681 else: |
29389
98e8313dcd9e
i18n: translate abort messages
liscju <piotr.listkiewicz@gmail.com>
parents:
29365
diff
changeset
|
682 raise error.Abort(_('unexpected revspec format character %s') |
98e8313dcd9e
i18n: translate abort messages
liscju <piotr.listkiewicz@gmail.com>
parents:
29365
diff
changeset
|
683 % d) |
14901
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
684 else: |
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
685 ret += c |
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
686 pos += 1 |
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
687 |
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
688 return ret |
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
689 |
16218
81a1a00f5738
debugrevspec: pretty print output
Patrick Mezard <patrick@mezard.eu>
parents:
16185
diff
changeset
|
690 def prettyformat(tree): |
25253
3f1a9b44b8c2
parser: move prettyformat() function from revset module
Yuya Nishihara <yuya@tcha.org>
parents:
25251
diff
changeset
|
691 return parser.prettyformat(tree, ('string', 'symbol')) |
16218
81a1a00f5738
debugrevspec: pretty print output
Patrick Mezard <patrick@mezard.eu>
parents:
16185
diff
changeset
|
692 |
19719
2f9d5c5256ea
revset: add helper function to get revset parse tree depth
Alexander Plavin <alexander@plav.in>
parents:
19706
diff
changeset
|
693 def depth(tree): |
2f9d5c5256ea
revset: add helper function to get revset parse tree depth
Alexander Plavin <alexander@plav.in>
parents:
19706
diff
changeset
|
694 if isinstance(tree, tuple): |
2f9d5c5256ea
revset: add helper function to get revset parse tree depth
Alexander Plavin <alexander@plav.in>
parents:
19706
diff
changeset
|
695 return max(map(depth, tree)) + 1 |
2f9d5c5256ea
revset: add helper function to get revset parse tree depth
Alexander Plavin <alexander@plav.in>
parents:
19706
diff
changeset
|
696 else: |
2f9d5c5256ea
revset: add helper function to get revset parse tree depth
Alexander Plavin <alexander@plav.in>
parents:
19706
diff
changeset
|
697 return 0 |
2f9d5c5256ea
revset: add helper function to get revset parse tree depth
Alexander Plavin <alexander@plav.in>
parents:
19706
diff
changeset
|
698 |
19720
f0b992a9be9c
revset: add helper function to get functions used in a revset parse tree
Alexander Plavin <alexander@plav.in>
parents:
19719
diff
changeset
|
699 def funcsused(tree): |
f0b992a9be9c
revset: add helper function to get functions used in a revset parse tree
Alexander Plavin <alexander@plav.in>
parents:
19719
diff
changeset
|
700 if not isinstance(tree, tuple) or tree[0] in ('string', 'symbol'): |
f0b992a9be9c
revset: add helper function to get functions used in a revset parse tree
Alexander Plavin <alexander@plav.in>
parents:
19719
diff
changeset
|
701 return set() |
f0b992a9be9c
revset: add helper function to get functions used in a revset parse tree
Alexander Plavin <alexander@plav.in>
parents:
19719
diff
changeset
|
702 else: |
f0b992a9be9c
revset: add helper function to get functions used in a revset parse tree
Alexander Plavin <alexander@plav.in>
parents:
19719
diff
changeset
|
703 funcs = set() |
f0b992a9be9c
revset: add helper function to get functions used in a revset parse tree
Alexander Plavin <alexander@plav.in>
parents:
19719
diff
changeset
|
704 for s in tree[1:]: |
f0b992a9be9c
revset: add helper function to get functions used in a revset parse tree
Alexander Plavin <alexander@plav.in>
parents:
19719
diff
changeset
|
705 funcs |= funcsused(s) |
f0b992a9be9c
revset: add helper function to get functions used in a revset parse tree
Alexander Plavin <alexander@plav.in>
parents:
19719
diff
changeset
|
706 if tree[0] == 'func': |
f0b992a9be9c
revset: add helper function to get functions used in a revset parse tree
Alexander Plavin <alexander@plav.in>
parents:
19719
diff
changeset
|
707 funcs.add(tree[1][1]) |
f0b992a9be9c
revset: add helper function to get functions used in a revset parse tree
Alexander Plavin <alexander@plav.in>
parents:
19719
diff
changeset
|
708 return funcs |