Mercurial > hg
annotate mercurial/revsetlang.py @ 37499:75c13343cf38
templater: wrap result of '%' operation so it never looks like a thunk
This fixes min/max()/json() of map result. Before, it was taken as a lazy
byte string and stringified by evalfuncarg().
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Sun, 18 Mar 2018 23:36:52 +0900 |
parents | f0b6fbea00cf |
children | 29eb4cafeeb8 |
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 ) |
37084
f0b6fbea00cf
stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36691
diff
changeset
|
20 from .utils import ( |
f0b6fbea00cf
stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36691
diff
changeset
|
21 stringutil, |
f0b6fbea00cf
stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36691
diff
changeset
|
22 ) |
11275 | 23 |
24 elements = { | |
25815
e71e5629e006
parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents:
25801
diff
changeset
|
25 # 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
|
26 "(": (21, None, ("group", 1, ")"), ("func", 1, ")"), None), |
33416
9467d5337292
revset: add experimental relation and subscript operators
Yuya Nishihara <yuya@tcha.org>
parents:
33415
diff
changeset
|
27 "[": (21, None, None, ("subscript", 1, "]"), None), |
9467d5337292
revset: add experimental relation and subscript operators
Yuya Nishihara <yuya@tcha.org>
parents:
33415
diff
changeset
|
28 "#": (21, None, None, ("relation", 21), None), |
25815
e71e5629e006
parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents:
25801
diff
changeset
|
29 "##": (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
|
30 "~": (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
|
31 "^": (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
|
32 "-": (5, None, ("negate", 19), ("minus", 5), None), |
35542
beb667c9880f
revset: parse x^:: as (x^):: (issue5764)
Yuya Nishihara <yuya@tcha.org>
parents:
35494
diff
changeset
|
33 "::": (17, "dagrangeall", ("dagrangepre", 17), ("dagrange", 17), |
beb667c9880f
revset: parse x^:: as (x^):: (issue5764)
Yuya Nishihara <yuya@tcha.org>
parents:
35494
diff
changeset
|
34 "dagrangepost"), |
beb667c9880f
revset: parse x^:: as (x^):: (issue5764)
Yuya Nishihara <yuya@tcha.org>
parents:
35494
diff
changeset
|
35 "..": (17, "dagrangeall", ("dagrangepre", 17), ("dagrange", 17), |
beb667c9880f
revset: parse x^:: as (x^):: (issue5764)
Yuya Nishihara <yuya@tcha.org>
parents:
35494
diff
changeset
|
36 "dagrangepost"), |
29767
e5b794063fd4
parser: remove unused binding parameter from suffix action
Yuya Nishihara <yuya@tcha.org>
parents:
29646
diff
changeset
|
37 ":": (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
|
38 "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
|
39 "!": (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
|
40 "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
|
41 "&": (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
|
42 "%": (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
|
43 "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
|
44 "|": (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
|
45 "+": (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
|
46 "=": (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
|
47 ",": (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
|
48 ")": (0, None, None, None, None), |
33416
9467d5337292
revset: add experimental relation and subscript operators
Yuya Nishihara <yuya@tcha.org>
parents:
33415
diff
changeset
|
49 "]": (0, None, None, None, None), |
25815
e71e5629e006
parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents:
25801
diff
changeset
|
50 "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
|
51 "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
|
52 "end": (0, None, None, None, None), |
11275 | 53 } |
54 | |
32291
bd872f64a8ba
cleanup: use set literals
Martin von Zweigbergk <martinvonz@google.com>
parents:
31997
diff
changeset
|
55 keywords = {'and', 'or', 'not'} |
11275 | 56 |
34273
b0790bebfcf8
revset: move weight information to predicate
Jun Wu <quark@fb.com>
parents:
34272
diff
changeset
|
57 symbols = {} |
b0790bebfcf8
revset: move weight information to predicate
Jun Wu <quark@fb.com>
parents:
34272
diff
changeset
|
58 |
32291
bd872f64a8ba
cleanup: use set literals
Martin von Zweigbergk <martinvonz@google.com>
parents:
31997
diff
changeset
|
59 _quoteletters = {'"', "'"} |
33416
9467d5337292
revset: add experimental relation and subscript operators
Yuya Nishihara <yuya@tcha.org>
parents:
33415
diff
changeset
|
60 _simpleopletters = set(pycompat.iterbytestr("()[]#:=,-|&+!~^%")) |
31384
fac5cd3b8673
py3: make set of revset operators and quotes in bytes
Yuya Nishihara <yuya@tcha.org>
parents:
31383
diff
changeset
|
61 |
23842
91dbb98b3513
revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23836
diff
changeset
|
62 # 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
|
63 _syminitletters = set(pycompat.iterbytestr( |
7556fe09cc48
py3: convert set of revset initial symbols back to bytes
Yuya Nishihara <yuya@tcha.org>
parents:
31355
diff
changeset
|
64 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
|
65 string.digits.encode('ascii') + |
7556fe09cc48
py3: convert set of revset initial symbols back to bytes
Yuya Nishihara <yuya@tcha.org>
parents:
31355
diff
changeset
|
66 '._@')) | 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
|
67 |
91dbb98b3513
revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23836
diff
changeset
|
68 # 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
|
69 _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
|
70 |
91dbb98b3513
revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23836
diff
changeset
|
71 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
|
72 ''' |
d8905e2c1301
revset: accept @ in unquoted symbols (issue3686)
Matt Mackall <mpm@selenic.com>
parents:
17829
diff
changeset
|
73 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
|
74 |
23842
91dbb98b3513
revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23836
diff
changeset
|
75 ``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
|
76 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
|
77 |
91dbb98b3513
revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23836
diff
changeset
|
78 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
|
79 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
|
80 |
91dbb98b3513
revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23836
diff
changeset
|
81 ``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
|
82 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
|
83 |
91dbb98b3513
revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23836
diff
changeset
|
84 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
|
85 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
|
86 |
17886
d8905e2c1301
revset: accept @ in unquoted symbols (issue3686)
Matt Mackall <mpm@selenic.com>
parents:
17829
diff
changeset
|
87 Check that @ is a valid unquoted token character (issue3686): |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34069
diff
changeset
|
88 >>> list(tokenize(b"@::")) |
17886
d8905e2c1301
revset: accept @ in unquoted symbols (issue3686)
Matt Mackall <mpm@selenic.com>
parents:
17829
diff
changeset
|
89 [('symbol', '@', 0), ('::', None, 1), ('end', None, 3)] |
d8905e2c1301
revset: accept @ in unquoted symbols (issue3686)
Matt Mackall <mpm@selenic.com>
parents:
17829
diff
changeset
|
90 |
d8905e2c1301
revset: accept @ in unquoted symbols (issue3686)
Matt Mackall <mpm@selenic.com>
parents:
17829
diff
changeset
|
91 ''' |
31441
80c8a6db450d
py3: use bytestr wrapper in revsetlang.tokenize()
Yuya Nishihara <yuya@tcha.org>
parents:
31440
diff
changeset
|
92 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
|
93 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
|
94 syminitletters = _syminitletters |
91dbb98b3513
revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23836
diff
changeset
|
95 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
|
96 symletters = _symletters |
17886
d8905e2c1301
revset: accept @ in unquoted symbols (issue3686)
Matt Mackall <mpm@selenic.com>
parents:
17829
diff
changeset
|
97 |
25902
5214cbdc37e5
revset: port parsing rule of old-style ranges from scmutil.revrange()
Yuya Nishihara <yuya@tcha.org>
parents:
25819
diff
changeset
|
98 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
|
99 # 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
|
100 # 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
|
101 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
|
102 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
|
103 if parts[0]: |
5214cbdc37e5
revset: port parsing rule of old-style ranges from scmutil.revrange()
Yuya Nishihara <yuya@tcha.org>
parents:
25819
diff
changeset
|
104 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
|
105 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
|
106 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
|
107 yield (':', None, s) |
5214cbdc37e5
revset: port parsing rule of old-style ranges from scmutil.revrange()
Yuya Nishihara <yuya@tcha.org>
parents:
25819
diff
changeset
|
108 if parts[1]: |
5214cbdc37e5
revset: port parsing rule of old-style ranges from scmutil.revrange()
Yuya Nishihara <yuya@tcha.org>
parents:
25819
diff
changeset
|
109 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
|
110 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
|
111 return |
5214cbdc37e5
revset: port parsing rule of old-style ranges from scmutil.revrange()
Yuya Nishihara <yuya@tcha.org>
parents:
25819
diff
changeset
|
112 |
11275 | 113 pos, l = 0, len(program) |
114 while pos < l: | |
31441
80c8a6db450d
py3: use bytestr wrapper in revsetlang.tokenize()
Yuya Nishihara <yuya@tcha.org>
parents:
31440
diff
changeset
|
115 c = program[pos] |
11275 | 116 if c.isspace(): # skip inter-token whitespace |
117 pass | |
11278
7df88cdf47fd
revset: add support for prefix and suffix versions of : and ::
Matt Mackall <mpm@selenic.com>
parents:
11275
diff
changeset
|
118 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
|
119 yield ('::', None, pos) |
11278
7df88cdf47fd
revset: add support for prefix and suffix versions of : and ::
Matt Mackall <mpm@selenic.com>
parents:
11275
diff
changeset
|
120 pos += 1 # skip ahead |
11275 | 121 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
|
122 yield ('..', None, pos) |
11275 | 123 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
|
124 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
|
125 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
|
126 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
|
127 elif c in _simpleopletters: # handle simple operators |
11289
4215ce511134
revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents:
11284
diff
changeset
|
128 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
|
129 elif (c in _quoteletters or c == 'r' and |
12408
78a97859b90d
revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents:
12401
diff
changeset
|
130 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
|
131 if c == 'r': |
78a97859b90d
revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents:
12401
diff
changeset
|
132 pos += 1 |
31441
80c8a6db450d
py3: use bytestr wrapper in revsetlang.tokenize()
Yuya Nishihara <yuya@tcha.org>
parents:
31440
diff
changeset
|
133 c = program[pos] |
12408
78a97859b90d
revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents:
12401
diff
changeset
|
134 decode = lambda x: x |
78a97859b90d
revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents:
12401
diff
changeset
|
135 else: |
26232
43f9976346e9
revset: handle error of string unescaping
Yuya Nishihara <yuya@tcha.org>
parents:
26212
diff
changeset
|
136 decode = parser.unescapestr |
11275 | 137 pos += 1 |
138 s = pos | |
139 while pos < l: # find closing quote | |
31441
80c8a6db450d
py3: use bytestr wrapper in revsetlang.tokenize()
Yuya Nishihara <yuya@tcha.org>
parents:
31440
diff
changeset
|
140 d = program[pos] |
11275 | 141 if d == '\\': # skip over escaped characters |
142 pos += 2 | |
143 continue | |
144 if d == c: | |
12408
78a97859b90d
revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents:
12401
diff
changeset
|
145 yield ('string', decode(program[s:pos]), s) |
11275 | 146 break |
147 pos += 1 | |
148 else: | |
11383
de544774ebea
revset: all your error messages are belong to _
Martin Geisler <mg@lazybytes.net>
parents:
11349
diff
changeset
|
149 raise error.ParseError(_("unterminated string"), s) |
16683 | 150 # 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
|
151 elif c in syminitletters: |
11275 | 152 s = pos |
153 pos += 1 | |
154 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
|
155 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
|
156 if d not in symletters: |
11275 | 157 break |
31441
80c8a6db450d
py3: use bytestr wrapper in revsetlang.tokenize()
Yuya Nishihara <yuya@tcha.org>
parents:
31440
diff
changeset
|
158 if d == '.' and program[pos - 1] == '.': # special case for .. |
11275 | 159 pos -= 1 |
160 break | |
161 pos += 1 | |
162 sym = program[s:pos] | |
163 if sym in keywords: # operator keywords | |
11289
4215ce511134
revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents:
11284
diff
changeset
|
164 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
|
165 elif '-' in sym: |
403f1f73d30f
revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents:
20779
diff
changeset
|
166 # 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
|
167 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
|
168 # 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
|
169 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
|
170 else: |
403f1f73d30f
revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents:
20779
diff
changeset
|
171 # 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
|
172 parts = sym.split('-') |
403f1f73d30f
revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents:
20779
diff
changeset
|
173 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
|
174 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
|
175 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
|
176 s += len(p) |
403f1f73d30f
revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents:
20779
diff
changeset
|
177 yield ('-', None, pos) |
403f1f73d30f
revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents:
20779
diff
changeset
|
178 s += 1 |
403f1f73d30f
revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents:
20779
diff
changeset
|
179 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
|
180 yield ('symbol', parts[-1], s) |
11275 | 181 else: |
11289
4215ce511134
revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents:
11284
diff
changeset
|
182 yield ('symbol', sym, s) |
11275 | 183 pos -= 1 |
184 else: | |
24708
fb47816e1a9c
revsets: more informative syntax error message
Ryan McElroy <rmcelroy@fb.com>
parents:
24518
diff
changeset
|
185 raise error.ParseError(_("syntax error in revset '%s'") % |
fb47816e1a9c
revsets: more informative syntax error message
Ryan McElroy <rmcelroy@fb.com>
parents:
24518
diff
changeset
|
186 program, pos) |
11275 | 187 pos += 1 |
11289
4215ce511134
revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents:
11284
diff
changeset
|
188 yield ('end', None, pos) |
11275 | 189 |
190 # helpers | |
191 | |
30802
5eb3e4568c94
revset: add default value to getinteger() helper
Yuya Nishihara <yuya@tcha.org>
parents:
30801
diff
changeset
|
192 _notset = object() |
5eb3e4568c94
revset: add default value to getinteger() helper
Yuya Nishihara <yuya@tcha.org>
parents:
30801
diff
changeset
|
193 |
29441
9e8d258708bb
revset: check invalid function syntax "func-name"() explicitly
Yuya Nishihara <yuya@tcha.org>
parents:
29425
diff
changeset
|
194 def getsymbol(x): |
9e8d258708bb
revset: check invalid function syntax "func-name"() explicitly
Yuya Nishihara <yuya@tcha.org>
parents:
29425
diff
changeset
|
195 if x and x[0] == 'symbol': |
9e8d258708bb
revset: check invalid function syntax "func-name"() explicitly
Yuya Nishihara <yuya@tcha.org>
parents:
29425
diff
changeset
|
196 return x[1] |
9e8d258708bb
revset: check invalid function syntax "func-name"() explicitly
Yuya Nishihara <yuya@tcha.org>
parents:
29425
diff
changeset
|
197 raise error.ParseError(_('not a symbol')) |
9e8d258708bb
revset: check invalid function syntax "func-name"() explicitly
Yuya Nishihara <yuya@tcha.org>
parents:
29425
diff
changeset
|
198 |
11275 | 199 def getstring(x, err): |
11406
42408cd43f55
revset: fix up contains/getstring when no args passed
Matt Mackall <mpm@selenic.com>
parents:
11404
diff
changeset
|
200 if x and (x[0] == 'string' or x[0] == 'symbol'): |
11275 | 201 return x[1] |
11289
4215ce511134
revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents:
11284
diff
changeset
|
202 raise error.ParseError(err) |
11275 | 203 |
30802
5eb3e4568c94
revset: add default value to getinteger() helper
Yuya Nishihara <yuya@tcha.org>
parents:
30801
diff
changeset
|
204 def getinteger(x, err, default=_notset): |
5eb3e4568c94
revset: add default value to getinteger() helper
Yuya Nishihara <yuya@tcha.org>
parents:
30801
diff
changeset
|
205 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
|
206 return default |
30801
67ee7874e53b
revset: factor out getinteger() helper
Yuya Nishihara <yuya@tcha.org>
parents:
30800
diff
changeset
|
207 try: |
67ee7874e53b
revset: factor out getinteger() helper
Yuya Nishihara <yuya@tcha.org>
parents:
30800
diff
changeset
|
208 return int(getstring(x, err)) |
67ee7874e53b
revset: factor out getinteger() helper
Yuya Nishihara <yuya@tcha.org>
parents:
30800
diff
changeset
|
209 except ValueError: |
67ee7874e53b
revset: factor out getinteger() helper
Yuya Nishihara <yuya@tcha.org>
parents:
30800
diff
changeset
|
210 raise error.ParseError(err) |
67ee7874e53b
revset: factor out getinteger() helper
Yuya Nishihara <yuya@tcha.org>
parents:
30800
diff
changeset
|
211 |
31997
11f501f0a213
revsetlang: add a getboolean helper function
Denis Laxalde <denis@laxalde.org>
parents:
31800
diff
changeset
|
212 def getboolean(x, err): |
37084
f0b6fbea00cf
stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36691
diff
changeset
|
213 value = stringutil.parsebool(getsymbol(x)) |
31997
11f501f0a213
revsetlang: add a getboolean helper function
Denis Laxalde <denis@laxalde.org>
parents:
31800
diff
changeset
|
214 if value is not None: |
11f501f0a213
revsetlang: add a getboolean helper function
Denis Laxalde <denis@laxalde.org>
parents:
31800
diff
changeset
|
215 return value |
11f501f0a213
revsetlang: add a getboolean helper function
Denis Laxalde <denis@laxalde.org>
parents:
31800
diff
changeset
|
216 raise error.ParseError(err) |
11f501f0a213
revsetlang: add a getboolean helper function
Denis Laxalde <denis@laxalde.org>
parents:
31800
diff
changeset
|
217 |
11275 | 218 def getlist(x): |
219 if not x: | |
220 return [] | |
221 if x[0] == 'list': | |
27987
b19d8d5d6b51
revset: flatten chained 'list' operations (aka function args) (issue5072)
Yuya Nishihara <yuya@tcha.org>
parents:
27945
diff
changeset
|
222 return list(x[1:]) |
11275 | 223 return [x] |
224 | |
30804
4227f80f72b2
revset: abuse x:y syntax to specify line range of followlines()
Yuya Nishihara <yuya@tcha.org>
parents:
30803
diff
changeset
|
225 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
|
226 if not x: |
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 op = x[0] |
4227f80f72b2
revset: abuse x:y syntax to specify line range of followlines()
Yuya Nishihara <yuya@tcha.org>
parents:
30803
diff
changeset
|
229 if op == 'range': |
4227f80f72b2
revset: abuse x:y syntax to specify line range of followlines()
Yuya Nishihara <yuya@tcha.org>
parents:
30803
diff
changeset
|
230 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
|
231 elif op == 'rangepre': |
4227f80f72b2
revset: abuse x:y syntax to specify line range of followlines()
Yuya Nishihara <yuya@tcha.org>
parents:
30803
diff
changeset
|
232 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
|
233 elif op == 'rangepost': |
4227f80f72b2
revset: abuse x:y syntax to specify line range of followlines()
Yuya Nishihara <yuya@tcha.org>
parents:
30803
diff
changeset
|
234 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
|
235 elif op == 'rangeall': |
4227f80f72b2
revset: abuse x:y syntax to specify line range of followlines()
Yuya Nishihara <yuya@tcha.org>
parents:
30803
diff
changeset
|
236 return None, None |
4227f80f72b2
revset: abuse x:y syntax to specify line range of followlines()
Yuya Nishihara <yuya@tcha.org>
parents:
30803
diff
changeset
|
237 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
|
238 |
11339
744d5b73f776
revset: improve filter argument handling
Matt Mackall <mpm@selenic.com>
parents:
11304
diff
changeset
|
239 def getargs(x, min, max, err): |
11275 | 240 l = getlist(x) |
16161
5a627b49b4d9
graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents:
16096
diff
changeset
|
241 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
|
242 raise error.ParseError(err) |
11275 | 243 return l |
244 | |
25767
026105c442d7
revset: rename getkwargs() to getargsdict()
Yuya Nishihara <yuya@tcha.org>
parents:
25766
diff
changeset
|
245 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
|
246 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
|
247 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
|
248 |
34044
b862e6fca7ac
revsetlang: build optimized tree by helper function
Yuya Nishihara <yuya@tcha.org>
parents:
34020
diff
changeset
|
249 # cache of {spec: raw parsed tree} built internally |
b862e6fca7ac
revsetlang: build optimized tree by helper function
Yuya Nishihara <yuya@tcha.org>
parents:
34020
diff
changeset
|
250 _treecache = {} |
b862e6fca7ac
revsetlang: build optimized tree by helper function
Yuya Nishihara <yuya@tcha.org>
parents:
34020
diff
changeset
|
251 |
b862e6fca7ac
revsetlang: build optimized tree by helper function
Yuya Nishihara <yuya@tcha.org>
parents:
34020
diff
changeset
|
252 def _cachedtree(spec): |
b862e6fca7ac
revsetlang: build optimized tree by helper function
Yuya Nishihara <yuya@tcha.org>
parents:
34020
diff
changeset
|
253 # thread safe because parse() is reentrant and dict.__setitem__() is atomic |
b862e6fca7ac
revsetlang: build optimized tree by helper function
Yuya Nishihara <yuya@tcha.org>
parents:
34020
diff
changeset
|
254 tree = _treecache.get(spec) |
b862e6fca7ac
revsetlang: build optimized tree by helper function
Yuya Nishihara <yuya@tcha.org>
parents:
34020
diff
changeset
|
255 if tree is None: |
b862e6fca7ac
revsetlang: build optimized tree by helper function
Yuya Nishihara <yuya@tcha.org>
parents:
34020
diff
changeset
|
256 _treecache[spec] = tree = parse(spec) |
b862e6fca7ac
revsetlang: build optimized tree by helper function
Yuya Nishihara <yuya@tcha.org>
parents:
34020
diff
changeset
|
257 return tree |
b862e6fca7ac
revsetlang: build optimized tree by helper function
Yuya Nishihara <yuya@tcha.org>
parents:
34020
diff
changeset
|
258 |
b862e6fca7ac
revsetlang: build optimized tree by helper function
Yuya Nishihara <yuya@tcha.org>
parents:
34020
diff
changeset
|
259 def _build(tmplspec, *repls): |
b862e6fca7ac
revsetlang: build optimized tree by helper function
Yuya Nishihara <yuya@tcha.org>
parents:
34020
diff
changeset
|
260 """Create raw parsed tree from a template revset statement |
b862e6fca7ac
revsetlang: build optimized tree by helper function
Yuya Nishihara <yuya@tcha.org>
parents:
34020
diff
changeset
|
261 |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34069
diff
changeset
|
262 >>> _build(b'f(_) and _', (b'string', b'1'), (b'symbol', b'2')) |
34044
b862e6fca7ac
revsetlang: build optimized tree by helper function
Yuya Nishihara <yuya@tcha.org>
parents:
34020
diff
changeset
|
263 ('and', ('func', ('symbol', 'f'), ('string', '1')), ('symbol', '2')) |
b862e6fca7ac
revsetlang: build optimized tree by helper function
Yuya Nishihara <yuya@tcha.org>
parents:
34020
diff
changeset
|
264 """ |
b862e6fca7ac
revsetlang: build optimized tree by helper function
Yuya Nishihara <yuya@tcha.org>
parents:
34020
diff
changeset
|
265 template = _cachedtree(tmplspec) |
b862e6fca7ac
revsetlang: build optimized tree by helper function
Yuya Nishihara <yuya@tcha.org>
parents:
34020
diff
changeset
|
266 return parser.buildtree(template, ('symbol', '_'), *repls) |
b862e6fca7ac
revsetlang: build optimized tree by helper function
Yuya Nishihara <yuya@tcha.org>
parents:
34020
diff
changeset
|
267 |
34046
f23cbca9b277
revsetlang: match tree by helper function on optimize
Yuya Nishihara <yuya@tcha.org>
parents:
34044
diff
changeset
|
268 def _match(patspec, tree): |
f23cbca9b277
revsetlang: match tree by helper function on optimize
Yuya Nishihara <yuya@tcha.org>
parents:
34044
diff
changeset
|
269 """Test if a tree matches the given pattern statement; return the matches |
f23cbca9b277
revsetlang: match tree by helper function on optimize
Yuya Nishihara <yuya@tcha.org>
parents:
34044
diff
changeset
|
270 |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34069
diff
changeset
|
271 >>> _match(b'f(_)', parse(b'f()')) |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34069
diff
changeset
|
272 >>> _match(b'f(_)', parse(b'f(1)')) |
34046
f23cbca9b277
revsetlang: match tree by helper function on optimize
Yuya Nishihara <yuya@tcha.org>
parents:
34044
diff
changeset
|
273 [('func', ('symbol', 'f'), ('symbol', '1')), ('symbol', '1')] |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34069
diff
changeset
|
274 >>> _match(b'f(_)', parse(b'f(1, 2)')) |
34046
f23cbca9b277
revsetlang: match tree by helper function on optimize
Yuya Nishihara <yuya@tcha.org>
parents:
34044
diff
changeset
|
275 """ |
f23cbca9b277
revsetlang: match tree by helper function on optimize
Yuya Nishihara <yuya@tcha.org>
parents:
34044
diff
changeset
|
276 pattern = _cachedtree(patspec) |
f23cbca9b277
revsetlang: match tree by helper function on optimize
Yuya Nishihara <yuya@tcha.org>
parents:
34044
diff
changeset
|
277 return parser.matchtree(pattern, tree, ('symbol', '_'), |
f23cbca9b277
revsetlang: match tree by helper function on optimize
Yuya Nishihara <yuya@tcha.org>
parents:
34044
diff
changeset
|
278 {'keyvalue', 'list'}) |
f23cbca9b277
revsetlang: match tree by helper function on optimize
Yuya Nishihara <yuya@tcha.org>
parents:
34044
diff
changeset
|
279 |
29117
7828cadd2873
revset: construct arguments of only() against matched tree
Yuya Nishihara <yuya@tcha.org>
parents:
29116
diff
changeset
|
280 def _matchonly(revs, bases): |
34046
f23cbca9b277
revsetlang: match tree by helper function on optimize
Yuya Nishihara <yuya@tcha.org>
parents:
34044
diff
changeset
|
281 return _match('ancestors(_) and not ancestors(_)', ('and', revs, bases)) |
29116
0c9b05dae010
revset: unnest isonly() closure from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29098
diff
changeset
|
282 |
29769
abe4eecc3253
revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents:
29767
diff
changeset
|
283 def _fixops(x): |
abe4eecc3253
revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents:
29767
diff
changeset
|
284 """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
|
285 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
|
286 if not isinstance(x, tuple): |
abe4eecc3253
revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents:
29767
diff
changeset
|
287 return x |
abe4eecc3253
revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents:
29767
diff
changeset
|
288 |
abe4eecc3253
revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents:
29767
diff
changeset
|
289 op = x[0] |
abe4eecc3253
revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents:
29767
diff
changeset
|
290 if op == 'parent': |
abe4eecc3253
revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents:
29767
diff
changeset
|
291 # 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
|
292 # 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
|
293 post = ('parentpost', x[1]) |
abe4eecc3253
revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents:
29767
diff
changeset
|
294 if x[2][0] == 'dagrangepre': |
abe4eecc3253
revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents:
29767
diff
changeset
|
295 return _fixops(('dagrange', post, x[2][1])) |
35542
beb667c9880f
revset: parse x^:: as (x^):: (issue5764)
Yuya Nishihara <yuya@tcha.org>
parents:
35494
diff
changeset
|
296 elif x[2][0] == 'dagrangeall': |
beb667c9880f
revset: parse x^:: as (x^):: (issue5764)
Yuya Nishihara <yuya@tcha.org>
parents:
35494
diff
changeset
|
297 return _fixops(('dagrangepost', post)) |
29769
abe4eecc3253
revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents:
29767
diff
changeset
|
298 elif x[2][0] == 'rangepre': |
abe4eecc3253
revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents:
29767
diff
changeset
|
299 return _fixops(('range', post, x[2][1])) |
29770
9c51a5de76db
revset: also parse x^: as (x^):
Yuya Nishihara <yuya@tcha.org>
parents:
29769
diff
changeset
|
300 elif x[2][0] == 'rangeall': |
9c51a5de76db
revset: also parse x^: as (x^):
Yuya Nishihara <yuya@tcha.org>
parents:
29769
diff
changeset
|
301 return _fixops(('rangepost', post)) |
29929
b3845cab4ddc
revset: wrap arguments of 'or' by 'list' node
Yuya Nishihara <yuya@tcha.org>
parents:
29922
diff
changeset
|
302 elif op == 'or': |
b3845cab4ddc
revset: wrap arguments of 'or' by 'list' node
Yuya Nishihara <yuya@tcha.org>
parents:
29922
diff
changeset
|
303 # make number of arguments deterministic: |
b3845cab4ddc
revset: wrap arguments of 'or' by 'list' node
Yuya Nishihara <yuya@tcha.org>
parents:
29922
diff
changeset
|
304 # 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
|
305 return (op, _fixops(('list',) + x[1:])) |
33416
9467d5337292
revset: add experimental relation and subscript operators
Yuya Nishihara <yuya@tcha.org>
parents:
33415
diff
changeset
|
306 elif op == 'subscript' and x[1][0] == 'relation': |
9467d5337292
revset: add experimental relation and subscript operators
Yuya Nishihara <yuya@tcha.org>
parents:
33415
diff
changeset
|
307 # x#y[z] ternary |
9467d5337292
revset: add experimental relation and subscript operators
Yuya Nishihara <yuya@tcha.org>
parents:
33415
diff
changeset
|
308 return _fixops(('relsubscript', x[1][1], x[1][2], x[2])) |
29769
abe4eecc3253
revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents:
29767
diff
changeset
|
309 |
abe4eecc3253
revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents:
29767
diff
changeset
|
310 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
|
311 |
34011
1b28525e6698
revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents:
34010
diff
changeset
|
312 def _analyze(x): |
29904
e4b4168a4f1c
revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29898
diff
changeset
|
313 if x is None: |
e4b4168a4f1c
revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29898
diff
changeset
|
314 return x |
e4b4168a4f1c
revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29898
diff
changeset
|
315 |
e4b4168a4f1c
revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29898
diff
changeset
|
316 op = x[0] |
e4b4168a4f1c
revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29898
diff
changeset
|
317 if op == 'minus': |
34044
b862e6fca7ac
revsetlang: build optimized tree by helper function
Yuya Nishihara <yuya@tcha.org>
parents:
34020
diff
changeset
|
318 return _analyze(_build('_ and not _', *x[1:])) |
29904
e4b4168a4f1c
revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29898
diff
changeset
|
319 elif op == 'only': |
34044
b862e6fca7ac
revsetlang: build optimized tree by helper function
Yuya Nishihara <yuya@tcha.org>
parents:
34020
diff
changeset
|
320 return _analyze(_build('only(_, _)', *x[1:])) |
29904
e4b4168a4f1c
revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29898
diff
changeset
|
321 elif op == 'onlypost': |
34044
b862e6fca7ac
revsetlang: build optimized tree by helper function
Yuya Nishihara <yuya@tcha.org>
parents:
34020
diff
changeset
|
322 return _analyze(_build('only(_)', x[1])) |
35542
beb667c9880f
revset: parse x^:: as (x^):: (issue5764)
Yuya Nishihara <yuya@tcha.org>
parents:
35494
diff
changeset
|
323 elif op == 'dagrangeall': |
beb667c9880f
revset: parse x^:: as (x^):: (issue5764)
Yuya Nishihara <yuya@tcha.org>
parents:
35494
diff
changeset
|
324 raise error.ParseError(_("can't use '::' in this context")) |
29904
e4b4168a4f1c
revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29898
diff
changeset
|
325 elif op == 'dagrangepre': |
34044
b862e6fca7ac
revsetlang: build optimized tree by helper function
Yuya Nishihara <yuya@tcha.org>
parents:
34020
diff
changeset
|
326 return _analyze(_build('ancestors(_)', x[1])) |
29904
e4b4168a4f1c
revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29898
diff
changeset
|
327 elif op == 'dagrangepost': |
34044
b862e6fca7ac
revsetlang: build optimized tree by helper function
Yuya Nishihara <yuya@tcha.org>
parents:
34020
diff
changeset
|
328 return _analyze(_build('descendants(_)', x[1])) |
29904
e4b4168a4f1c
revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29898
diff
changeset
|
329 elif op == 'negate': |
e4b4168a4f1c
revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29898
diff
changeset
|
330 s = getstring(x[1], _("can't negate that")) |
34011
1b28525e6698
revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents:
34010
diff
changeset
|
331 return _analyze(('string', '-' + s)) |
29904
e4b4168a4f1c
revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29898
diff
changeset
|
332 elif op in ('string', 'symbol'): |
e4b4168a4f1c
revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29898
diff
changeset
|
333 return x |
30803
d389f19f14aa
revset: do not transform range* operators in parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
30802
diff
changeset
|
334 elif op == 'rangeall': |
34011
1b28525e6698
revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents:
34010
diff
changeset
|
335 return (op, None) |
1b28525e6698
revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents:
34010
diff
changeset
|
336 elif op in {'or', 'not', 'rangepre', 'rangepost', 'parentpost'}: |
1b28525e6698
revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents:
34010
diff
changeset
|
337 return (op, _analyze(x[1])) |
29904
e4b4168a4f1c
revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29898
diff
changeset
|
338 elif op == 'group': |
34011
1b28525e6698
revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents:
34010
diff
changeset
|
339 return _analyze(x[1]) |
1b28525e6698
revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents:
34010
diff
changeset
|
340 elif op in {'and', 'dagrange', 'range', 'parent', 'ancestor', 'relation', |
1b28525e6698
revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents:
34010
diff
changeset
|
341 'subscript'}: |
1b28525e6698
revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents:
34010
diff
changeset
|
342 ta = _analyze(x[1]) |
1b28525e6698
revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents:
34010
diff
changeset
|
343 tb = _analyze(x[2]) |
1b28525e6698
revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents:
34010
diff
changeset
|
344 return (op, ta, tb) |
33416
9467d5337292
revset: add experimental relation and subscript operators
Yuya Nishihara <yuya@tcha.org>
parents:
33415
diff
changeset
|
345 elif op == 'relsubscript': |
34011
1b28525e6698
revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents:
34010
diff
changeset
|
346 ta = _analyze(x[1]) |
1b28525e6698
revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents:
34010
diff
changeset
|
347 tb = _analyze(x[2]) |
1b28525e6698
revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents:
34010
diff
changeset
|
348 tc = _analyze(x[3]) |
1b28525e6698
revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents:
34010
diff
changeset
|
349 return (op, ta, tb, tc) |
29904
e4b4168a4f1c
revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29898
diff
changeset
|
350 elif op == 'list': |
34011
1b28525e6698
revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents:
34010
diff
changeset
|
351 return (op,) + tuple(_analyze(y) for y in x[1:]) |
29904
e4b4168a4f1c
revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29898
diff
changeset
|
352 elif op == 'keyvalue': |
34011
1b28525e6698
revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents:
34010
diff
changeset
|
353 return (op, x[1], _analyze(x[2])) |
29904
e4b4168a4f1c
revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29898
diff
changeset
|
354 elif op == 'func': |
34011
1b28525e6698
revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents:
34010
diff
changeset
|
355 return (op, x[1], _analyze(x[2])) |
29904
e4b4168a4f1c
revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29898
diff
changeset
|
356 raise ValueError('invalid operator %r' % op) |
e4b4168a4f1c
revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29898
diff
changeset
|
357 |
34011
1b28525e6698
revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents:
34010
diff
changeset
|
358 def analyze(x): |
29905
371c2a39eead
revset: make analyze() a separate step from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29904
diff
changeset
|
359 """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
|
360 optimize() or getset() |
371c2a39eead
revset: make analyze() a separate step from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29904
diff
changeset
|
361 |
371c2a39eead
revset: make analyze() a separate step from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29904
diff
changeset
|
362 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
|
363 defined in methods or symbols table respectively. |
371c2a39eead
revset: make analyze() a separate step from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29904
diff
changeset
|
364 """ |
34011
1b28525e6698
revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents:
34010
diff
changeset
|
365 return _analyze(x) |
29905
371c2a39eead
revset: make analyze() a separate step from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29904
diff
changeset
|
366 |
34272
53fb09c73ba8
revset: remove "small" argument from "_optimize"
Jun Wu <quark@fb.com>
parents:
34131
diff
changeset
|
367 def _optimize(x): |
13031
3da456d0c885
code style: prefer 'is' and 'is not' tests with singletons
Martin Geisler <mg@aragost.com>
parents:
12936
diff
changeset
|
368 if x is None: |
11279
62ccf4cd6e7f
revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents:
11278
diff
changeset
|
369 return 0, x |
62ccf4cd6e7f
revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents:
11278
diff
changeset
|
370 |
11275 | 371 op = x[0] |
29904
e4b4168a4f1c
revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29898
diff
changeset
|
372 if op in ('string', 'symbol'): |
34272
53fb09c73ba8
revset: remove "small" argument from "_optimize"
Jun Wu <quark@fb.com>
parents:
34131
diff
changeset
|
373 return 0.5, x # single revisions are small |
16859
eeb464ed7275
revset: drop unreachable code
Bryan O'Sullivan <bryano@fb.com>
parents:
16838
diff
changeset
|
374 elif op == 'and': |
34272
53fb09c73ba8
revset: remove "small" argument from "_optimize"
Jun Wu <quark@fb.com>
parents:
34131
diff
changeset
|
375 wa, ta = _optimize(x[1]) |
53fb09c73ba8
revset: remove "small" argument from "_optimize"
Jun Wu <quark@fb.com>
parents:
34131
diff
changeset
|
376 wb, tb = _optimize(x[2]) |
29116
0c9b05dae010
revset: unnest isonly() closure from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29098
diff
changeset
|
377 w = min(wa, wb) |
20499
2efd608473fb
revset: optimize missing ancestor expressions
Siddharth Agarwal <sid0@fb.com>
parents:
20498
diff
changeset
|
378 |
34065
c6c8a52e28c9
revset: optimize "draft() & ::x" pattern
Jun Wu <quark@fb.com>
parents:
34047
diff
changeset
|
379 # (draft/secret/_notpublic() & ::x) have a fast path |
c6c8a52e28c9
revset: optimize "draft() & ::x" pattern
Jun Wu <quark@fb.com>
parents:
34047
diff
changeset
|
380 m = _match('_() & ancestors(_)', ('and', ta, tb)) |
c6c8a52e28c9
revset: optimize "draft() & ::x" pattern
Jun Wu <quark@fb.com>
parents:
34047
diff
changeset
|
381 if m and getsymbol(m[1]) in {'draft', 'secret', '_notpublic'}: |
c6c8a52e28c9
revset: optimize "draft() & ::x" pattern
Jun Wu <quark@fb.com>
parents:
34047
diff
changeset
|
382 return w, _build('_phaseandancestors(_, _)', m[1], m[2]) |
c6c8a52e28c9
revset: optimize "draft() & ::x" pattern
Jun Wu <quark@fb.com>
parents:
34047
diff
changeset
|
383 |
20499
2efd608473fb
revset: optimize missing ancestor expressions
Siddharth Agarwal <sid0@fb.com>
parents:
20498
diff
changeset
|
384 # (::x and not ::y)/(not ::y and ::x) have a fast path |
34044
b862e6fca7ac
revsetlang: build optimized tree by helper function
Yuya Nishihara <yuya@tcha.org>
parents:
34020
diff
changeset
|
385 m = _matchonly(ta, tb) or _matchonly(tb, ta) |
b862e6fca7ac
revsetlang: build optimized tree by helper function
Yuya Nishihara <yuya@tcha.org>
parents:
34020
diff
changeset
|
386 if m: |
b862e6fca7ac
revsetlang: build optimized tree by helper function
Yuya Nishihara <yuya@tcha.org>
parents:
34020
diff
changeset
|
387 return w, _build('only(_, _)', *m[1:]) |
20499
2efd608473fb
revset: optimize missing ancestor expressions
Siddharth Agarwal <sid0@fb.com>
parents:
20498
diff
changeset
|
388 |
34046
f23cbca9b277
revsetlang: match tree by helper function on optimize
Yuya Nishihara <yuya@tcha.org>
parents:
34044
diff
changeset
|
389 m = _match('not _', tb) |
f23cbca9b277
revsetlang: match tree by helper function on optimize
Yuya Nishihara <yuya@tcha.org>
parents:
34044
diff
changeset
|
390 if m: |
f23cbca9b277
revsetlang: match tree by helper function on optimize
Yuya Nishihara <yuya@tcha.org>
parents:
34044
diff
changeset
|
391 return wa, ('difference', ta, m[1]) |
11279
62ccf4cd6e7f
revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents:
11278
diff
changeset
|
392 if wa > wb: |
34020
37b82485097f
revset: do not flip "and" arguments when optimizing
Jun Wu <quark@fb.com>
parents:
34016
diff
changeset
|
393 op = 'andsmally' |
34011
1b28525e6698
revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents:
34010
diff
changeset
|
394 return w, (op, ta, tb) |
11279
62ccf4cd6e7f
revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents:
11278
diff
changeset
|
395 elif op == 'or': |
25343
7fbef7932af9
revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents:
25342
diff
changeset
|
396 # 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
|
397 # lots of trivial revisions: 'a + b + c()' to '_list(a b) + c()' |
7fbef7932af9
revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents:
25342
diff
changeset
|
398 ws, ts, ss = [], [], [] |
7fbef7932af9
revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents:
25342
diff
changeset
|
399 def flushss(): |
7fbef7932af9
revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents:
25342
diff
changeset
|
400 if not ss: |
7fbef7932af9
revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents:
25342
diff
changeset
|
401 return |
7fbef7932af9
revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents:
25342
diff
changeset
|
402 if len(ss) == 1: |
7fbef7932af9
revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents:
25342
diff
changeset
|
403 w, t = ss[0] |
7fbef7932af9
revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents:
25342
diff
changeset
|
404 else: |
7fbef7932af9
revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents:
25342
diff
changeset
|
405 s = '\0'.join(t[1] for w, t in ss) |
34044
b862e6fca7ac
revsetlang: build optimized tree by helper function
Yuya Nishihara <yuya@tcha.org>
parents:
34020
diff
changeset
|
406 y = _build('_list(_)', ('string', s)) |
34272
53fb09c73ba8
revset: remove "small" argument from "_optimize"
Jun Wu <quark@fb.com>
parents:
34131
diff
changeset
|
407 w, t = _optimize(y) |
25343
7fbef7932af9
revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents:
25342
diff
changeset
|
408 ws.append(w) |
7fbef7932af9
revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents:
25342
diff
changeset
|
409 ts.append(t) |
7fbef7932af9
revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents:
25342
diff
changeset
|
410 del ss[:] |
29929
b3845cab4ddc
revset: wrap arguments of 'or' by 'list' node
Yuya Nishihara <yuya@tcha.org>
parents:
29922
diff
changeset
|
411 for y in getlist(x[1]): |
34272
53fb09c73ba8
revset: remove "small" argument from "_optimize"
Jun Wu <quark@fb.com>
parents:
34131
diff
changeset
|
412 w, t = _optimize(y) |
25996
b12e00a05d57
revset: prevent crash caused by empty group expression while optimizing "or"
Yuya Nishihara <yuya@tcha.org>
parents:
25995
diff
changeset
|
413 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
|
414 ss.append((w, t)) |
7fbef7932af9
revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents:
25342
diff
changeset
|
415 continue |
7fbef7932af9
revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents:
25342
diff
changeset
|
416 flushss() |
7fbef7932af9
revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents:
25342
diff
changeset
|
417 ws.append(w) |
7fbef7932af9
revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents:
25342
diff
changeset
|
418 ts.append(t) |
7fbef7932af9
revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents:
25342
diff
changeset
|
419 flushss() |
7fbef7932af9
revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents:
25342
diff
changeset
|
420 if len(ts) == 1: |
7fbef7932af9
revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents:
25342
diff
changeset
|
421 return ws[0], ts[0] # 'or' operation is fully optimized out |
34011
1b28525e6698
revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents:
34010
diff
changeset
|
422 return max(ws), (op, ('list',) + tuple(ts)) |
11275 | 423 elif op == 'not': |
25191
08d1ef09ed37
revset: optimize not public revset
Laurent Charignon <lcharignon@fb.com>
parents:
25149
diff
changeset
|
424 # Optimize not public() to _notpublic() because we have a fast version |
34046
f23cbca9b277
revsetlang: match tree by helper function on optimize
Yuya Nishihara <yuya@tcha.org>
parents:
34044
diff
changeset
|
425 if _match('public()', x[1]): |
34272
53fb09c73ba8
revset: remove "small" argument from "_optimize"
Jun Wu <quark@fb.com>
parents:
34131
diff
changeset
|
426 o = _optimize(_build('_notpublic()')) |
25191
08d1ef09ed37
revset: optimize not public revset
Laurent Charignon <lcharignon@fb.com>
parents:
25149
diff
changeset
|
427 return o[0], o[1] |
08d1ef09ed37
revset: optimize not public revset
Laurent Charignon <lcharignon@fb.com>
parents:
25149
diff
changeset
|
428 else: |
34272
53fb09c73ba8
revset: remove "small" argument from "_optimize"
Jun Wu <quark@fb.com>
parents:
34131
diff
changeset
|
429 o = _optimize(x[1]) |
34011
1b28525e6698
revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents:
34010
diff
changeset
|
430 return o[0], (op, o[1]) |
30803
d389f19f14aa
revset: do not transform range* operators in parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
30802
diff
changeset
|
431 elif op == 'rangeall': |
34272
53fb09c73ba8
revset: remove "small" argument from "_optimize"
Jun Wu <quark@fb.com>
parents:
34131
diff
changeset
|
432 return 1, x |
30803
d389f19f14aa
revset: do not transform range* operators in parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
30802
diff
changeset
|
433 elif op in ('rangepre', 'rangepost', 'parentpost'): |
34272
53fb09c73ba8
revset: remove "small" argument from "_optimize"
Jun Wu <quark@fb.com>
parents:
34131
diff
changeset
|
434 o = _optimize(x[1]) |
34011
1b28525e6698
revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents:
34010
diff
changeset
|
435 return o[0], (op, o[1]) |
33415
371f59c6a89e
revset: do not compute weight for integer literal argument
Yuya Nishihara <yuya@tcha.org>
parents:
33336
diff
changeset
|
436 elif op in ('dagrange', 'range'): |
34272
53fb09c73ba8
revset: remove "small" argument from "_optimize"
Jun Wu <quark@fb.com>
parents:
34131
diff
changeset
|
437 wa, ta = _optimize(x[1]) |
53fb09c73ba8
revset: remove "small" argument from "_optimize"
Jun Wu <quark@fb.com>
parents:
34131
diff
changeset
|
438 wb, tb = _optimize(x[2]) |
34011
1b28525e6698
revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents:
34010
diff
changeset
|
439 return wa + wb, (op, ta, tb) |
33416
9467d5337292
revset: add experimental relation and subscript operators
Yuya Nishihara <yuya@tcha.org>
parents:
33415
diff
changeset
|
440 elif op in ('parent', 'ancestor', 'relation', 'subscript'): |
34272
53fb09c73ba8
revset: remove "small" argument from "_optimize"
Jun Wu <quark@fb.com>
parents:
34131
diff
changeset
|
441 w, t = _optimize(x[1]) |
34011
1b28525e6698
revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents:
34010
diff
changeset
|
442 return w, (op, t, x[2]) |
33416
9467d5337292
revset: add experimental relation and subscript operators
Yuya Nishihara <yuya@tcha.org>
parents:
33415
diff
changeset
|
443 elif op == 'relsubscript': |
34272
53fb09c73ba8
revset: remove "small" argument from "_optimize"
Jun Wu <quark@fb.com>
parents:
34131
diff
changeset
|
444 w, t = _optimize(x[1]) |
34011
1b28525e6698
revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents:
34010
diff
changeset
|
445 return w, (op, t, x[2], x[3]) |
27987
b19d8d5d6b51
revset: flatten chained 'list' operations (aka function args) (issue5072)
Yuya Nishihara <yuya@tcha.org>
parents:
27945
diff
changeset
|
446 elif op == 'list': |
34272
53fb09c73ba8
revset: remove "small" argument from "_optimize"
Jun Wu <quark@fb.com>
parents:
34131
diff
changeset
|
447 ws, ts = zip(*(_optimize(y) 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
|
448 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
|
449 elif op == 'keyvalue': |
34272
53fb09c73ba8
revset: remove "small" argument from "_optimize"
Jun Wu <quark@fb.com>
parents:
34131
diff
changeset
|
450 w, t = _optimize(x[2]) |
29766
5004ef47f437
revset: fix keyword arguments to go through optimization process
Yuya Nishihara <yuya@tcha.org>
parents:
29646
diff
changeset
|
451 return w, (op, x[1], t) |
11275 | 452 elif op == 'func': |
29441
9e8d258708bb
revset: check invalid function syntax "func-name"() explicitly
Yuya Nishihara <yuya@tcha.org>
parents:
29425
diff
changeset
|
453 f = getsymbol(x[1]) |
34272
53fb09c73ba8
revset: remove "small" argument from "_optimize"
Jun Wu <quark@fb.com>
parents:
34131
diff
changeset
|
454 wa, ta = _optimize(x[2]) |
34273
b0790bebfcf8
revset: move weight information to predicate
Jun Wu <quark@fb.com>
parents:
34272
diff
changeset
|
455 w = getattr(symbols.get(f), '_weight', 1) |
34011
1b28525e6698
revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents:
34010
diff
changeset
|
456 return w + wa, (op, x[1], ta) |
29896
104914b03b83
revset: make optimize() reject unknown operators
Yuya Nishihara <yuya@tcha.org>
parents:
29814
diff
changeset
|
457 raise ValueError('invalid operator %r' % op) |
11275 | 458 |
29119
a032ebea4e97
revset: factor out public optimize() function from recursion
Yuya Nishihara <yuya@tcha.org>
parents:
29118
diff
changeset
|
459 def optimize(tree): |
29905
371c2a39eead
revset: make analyze() a separate step from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29904
diff
changeset
|
460 """Optimize evaluatable tree |
371c2a39eead
revset: make analyze() a separate step from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29904
diff
changeset
|
461 |
371c2a39eead
revset: make analyze() a separate step from optimize()
Yuya Nishihara <yuya@tcha.org>
parents:
29904
diff
changeset
|
462 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
|
463 """ |
34272
53fb09c73ba8
revset: remove "small" argument from "_optimize"
Jun Wu <quark@fb.com>
parents:
34131
diff
changeset
|
464 _weight, newtree = _optimize(tree) |
29119
a032ebea4e97
revset: factor out public optimize() function from recursion
Yuya Nishihara <yuya@tcha.org>
parents:
29118
diff
changeset
|
465 return newtree |
a032ebea4e97
revset: factor out public optimize() function from recursion
Yuya Nishihara <yuya@tcha.org>
parents:
29118
diff
changeset
|
466 |
23845
0a7fd54d4e60
revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23844
diff
changeset
|
467 # 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
|
468 # alias declarations and definitions |
34069
e18119b1ad5d
py3: fix mixed bytes/unicode in revsetlang._aliassyminitletters
Yuya Nishihara <yuya@tcha.org>
parents:
34065
diff
changeset
|
469 _aliassyminitletters = _syminitletters | {'$'} |
23845
0a7fd54d4e60
revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23844
diff
changeset
|
470 |
29073
81bac118f9e2
revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents:
29072
diff
changeset
|
471 def _parsewith(spec, lookup=None, syminitletters=None): |
81bac118f9e2
revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents:
29072
diff
changeset
|
472 """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
|
473 |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34069
diff
changeset
|
474 >>> _parsewith(b'foo($1)', syminitletters=_aliassyminitletters) |
29073
81bac118f9e2
revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents:
29072
diff
changeset
|
475 ('func', ('symbol', 'foo'), ('symbol', '$1')) |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34069
diff
changeset
|
476 >>> _parsewith(b'$1') |
29073
81bac118f9e2
revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents:
29072
diff
changeset
|
477 Traceback (most recent call last): |
81bac118f9e2
revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents:
29072
diff
changeset
|
478 ... |
81bac118f9e2
revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents:
29072
diff
changeset
|
479 ParseError: ("syntax error in revset '$1'", 0) |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34069
diff
changeset
|
480 >>> _parsewith(b'foo bar') |
29073
81bac118f9e2
revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents:
29072
diff
changeset
|
481 Traceback (most recent call last): |
81bac118f9e2
revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents:
29072
diff
changeset
|
482 ... |
81bac118f9e2
revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents:
29072
diff
changeset
|
483 ParseError: ('invalid token', 4) |
81bac118f9e2
revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents:
29072
diff
changeset
|
484 """ |
81bac118f9e2
revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents:
29072
diff
changeset
|
485 p = parser.parser(elements) |
81bac118f9e2
revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents:
29072
diff
changeset
|
486 tree, pos = p.parse(tokenize(spec, lookup=lookup, |
81bac118f9e2
revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents:
29072
diff
changeset
|
487 syminitletters=syminitletters)) |
81bac118f9e2
revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents:
29072
diff
changeset
|
488 if pos != len(spec): |
81bac118f9e2
revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents:
29072
diff
changeset
|
489 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
|
490 return _fixops(parser.simplifyinfixops(tree, ('list', 'or'))) |
29073
81bac118f9e2
revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents:
29072
diff
changeset
|
491 |
28870
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28869
diff
changeset
|
492 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
|
493 """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
|
494 _section = _('revset alias') |
29074
e7c679738503
revset: define _parsealias() in _aliasrules class
Yuya Nishihara <yuya@tcha.org>
parents:
29073
diff
changeset
|
495 |
e7c679738503
revset: define _parsealias() in _aliasrules class
Yuya Nishihara <yuya@tcha.org>
parents:
29073
diff
changeset
|
496 @staticmethod |
e7c679738503
revset: define _parsealias() in _aliasrules class
Yuya Nishihara <yuya@tcha.org>
parents:
29073
diff
changeset
|
497 def _parse(spec): |
e7c679738503
revset: define _parsealias() in _aliasrules class
Yuya Nishihara <yuya@tcha.org>
parents:
29073
diff
changeset
|
498 """Parse alias declaration/definition ``spec`` |
e7c679738503
revset: define _parsealias() in _aliasrules class
Yuya Nishihara <yuya@tcha.org>
parents:
29073
diff
changeset
|
499 |
e7c679738503
revset: define _parsealias() in _aliasrules class
Yuya Nishihara <yuya@tcha.org>
parents:
29073
diff
changeset
|
500 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
|
501 (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
|
502 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
|
503 """ |
e7c679738503
revset: define _parsealias() in _aliasrules class
Yuya Nishihara <yuya@tcha.org>
parents:
29073
diff
changeset
|
504 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
|
505 |
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
506 @staticmethod |
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
507 def _trygetfunc(tree): |
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
508 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
|
509 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
|
510 |
33336
4672db164c98
revset: make repo.anyrevs accept customized alias override (API)
Jun Wu <quark@fb.com>
parents:
32913
diff
changeset
|
511 def expandaliases(tree, aliases, warn=None): |
4672db164c98
revset: make repo.anyrevs accept customized alias override (API)
Jun Wu <quark@fb.com>
parents:
32913
diff
changeset
|
512 """Expand aliases in a tree, aliases is a list of (name, value) tuples""" |
4672db164c98
revset: make repo.anyrevs accept customized alias override (API)
Jun Wu <quark@fb.com>
parents:
32913
diff
changeset
|
513 aliases = _aliasrules.buildmap(aliases) |
28895
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28894
diff
changeset
|
514 tree = _aliasrules.expand(aliases, tree) |
29922
ae933e3e2226
revset: remove showwarning option from expandaliases()
Yuya Nishihara <yuya@tcha.org>
parents:
29906
diff
changeset
|
515 # warn about problematic (but not referred) aliases |
33336
4672db164c98
revset: make repo.anyrevs accept customized alias override (API)
Jun Wu <quark@fb.com>
parents:
32913
diff
changeset
|
516 if warn is not None: |
4672db164c98
revset: make repo.anyrevs accept customized alias override (API)
Jun Wu <quark@fb.com>
parents:
32913
diff
changeset
|
517 for name, alias in sorted(aliases.iteritems()): |
4672db164c98
revset: make repo.anyrevs accept customized alias override (API)
Jun Wu <quark@fb.com>
parents:
32913
diff
changeset
|
518 if alias.error and not alias.warned: |
4672db164c98
revset: make repo.anyrevs accept customized alias override (API)
Jun Wu <quark@fb.com>
parents:
32913
diff
changeset
|
519 warn(_('warning: %s\n') % (alias.error)) |
4672db164c98
revset: make repo.anyrevs accept customized alias override (API)
Jun Wu <quark@fb.com>
parents:
32913
diff
changeset
|
520 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
|
521 return tree |
14098
9f5a0acb0056
revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents:
14073
diff
changeset
|
522 |
23742
3a4d8a6ce432
revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23729
diff
changeset
|
523 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
|
524 """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
|
525 """ |
3a4d8a6ce432
revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23729
diff
changeset
|
526 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
|
527 return tree |
3a4d8a6ce432
revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23729
diff
changeset
|
528 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
|
529 pending = [tree] |
3a4d8a6ce432
revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23729
diff
changeset
|
530 l = [] |
3a4d8a6ce432
revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23729
diff
changeset
|
531 while pending: |
3a4d8a6ce432
revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23729
diff
changeset
|
532 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
|
533 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
|
534 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
|
535 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
|
536 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
|
537 else: |
3a4d8a6ce432
revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23729
diff
changeset
|
538 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
|
539 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
|
540 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
|
541 else: |
3a4d8a6ce432
revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
23729
diff
changeset
|
542 return tuple(foldconcat(t) for t in tree) |
14098
9f5a0acb0056
revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents:
14073
diff
changeset
|
543 |
20779
ffc2295c6b80
revset: pass a lookup function to the tokenizer
Matt Mackall <mpm@selenic.com>
parents:
20754
diff
changeset
|
544 def parse(spec, lookup=None): |
36685
2a258985ffeb
revsetlang: add a hint for more useful parse errors
Ryan McElroy <rmcelroy@fb.com>
parents:
35882
diff
changeset
|
545 try: |
2a258985ffeb
revsetlang: add a hint for more useful parse errors
Ryan McElroy <rmcelroy@fb.com>
parents:
35882
diff
changeset
|
546 return _parsewith(spec, lookup=lookup) |
2a258985ffeb
revsetlang: add a hint for more useful parse errors
Ryan McElroy <rmcelroy@fb.com>
parents:
35882
diff
changeset
|
547 except error.ParseError as inst: |
2a258985ffeb
revsetlang: add a hint for more useful parse errors
Ryan McElroy <rmcelroy@fb.com>
parents:
35882
diff
changeset
|
548 if len(inst.args) > 1: # has location |
36691
1b179d151578
templater: fix position of terminator character in error message
Yuya Nishihara <yuya@tcha.org>
parents:
36685
diff
changeset
|
549 loc = inst.args[1] |
36685
2a258985ffeb
revsetlang: add a hint for more useful parse errors
Ryan McElroy <rmcelroy@fb.com>
parents:
35882
diff
changeset
|
550 # Remove newlines -- spaces are equivalent whitespace. |
2a258985ffeb
revsetlang: add a hint for more useful parse errors
Ryan McElroy <rmcelroy@fb.com>
parents:
35882
diff
changeset
|
551 spec = spec.replace('\n', ' ') |
2a258985ffeb
revsetlang: add a hint for more useful parse errors
Ryan McElroy <rmcelroy@fb.com>
parents:
35882
diff
changeset
|
552 # We want the caret to point to the place in the template that |
2a258985ffeb
revsetlang: add a hint for more useful parse errors
Ryan McElroy <rmcelroy@fb.com>
parents:
35882
diff
changeset
|
553 # failed to parse, but in a hint we get a open paren at the |
2a258985ffeb
revsetlang: add a hint for more useful parse errors
Ryan McElroy <rmcelroy@fb.com>
parents:
35882
diff
changeset
|
554 # start. Therefore, we print "loc + 1" spaces (instead of "loc") |
2a258985ffeb
revsetlang: add a hint for more useful parse errors
Ryan McElroy <rmcelroy@fb.com>
parents:
35882
diff
changeset
|
555 # to line up the caret with the location of the error. |
36691
1b179d151578
templater: fix position of terminator character in error message
Yuya Nishihara <yuya@tcha.org>
parents:
36685
diff
changeset
|
556 inst.hint = spec + '\n' + ' ' * (loc + 1) + '^ ' + _('here') |
36685
2a258985ffeb
revsetlang: add a hint for more useful parse errors
Ryan McElroy <rmcelroy@fb.com>
parents:
35882
diff
changeset
|
557 raise |
20779
ffc2295c6b80
revset: pass a lookup function to the tokenizer
Matt Mackall <mpm@selenic.com>
parents:
20754
diff
changeset
|
558 |
31604
7eac6fcf2ffa
revsetlang: move quoting function to not be a closure
Augie Fackler <augie@google.com>
parents:
31603
diff
changeset
|
559 def _quote(s): |
31605
0b94c19b641c
revsetlang: add docstring with some tests to _quote
Augie Fackler <augie@google.com>
parents:
31604
diff
changeset
|
560 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
|
561 |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34069
diff
changeset
|
562 >>> _quote(b'asdf') |
31605
0b94c19b641c
revsetlang: add docstring with some tests to _quote
Augie Fackler <augie@google.com>
parents:
31604
diff
changeset
|
563 "'asdf'" |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34069
diff
changeset
|
564 >>> _quote(b"asdf'\"") |
31605
0b94c19b641c
revsetlang: add docstring with some tests to _quote
Augie Fackler <augie@google.com>
parents:
31604
diff
changeset
|
565 '\'asdf\\\'"\'' |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34069
diff
changeset
|
566 >>> _quote(b'asdf\'') |
31606
0b3eb280564b
revsetlang: perform quoting using ui.escapestr instead of repr()
Augie Fackler <augie@google.com>
parents:
31605
diff
changeset
|
567 "'asdf\\''" |
31605
0b94c19b641c
revsetlang: add docstring with some tests to _quote
Augie Fackler <augie@google.com>
parents:
31604
diff
changeset
|
568 >>> _quote(1) |
0b94c19b641c
revsetlang: add docstring with some tests to _quote
Augie Fackler <augie@google.com>
parents:
31604
diff
changeset
|
569 "'1'" |
0b94c19b641c
revsetlang: add docstring with some tests to _quote
Augie Fackler <augie@google.com>
parents:
31604
diff
changeset
|
570 """ |
37084
f0b6fbea00cf
stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36691
diff
changeset
|
571 return "'%s'" % stringutil.escapestr(pycompat.bytestr(s)) |
31604
7eac6fcf2ffa
revsetlang: move quoting function to not be a closure
Augie Fackler <augie@google.com>
parents:
31603
diff
changeset
|
572 |
35596
a57acea31b3b
revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35595
diff
changeset
|
573 def _formatargtype(c, arg): |
a57acea31b3b
revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35595
diff
changeset
|
574 if c == 'd': |
a57acea31b3b
revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35595
diff
changeset
|
575 return '%d' % int(arg) |
a57acea31b3b
revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35595
diff
changeset
|
576 elif c == 's': |
a57acea31b3b
revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35595
diff
changeset
|
577 return _quote(arg) |
a57acea31b3b
revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35595
diff
changeset
|
578 elif c == 'r': |
a57acea31b3b
revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35595
diff
changeset
|
579 parse(arg) # make sure syntax errors are confined |
a57acea31b3b
revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35595
diff
changeset
|
580 return '(%s)' % arg |
a57acea31b3b
revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35595
diff
changeset
|
581 elif c == 'n': |
a57acea31b3b
revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35595
diff
changeset
|
582 return _quote(node.hex(arg)) |
a57acea31b3b
revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35595
diff
changeset
|
583 elif c == 'b': |
a57acea31b3b
revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35595
diff
changeset
|
584 try: |
a57acea31b3b
revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35595
diff
changeset
|
585 return _quote(arg.branch()) |
a57acea31b3b
revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35595
diff
changeset
|
586 except AttributeError: |
a57acea31b3b
revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35595
diff
changeset
|
587 raise TypeError |
a57acea31b3b
revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35595
diff
changeset
|
588 raise error.ParseError(_('unexpected revspec format character %s') % c) |
a57acea31b3b
revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35595
diff
changeset
|
589 |
a57acea31b3b
revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35595
diff
changeset
|
590 def _formatlistexp(s, t): |
a57acea31b3b
revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35595
diff
changeset
|
591 l = len(s) |
a57acea31b3b
revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35595
diff
changeset
|
592 if l == 0: |
a57acea31b3b
revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35595
diff
changeset
|
593 return "_list('')" |
a57acea31b3b
revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35595
diff
changeset
|
594 elif l == 1: |
a57acea31b3b
revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35595
diff
changeset
|
595 return _formatargtype(t, s[0]) |
a57acea31b3b
revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35595
diff
changeset
|
596 elif t == 'd': |
a57acea31b3b
revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35595
diff
changeset
|
597 return "_intlist('%s')" % "\0".join('%d' % int(a) for a in s) |
a57acea31b3b
revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35595
diff
changeset
|
598 elif t == 's': |
a57acea31b3b
revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35595
diff
changeset
|
599 return "_list(%s)" % _quote("\0".join(s)) |
a57acea31b3b
revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35595
diff
changeset
|
600 elif t == 'n': |
a57acea31b3b
revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35595
diff
changeset
|
601 return "_hexlist('%s')" % "\0".join(node.hex(a) for a in s) |
a57acea31b3b
revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35595
diff
changeset
|
602 elif t == 'b': |
a57acea31b3b
revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35595
diff
changeset
|
603 try: |
a57acea31b3b
revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35595
diff
changeset
|
604 return "_list('%s')" % "\0".join(a.branch() for a in s) |
a57acea31b3b
revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35595
diff
changeset
|
605 except AttributeError: |
a57acea31b3b
revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35595
diff
changeset
|
606 raise TypeError |
a57acea31b3b
revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35595
diff
changeset
|
607 |
a57acea31b3b
revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35595
diff
changeset
|
608 m = l // 2 |
a57acea31b3b
revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35595
diff
changeset
|
609 return '(%s or %s)' % (_formatlistexp(s[:m], t), _formatlistexp(s[m:], t)) |
a57acea31b3b
revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35595
diff
changeset
|
610 |
35597
ed0902e8053e
revsetlang: add %p specifier to format list of function arguments
Yuya Nishihara <yuya@tcha.org>
parents:
35596
diff
changeset
|
611 def _formatparamexp(args, t): |
ed0902e8053e
revsetlang: add %p specifier to format list of function arguments
Yuya Nishihara <yuya@tcha.org>
parents:
35596
diff
changeset
|
612 return ', '.join(_formatargtype(t, a) for a in args) |
ed0902e8053e
revsetlang: add %p specifier to format list of function arguments
Yuya Nishihara <yuya@tcha.org>
parents:
35596
diff
changeset
|
613 |
ed0902e8053e
revsetlang: add %p specifier to format list of function arguments
Yuya Nishihara <yuya@tcha.org>
parents:
35596
diff
changeset
|
614 _formatlistfuncs = { |
ed0902e8053e
revsetlang: add %p specifier to format list of function arguments
Yuya Nishihara <yuya@tcha.org>
parents:
35596
diff
changeset
|
615 'l': _formatlistexp, |
ed0902e8053e
revsetlang: add %p specifier to format list of function arguments
Yuya Nishihara <yuya@tcha.org>
parents:
35596
diff
changeset
|
616 'p': _formatparamexp, |
ed0902e8053e
revsetlang: add %p specifier to format list of function arguments
Yuya Nishihara <yuya@tcha.org>
parents:
35596
diff
changeset
|
617 } |
ed0902e8053e
revsetlang: add %p specifier to format list of function arguments
Yuya Nishihara <yuya@tcha.org>
parents:
35596
diff
changeset
|
618 |
14901
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
619 def formatspec(expr, *args): |
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
620 ''' |
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
621 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
|
622 escapes arguments appropriately. Aliases are intentionally ignored |
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
623 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
|
624 |
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
625 Supported arguments: |
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
626 |
15266
8bea39ca9acb
revset: add %r for embedded revset support to formatspec
Matt Mackall <mpm@selenic.com>
parents:
15153
diff
changeset
|
627 %r = revset expression, parenthesized |
14901
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
628 %d = int(arg), no quoting |
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
629 %s = string(arg), escaped and single-quoted |
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
630 %b = arg.branch(), escaped and single-quoted |
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
631 %n = hex(arg), single-quoted |
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
632 %% = a literal '%' |
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
633 |
35597
ed0902e8053e
revsetlang: add %p specifier to format list of function arguments
Yuya Nishihara <yuya@tcha.org>
parents:
35596
diff
changeset
|
634 Prefixing the type with 'l' specifies a parenthesized list of that type, |
ed0902e8053e
revsetlang: add %p specifier to format list of function arguments
Yuya Nishihara <yuya@tcha.org>
parents:
35596
diff
changeset
|
635 and 'p' specifies a list of function parameters of that type. |
15140
353a1ba928f6
revset: add 'l' flag to formatspec for args
Matt Mackall <mpm@selenic.com>
parents:
15138
diff
changeset
|
636 |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34069
diff
changeset
|
637 >>> formatspec(b'%r:: and %lr', b'10 or 11', (b"this()", b"that()")) |
15268
bd5103819c2e
revset: fix %r handling in formatspec
Matt Mackall <mpm@selenic.com>
parents:
15266
diff
changeset
|
638 '(10 or 11):: and ((this()) or (that()))' |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34069
diff
changeset
|
639 >>> formatspec(b'%d:: and not %d::', 10, 20) |
14901
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
640 '10:: and not 20::' |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34069
diff
changeset
|
641 >>> formatspec(b'%ld or %ld', [], [1]) |
15898
6902e13ddd03
revset: optimize building large lists in formatrevspec
Matt Mackall <mpm@selenic.com>
parents:
15837
diff
changeset
|
642 "_list('') or 1" |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34069
diff
changeset
|
643 >>> formatspec(b'keyword(%s)', b'foo\\xe9') |
14901
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
644 "keyword('foo\\\\xe9')" |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34069
diff
changeset
|
645 >>> b = lambda: b'default' |
14901
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
646 >>> b.branch = b |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34069
diff
changeset
|
647 >>> formatspec(b'branch(%b)', b) |
14901
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
648 "branch('default')" |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34069
diff
changeset
|
649 >>> formatspec(b'root(%ls)', [b'a', b'b', b'c', b'd']) |
35595
91201737d07a
revsetlang: fix quoting of %ls string
Yuya Nishihara <yuya@tcha.org>
parents:
35594
diff
changeset
|
650 "root(_list('a\\\\x00b\\\\x00c\\\\x00d'))" |
35597
ed0902e8053e
revsetlang: add %p specifier to format list of function arguments
Yuya Nishihara <yuya@tcha.org>
parents:
35596
diff
changeset
|
651 >>> formatspec(b'sort(%r, %ps)', b':', [b'desc', b'user']) |
ed0902e8053e
revsetlang: add %p specifier to format list of function arguments
Yuya Nishihara <yuya@tcha.org>
parents:
35596
diff
changeset
|
652 "sort((:), 'desc', 'user')" |
35822
4269971b0d26
revsetlang: fix a doctest example on Python 3
Augie Fackler <augie@google.com>
parents:
35597
diff
changeset
|
653 >>> formatspec(b'%ls', [b'a', b"'"]) |
35595
91201737d07a
revsetlang: fix quoting of %ls string
Yuya Nishihara <yuya@tcha.org>
parents:
35594
diff
changeset
|
654 "_list('a\\\\x00\\\\'')" |
14901
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
655 ''' |
31440
f784ba187089
py3: use bytestr wrapper in revsetlang.formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
31385
diff
changeset
|
656 expr = pycompat.bytestr(expr) |
35560
3a8810c1b9bc
revsetlang: use iterator to track current argument in formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35559
diff
changeset
|
657 argiter = iter(args) |
35557
2df8d12f23bc
revsetlang: avoid string concatenation in formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35542
diff
changeset
|
658 ret = [] |
14901
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
659 pos = 0 |
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
660 while pos < len(expr): |
35558
dfc628611144
revsetlang: use str.find() to scan expr in formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35557
diff
changeset
|
661 q = expr.find('%', pos) |
dfc628611144
revsetlang: use str.find() to scan expr in formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35557
diff
changeset
|
662 if q < 0: |
dfc628611144
revsetlang: use str.find() to scan expr in formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35557
diff
changeset
|
663 ret.append(expr[pos:]) |
dfc628611144
revsetlang: use str.find() to scan expr in formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35557
diff
changeset
|
664 break |
dfc628611144
revsetlang: use str.find() to scan expr in formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35557
diff
changeset
|
665 ret.append(expr[pos:q]) |
dfc628611144
revsetlang: use str.find() to scan expr in formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35557
diff
changeset
|
666 pos = q + 1 |
35593
850cd045b1df
revsetlang: check incomplete revspec format character
Yuya Nishihara <yuya@tcha.org>
parents:
35592
diff
changeset
|
667 try: |
850cd045b1df
revsetlang: check incomplete revspec format character
Yuya Nishihara <yuya@tcha.org>
parents:
35592
diff
changeset
|
668 d = expr[pos] |
850cd045b1df
revsetlang: check incomplete revspec format character
Yuya Nishihara <yuya@tcha.org>
parents:
35592
diff
changeset
|
669 except IndexError: |
850cd045b1df
revsetlang: check incomplete revspec format character
Yuya Nishihara <yuya@tcha.org>
parents:
35592
diff
changeset
|
670 raise error.ParseError(_('incomplete revspec format character')) |
35559
a480551bd1b4
revsetlang: unnest "if True" in formatrevspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35558
diff
changeset
|
671 if d == '%': |
a480551bd1b4
revsetlang: unnest "if True" in formatrevspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35558
diff
changeset
|
672 ret.append(d) |
35592
0fd617afebc0
revsetlang: check number of arguments passed to formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35591
diff
changeset
|
673 pos += 1 |
0fd617afebc0
revsetlang: check number of arguments passed to formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35591
diff
changeset
|
674 continue |
0fd617afebc0
revsetlang: check number of arguments passed to formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35591
diff
changeset
|
675 |
0fd617afebc0
revsetlang: check number of arguments passed to formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35591
diff
changeset
|
676 try: |
0fd617afebc0
revsetlang: check number of arguments passed to formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35591
diff
changeset
|
677 arg = next(argiter) |
0fd617afebc0
revsetlang: check number of arguments passed to formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35591
diff
changeset
|
678 except StopIteration: |
0fd617afebc0
revsetlang: check number of arguments passed to formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35591
diff
changeset
|
679 raise error.ParseError(_('missing argument for revspec')) |
35597
ed0902e8053e
revsetlang: add %p specifier to format list of function arguments
Yuya Nishihara <yuya@tcha.org>
parents:
35596
diff
changeset
|
680 f = _formatlistfuncs.get(d) |
ed0902e8053e
revsetlang: add %p specifier to format list of function arguments
Yuya Nishihara <yuya@tcha.org>
parents:
35596
diff
changeset
|
681 if f: |
35559
a480551bd1b4
revsetlang: unnest "if True" in formatrevspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35558
diff
changeset
|
682 # a list of some type |
a480551bd1b4
revsetlang: unnest "if True" in formatrevspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35558
diff
changeset
|
683 pos += 1 |
35593
850cd045b1df
revsetlang: check incomplete revspec format character
Yuya Nishihara <yuya@tcha.org>
parents:
35592
diff
changeset
|
684 try: |
850cd045b1df
revsetlang: check incomplete revspec format character
Yuya Nishihara <yuya@tcha.org>
parents:
35592
diff
changeset
|
685 d = expr[pos] |
850cd045b1df
revsetlang: check incomplete revspec format character
Yuya Nishihara <yuya@tcha.org>
parents:
35592
diff
changeset
|
686 except IndexError: |
850cd045b1df
revsetlang: check incomplete revspec format character
Yuya Nishihara <yuya@tcha.org>
parents:
35592
diff
changeset
|
687 raise error.ParseError(_('incomplete revspec format character')) |
35594
468d7a1f6633
revsetlang: catch invalid value passed to formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35593
diff
changeset
|
688 try: |
35597
ed0902e8053e
revsetlang: add %p specifier to format list of function arguments
Yuya Nishihara <yuya@tcha.org>
parents:
35596
diff
changeset
|
689 ret.append(f(list(arg), d)) |
35594
468d7a1f6633
revsetlang: catch invalid value passed to formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35593
diff
changeset
|
690 except (TypeError, ValueError): |
468d7a1f6633
revsetlang: catch invalid value passed to formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35593
diff
changeset
|
691 raise error.ParseError(_('invalid argument for revspec')) |
35559
a480551bd1b4
revsetlang: unnest "if True" in formatrevspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35558
diff
changeset
|
692 else: |
35594
468d7a1f6633
revsetlang: catch invalid value passed to formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35593
diff
changeset
|
693 try: |
35596
a57acea31b3b
revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35595
diff
changeset
|
694 ret.append(_formatargtype(d, arg)) |
35594
468d7a1f6633
revsetlang: catch invalid value passed to formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35593
diff
changeset
|
695 except (TypeError, ValueError): |
468d7a1f6633
revsetlang: catch invalid value passed to formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35593
diff
changeset
|
696 raise error.ParseError(_('invalid argument for revspec')) |
14901
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
697 pos += 1 |
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
698 |
35592
0fd617afebc0
revsetlang: check number of arguments passed to formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35591
diff
changeset
|
699 try: |
0fd617afebc0
revsetlang: check number of arguments passed to formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35591
diff
changeset
|
700 next(argiter) |
0fd617afebc0
revsetlang: check number of arguments passed to formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35591
diff
changeset
|
701 raise error.ParseError(_('too many revspec arguments specified')) |
0fd617afebc0
revsetlang: check number of arguments passed to formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35591
diff
changeset
|
702 except StopIteration: |
0fd617afebc0
revsetlang: check number of arguments passed to formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35591
diff
changeset
|
703 pass |
35557
2df8d12f23bc
revsetlang: avoid string concatenation in formatspec()
Yuya Nishihara <yuya@tcha.org>
parents:
35542
diff
changeset
|
704 return ''.join(ret) |
14901
a773119f30ba
revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents:
14900
diff
changeset
|
705 |
16218
81a1a00f5738
debugrevspec: pretty print output
Patrick Mezard <patrick@mezard.eu>
parents:
16185
diff
changeset
|
706 def prettyformat(tree): |
25253
3f1a9b44b8c2
parser: move prettyformat() function from revset module
Yuya Nishihara <yuya@tcha.org>
parents:
25251
diff
changeset
|
707 return parser.prettyformat(tree, ('string', 'symbol')) |
16218
81a1a00f5738
debugrevspec: pretty print output
Patrick Mezard <patrick@mezard.eu>
parents:
16185
diff
changeset
|
708 |
19719
2f9d5c5256ea
revset: add helper function to get revset parse tree depth
Alexander Plavin <alexander@plav.in>
parents:
19706
diff
changeset
|
709 def depth(tree): |
2f9d5c5256ea
revset: add helper function to get revset parse tree depth
Alexander Plavin <alexander@plav.in>
parents:
19706
diff
changeset
|
710 if isinstance(tree, tuple): |
2f9d5c5256ea
revset: add helper function to get revset parse tree depth
Alexander Plavin <alexander@plav.in>
parents:
19706
diff
changeset
|
711 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
|
712 else: |
2f9d5c5256ea
revset: add helper function to get revset parse tree depth
Alexander Plavin <alexander@plav.in>
parents:
19706
diff
changeset
|
713 return 0 |
2f9d5c5256ea
revset: add helper function to get revset parse tree depth
Alexander Plavin <alexander@plav.in>
parents:
19706
diff
changeset
|
714 |
19720
f0b992a9be9c
revset: add helper function to get functions used in a revset parse tree
Alexander Plavin <alexander@plav.in>
parents:
19719
diff
changeset
|
715 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
|
716 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
|
717 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
|
718 else: |
f0b992a9be9c
revset: add helper function to get functions used in a revset parse tree
Alexander Plavin <alexander@plav.in>
parents:
19719
diff
changeset
|
719 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
|
720 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
|
721 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
|
722 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
|
723 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
|
724 return funcs |
35494
dd911f95cbda
revsetlang: add utility function to return hash like symbols from the tree
Pulkit Goyal <7895pulkit@gmail.com>
parents:
34273
diff
changeset
|
725 |
dd911f95cbda
revsetlang: add utility function to return hash like symbols from the tree
Pulkit Goyal <7895pulkit@gmail.com>
parents:
34273
diff
changeset
|
726 _hashre = util.re.compile('[0-9a-fA-F]{1,40}$') |
dd911f95cbda
revsetlang: add utility function to return hash like symbols from the tree
Pulkit Goyal <7895pulkit@gmail.com>
parents:
34273
diff
changeset
|
727 |
dd911f95cbda
revsetlang: add utility function to return hash like symbols from the tree
Pulkit Goyal <7895pulkit@gmail.com>
parents:
34273
diff
changeset
|
728 def _ishashlikesymbol(symbol): |
dd911f95cbda
revsetlang: add utility function to return hash like symbols from the tree
Pulkit Goyal <7895pulkit@gmail.com>
parents:
34273
diff
changeset
|
729 """returns true if the symbol looks like a hash""" |
dd911f95cbda
revsetlang: add utility function to return hash like symbols from the tree
Pulkit Goyal <7895pulkit@gmail.com>
parents:
34273
diff
changeset
|
730 return _hashre.match(symbol) |
dd911f95cbda
revsetlang: add utility function to return hash like symbols from the tree
Pulkit Goyal <7895pulkit@gmail.com>
parents:
34273
diff
changeset
|
731 |
dd911f95cbda
revsetlang: add utility function to return hash like symbols from the tree
Pulkit Goyal <7895pulkit@gmail.com>
parents:
34273
diff
changeset
|
732 def gethashlikesymbols(tree): |
dd911f95cbda
revsetlang: add utility function to return hash like symbols from the tree
Pulkit Goyal <7895pulkit@gmail.com>
parents:
34273
diff
changeset
|
733 """returns the list of symbols of the tree that look like hashes |
dd911f95cbda
revsetlang: add utility function to return hash like symbols from the tree
Pulkit Goyal <7895pulkit@gmail.com>
parents:
34273
diff
changeset
|
734 |
35882
87416288be98
tests: make doctest py3-compatible again
Yuya Nishihara <yuya@tcha.org>
parents:
35822
diff
changeset
|
735 >>> gethashlikesymbols(parse(b'3::abe3ff')) |
35494
dd911f95cbda
revsetlang: add utility function to return hash like symbols from the tree
Pulkit Goyal <7895pulkit@gmail.com>
parents:
34273
diff
changeset
|
736 ['3', 'abe3ff'] |
35882
87416288be98
tests: make doctest py3-compatible again
Yuya Nishihara <yuya@tcha.org>
parents:
35822
diff
changeset
|
737 >>> gethashlikesymbols(parse(b'precursors(.)')) |
35494
dd911f95cbda
revsetlang: add utility function to return hash like symbols from the tree
Pulkit Goyal <7895pulkit@gmail.com>
parents:
34273
diff
changeset
|
738 [] |
35882
87416288be98
tests: make doctest py3-compatible again
Yuya Nishihara <yuya@tcha.org>
parents:
35822
diff
changeset
|
739 >>> gethashlikesymbols(parse(b'precursors(34)')) |
35494
dd911f95cbda
revsetlang: add utility function to return hash like symbols from the tree
Pulkit Goyal <7895pulkit@gmail.com>
parents:
34273
diff
changeset
|
740 ['34'] |
35882
87416288be98
tests: make doctest py3-compatible again
Yuya Nishihara <yuya@tcha.org>
parents:
35822
diff
changeset
|
741 >>> gethashlikesymbols(parse(b'abe3ffZ')) |
35494
dd911f95cbda
revsetlang: add utility function to return hash like symbols from the tree
Pulkit Goyal <7895pulkit@gmail.com>
parents:
34273
diff
changeset
|
742 [] |
dd911f95cbda
revsetlang: add utility function to return hash like symbols from the tree
Pulkit Goyal <7895pulkit@gmail.com>
parents:
34273
diff
changeset
|
743 """ |
dd911f95cbda
revsetlang: add utility function to return hash like symbols from the tree
Pulkit Goyal <7895pulkit@gmail.com>
parents:
34273
diff
changeset
|
744 if not tree: |
dd911f95cbda
revsetlang: add utility function to return hash like symbols from the tree
Pulkit Goyal <7895pulkit@gmail.com>
parents:
34273
diff
changeset
|
745 return [] |
dd911f95cbda
revsetlang: add utility function to return hash like symbols from the tree
Pulkit Goyal <7895pulkit@gmail.com>
parents:
34273
diff
changeset
|
746 |
dd911f95cbda
revsetlang: add utility function to return hash like symbols from the tree
Pulkit Goyal <7895pulkit@gmail.com>
parents:
34273
diff
changeset
|
747 if tree[0] == "symbol": |
dd911f95cbda
revsetlang: add utility function to return hash like symbols from the tree
Pulkit Goyal <7895pulkit@gmail.com>
parents:
34273
diff
changeset
|
748 if _ishashlikesymbol(tree[1]): |
dd911f95cbda
revsetlang: add utility function to return hash like symbols from the tree
Pulkit Goyal <7895pulkit@gmail.com>
parents:
34273
diff
changeset
|
749 return [tree[1]] |
dd911f95cbda
revsetlang: add utility function to return hash like symbols from the tree
Pulkit Goyal <7895pulkit@gmail.com>
parents:
34273
diff
changeset
|
750 elif len(tree) >= 3: |
dd911f95cbda
revsetlang: add utility function to return hash like symbols from the tree
Pulkit Goyal <7895pulkit@gmail.com>
parents:
34273
diff
changeset
|
751 results = [] |
dd911f95cbda
revsetlang: add utility function to return hash like symbols from the tree
Pulkit Goyal <7895pulkit@gmail.com>
parents:
34273
diff
changeset
|
752 for subtree in tree[1:]: |
dd911f95cbda
revsetlang: add utility function to return hash like symbols from the tree
Pulkit Goyal <7895pulkit@gmail.com>
parents:
34273
diff
changeset
|
753 results += gethashlikesymbols(subtree) |
dd911f95cbda
revsetlang: add utility function to return hash like symbols from the tree
Pulkit Goyal <7895pulkit@gmail.com>
parents:
34273
diff
changeset
|
754 return results |
dd911f95cbda
revsetlang: add utility function to return hash like symbols from the tree
Pulkit Goyal <7895pulkit@gmail.com>
parents:
34273
diff
changeset
|
755 return [] |