annotate mercurial/revsetlang.py @ 49012:5b65721a75eb

revlog: recommit 49fd21f32695 with a fix for issue6528 `filelog.size` currently special cases two forms of metadata encoding: - copy data via the parent order as flag bit - censor data by peaking into the raw delta All other forms of metadata encoding including the empty metadata block are mishandled. In `basefilectx.cmp` the empty metadata block is explicitly checked to compensate for this. Restore 49fd21f32695, but disable it for filelog, so that the original flag bit use contines to work. Document all this mess for now in preparation of a proper rework. Differential Revision: https://phab.mercurial-scm.org/D11203
author Joerg Sonnenberger <joerg@bec.de>
date Tue, 20 Jul 2021 15:07:10 +0200
parents f254fc73d956
children d44e3c45f0e4
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
2 #
46819
d4ba4d51f85f contributor: change mentions of mpm to olivia
Raphaël Gomès <rgomes@octobus.net>
parents: 46113
diff changeset
3 # Copyright 2010 Olivia Mackall <olivia@selenic.com>
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
4 #
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
5 # This software may be used and distributed according to the terms of the
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
6 # GNU General Public License version 2 or any later version.
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
7
25971
e9cd028f2dff revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25929
diff changeset
8
30071
2def3d55b1b9 revset: build _syminitletters from a saner source: the string module
Augie Fackler <augie@google.com>
parents: 30056
diff changeset
9 import string
25971
e9cd028f2dff revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25929
diff changeset
10
e9cd028f2dff revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25929
diff changeset
11 from .i18n import _
43089
c59eb1560c44 py3: manually import getattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43077
diff changeset
12 from .pycompat import getattr
46113
59fa3890d40a node: import symbols explicitly
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
13 from .node import hex
25971
e9cd028f2dff revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25929
diff changeset
14 from . import (
e9cd028f2dff revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25929
diff changeset
15 error,
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,
41221
73203cdfe3fe revset: detect integer list on parsing
Boris Feld <boris.feld@octobus.net>
parents: 41220
diff changeset
18 smartset,
31606
0b3eb280564b revsetlang: perform quoting using ui.escapestr instead of repr()
Augie Fackler <augie@google.com>
parents: 31605
diff changeset
19 util,
25971
e9cd028f2dff revset: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25929
diff changeset
20 )
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
21 from .utils import stringutil
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
22
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
23 elements = {
25815
e71e5629e006 parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents: 25801
diff changeset
24 # token-type: binding-strength, primary, prefix, infix, suffix
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
25 b"(": (21, None, (b"group", 1, b")"), (b"func", 1, b")"), None),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
26 b"[": (21, None, None, (b"subscript", 1, b"]"), None),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
27 b"#": (21, None, None, (b"relation", 21), None),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
28 b"##": (20, None, None, (b"_concat", 20), None),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
29 b"~": (18, None, None, (b"ancestor", 18), None),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
30 b"^": (18, None, None, (b"parent", 18), b"parentpost"),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
31 b"-": (5, None, (b"negate", 19), (b"minus", 5), None),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
32 b"::": (
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
33 17,
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
34 b"dagrangeall",
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
35 (b"dagrangepre", 17),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
36 (b"dagrange", 17),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
37 b"dagrangepost",
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
38 ),
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
39 b"..": (
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
40 17,
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
41 b"dagrangeall",
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
42 (b"dagrangepre", 17),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
43 (b"dagrange", 17),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
44 b"dagrangepost",
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
45 ),
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
46 b":": (15, b"rangeall", (b"rangepre", 15), (b"range", 15), b"rangepost"),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
47 b"not": (10, None, (b"not", 10), None, None),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
48 b"!": (10, None, (b"not", 10), None, None),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
49 b"and": (5, None, None, (b"and", 5), None),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
50 b"&": (5, None, None, (b"and", 5), None),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
51 b"%": (5, None, None, (b"only", 5), b"onlypost"),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
52 b"or": (4, None, None, (b"or", 4), None),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
53 b"|": (4, None, None, (b"or", 4), None),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
54 b"+": (4, None, None, (b"or", 4), None),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
55 b"=": (3, None, None, (b"keyvalue", 3), None),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
56 b",": (2, None, None, (b"list", 2), None),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
57 b")": (0, None, None, None, None),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
58 b"]": (0, None, None, None, None),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
59 b"symbol": (0, b"symbol", None, None, None),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
60 b"string": (0, b"string", None, None, None),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
61 b"end": (0, None, None, None, None),
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
62 }
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
63
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
64 keywords = {b'and', b'or', b'not'}
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
65
34273
b0790bebfcf8 revset: move weight information to predicate
Jun Wu <quark@fb.com>
parents: 34272
diff changeset
66 symbols = {}
b0790bebfcf8 revset: move weight information to predicate
Jun Wu <quark@fb.com>
parents: 34272
diff changeset
67
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
68 _quoteletters = {b'"', b"'"}
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
69 _simpleopletters = set(pycompat.iterbytestr(b"()[]#:=,-|&+!~^%"))
31384
fac5cd3b8673 py3: make set of revset operators and quotes in bytes
Yuya Nishihara <yuya@tcha.org>
parents: 31383
diff changeset
70
23842
91dbb98b3513 revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23836
diff changeset
71 # default set of valid characters for the initial letter of symbols
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
72 _syminitletters = set(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
73 pycompat.iterbytestr(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
74 pycompat.sysbytes(string.ascii_letters)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
75 + pycompat.sysbytes(string.digits)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
76 + b'._@'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
77 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
78 ) | set(map(pycompat.bytechr, pycompat.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
79
91dbb98b3513 revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23836
diff changeset
80 # default set of valid characters for non-initial letters of symbols
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
81 _symletters = _syminitletters | set(pycompat.iterbytestr(b'-/'))
23842
91dbb98b3513 revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23836
diff changeset
82
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
83
23842
91dbb98b3513 revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23836
diff changeset
84 def tokenize(program, lookup=None, syminitletters=None, symletters=None):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45886
diff changeset
85 """
17886
d8905e2c1301 revset: accept @ in unquoted symbols (issue3686)
Matt Mackall <mpm@selenic.com>
parents: 17829
diff changeset
86 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
87
23842
91dbb98b3513 revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23836
diff changeset
88 ``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
89 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
90
91dbb98b3513 revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23836
diff changeset
91 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
92 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
93
91dbb98b3513 revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23836
diff changeset
94 ``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
95 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
96
91dbb98b3513 revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23836
diff changeset
97 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
98 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
99
17886
d8905e2c1301 revset: accept @ in unquoted symbols (issue3686)
Matt Mackall <mpm@selenic.com>
parents: 17829
diff changeset
100 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
101 >>> list(tokenize(b"@::"))
17886
d8905e2c1301 revset: accept @ in unquoted symbols (issue3686)
Matt Mackall <mpm@selenic.com>
parents: 17829
diff changeset
102 [('symbol', '@', 0), ('::', None, 1), ('end', None, 3)]
d8905e2c1301 revset: accept @ in unquoted symbols (issue3686)
Matt Mackall <mpm@selenic.com>
parents: 17829
diff changeset
103
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45886
diff changeset
104 """
37775
03d7f885d5f2 revsetlang: do not pass in non-bytes to parse()
Yuya Nishihara <yuya@tcha.org>
parents: 37760
diff changeset
105 if not isinstance(program, bytes):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
106 raise error.ProgrammingError(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
107 b'revset statement must be bytes, got %r' % program
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
108 )
31441
80c8a6db450d py3: use bytestr wrapper in revsetlang.tokenize()
Yuya Nishihara <yuya@tcha.org>
parents: 31440
diff changeset
109 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
110 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
111 syminitletters = _syminitletters
91dbb98b3513 revset: make tokenize extensible to parse alias declarations and definitions
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23836
diff changeset
112 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
113 symletters = _symletters
17886
d8905e2c1301 revset: accept @ in unquoted symbols (issue3686)
Matt Mackall <mpm@selenic.com>
parents: 17829
diff changeset
114
25902
5214cbdc37e5 revset: port parsing rule of old-style ranges from scmutil.revrange()
Yuya Nishihara <yuya@tcha.org>
parents: 25819
diff changeset
115 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
116 # 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
117 # things like old-tag which contain query metacharacters
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
118 parts = program.split(b':', 1)
25902
5214cbdc37e5 revset: port parsing rule of old-style ranges from scmutil.revrange()
Yuya Nishihara <yuya@tcha.org>
parents: 25819
diff changeset
119 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
120 if parts[0]:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
121 yield (b'symbol', parts[0], 0)
25902
5214cbdc37e5 revset: port parsing rule of old-style ranges from scmutil.revrange()
Yuya Nishihara <yuya@tcha.org>
parents: 25819
diff changeset
122 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
123 s = len(parts[0])
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
124 yield (b':', None, s)
25902
5214cbdc37e5 revset: port parsing rule of old-style ranges from scmutil.revrange()
Yuya Nishihara <yuya@tcha.org>
parents: 25819
diff changeset
125 if parts[1]:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
126 yield (b'symbol', parts[1], s + 1)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
127 yield (b'end', None, len(program))
25902
5214cbdc37e5 revset: port parsing rule of old-style ranges from scmutil.revrange()
Yuya Nishihara <yuya@tcha.org>
parents: 25819
diff changeset
128 return
5214cbdc37e5 revset: port parsing rule of old-style ranges from scmutil.revrange()
Yuya Nishihara <yuya@tcha.org>
parents: 25819
diff changeset
129
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
130 pos, l = 0, len(program)
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
131 while pos < l:
31441
80c8a6db450d py3: use bytestr wrapper in revsetlang.tokenize()
Yuya Nishihara <yuya@tcha.org>
parents: 31440
diff changeset
132 c = program[pos]
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
133 if c.isspace(): # skip inter-token whitespace
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
134 pass
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
135 elif (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
136 c == b':' and program[pos : pos + 2] == b'::'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
137 ): # look ahead carefully
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
138 yield (b'::', None, pos)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
139 pos += 1 # skip ahead
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
140 elif (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
141 c == b'.' and program[pos : pos + 2] == b'..'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
142 ): # look ahead carefully
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
143 yield (b'..', None, pos)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
144 pos += 1 # skip ahead
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
145 elif (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
146 c == b'#' and program[pos : pos + 2] == b'##'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
147 ): # look ahead carefully
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
148 yield (b'##', None, pos)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
149 pos += 1 # skip ahead
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
150 elif c in _simpleopletters: # handle simple operators
11289
4215ce511134 revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents: 11284
diff changeset
151 yield (c, None, pos)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
152 elif (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
153 c in _quoteletters
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
154 or c == b'r'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
155 and program[pos : pos + 2] in (b"r'", b'r"')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
156 ): # handle quoted strings
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
157 if c == b'r':
12408
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
158 pos += 1
31441
80c8a6db450d py3: use bytestr wrapper in revsetlang.tokenize()
Yuya Nishihara <yuya@tcha.org>
parents: 31440
diff changeset
159 c = program[pos]
12408
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
160 decode = lambda x: x
78a97859b90d revset: support raw string literals
Brodie Rao <brodie@bitheap.org>
parents: 12401
diff changeset
161 else:
26232
43f9976346e9 revset: handle error of string unescaping
Yuya Nishihara <yuya@tcha.org>
parents: 26212
diff changeset
162 decode = parser.unescapestr
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
163 pos += 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
164 s = pos
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
165 while pos < l: # find closing quote
31441
80c8a6db450d py3: use bytestr wrapper in revsetlang.tokenize()
Yuya Nishihara <yuya@tcha.org>
parents: 31440
diff changeset
166 d = program[pos]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
167 if d == b'\\': # skip over escaped characters
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
168 pos += 2
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
169 continue
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
170 if d == c:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
171 yield (b'string', decode(program[s:pos]), s)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
172 break
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
173 pos += 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
174 else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
175 raise error.ParseError(_(b"unterminated string"), s)
16683
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16661
diff changeset
176 # 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
177 elif c in syminitletters:
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
178 s = pos
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
179 pos += 1
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
180 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
181 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
182 if d not in symletters:
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
183 break
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
184 if (
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
185 d == b'.' and program[pos - 1] == b'.'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
186 ): # special case for ..
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
187 pos -= 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
188 break
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
189 pos += 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
190 sym = program[s:pos]
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
191 if sym in keywords: # operator keywords
11289
4215ce511134 revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents: 11284
diff changeset
192 yield (sym, None, s)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
193 elif b'-' in sym:
20780
403f1f73d30f revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents: 20779
diff changeset
194 # 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
195 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
196 # looks like a real symbol
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
197 yield (b'symbol', sym, s)
20780
403f1f73d30f revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents: 20779
diff changeset
198 else:
403f1f73d30f revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents: 20779
diff changeset
199 # looks like an expression
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
200 parts = sym.split(b'-')
20780
403f1f73d30f revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents: 20779
diff changeset
201 for p in parts[:-1]:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
202 if p: # possible consecutive -
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
203 yield (b'symbol', p, s)
20780
403f1f73d30f revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents: 20779
diff changeset
204 s += len(p)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
205 yield (b'-', None, s)
20780
403f1f73d30f revset: try to handle hyphenated symbols if lookup callback is available
Matt Mackall <mpm@selenic.com>
parents: 20779
diff changeset
206 s += 1
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
207 if parts[-1]: # possible trailing -
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
208 yield (b'symbol', parts[-1], s)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
209 else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
210 yield (b'symbol', sym, s)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
211 pos -= 1
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
212 else:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
213 raise error.ParseError(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
214 _(b"syntax error in revset '%s'") % program, pos
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
215 )
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
216 pos += 1
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
217 yield (b'end', None, pos)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
218
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
219
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
220 # helpers
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
221
30802
5eb3e4568c94 revset: add default value to getinteger() helper
Yuya Nishihara <yuya@tcha.org>
parents: 30801
diff changeset
222 _notset = object()
5eb3e4568c94 revset: add default value to getinteger() helper
Yuya Nishihara <yuya@tcha.org>
parents: 30801
diff changeset
223
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
224
29441
9e8d258708bb revset: check invalid function syntax "func-name"() explicitly
Yuya Nishihara <yuya@tcha.org>
parents: 29425
diff changeset
225 def getsymbol(x):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
226 if x and x[0] == b'symbol':
29441
9e8d258708bb revset: check invalid function syntax "func-name"() explicitly
Yuya Nishihara <yuya@tcha.org>
parents: 29425
diff changeset
227 return x[1]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
228 raise error.ParseError(_(b'not a symbol'))
29441
9e8d258708bb revset: check invalid function syntax "func-name"() explicitly
Yuya Nishihara <yuya@tcha.org>
parents: 29425
diff changeset
229
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
230
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
231 def getstring(x, err):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
232 if x and (x[0] == b'string' or x[0] == b'symbol'):
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
233 return x[1]
11289
4215ce511134 revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents: 11284
diff changeset
234 raise error.ParseError(err)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
235
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
236
30802
5eb3e4568c94 revset: add default value to getinteger() helper
Yuya Nishihara <yuya@tcha.org>
parents: 30801
diff changeset
237 def getinteger(x, err, default=_notset):
5eb3e4568c94 revset: add default value to getinteger() helper
Yuya Nishihara <yuya@tcha.org>
parents: 30801
diff changeset
238 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
239 return default
30801
67ee7874e53b revset: factor out getinteger() helper
Yuya Nishihara <yuya@tcha.org>
parents: 30800
diff changeset
240 try:
67ee7874e53b revset: factor out getinteger() helper
Yuya Nishihara <yuya@tcha.org>
parents: 30800
diff changeset
241 return int(getstring(x, err))
67ee7874e53b revset: factor out getinteger() helper
Yuya Nishihara <yuya@tcha.org>
parents: 30800
diff changeset
242 except ValueError:
67ee7874e53b revset: factor out getinteger() helper
Yuya Nishihara <yuya@tcha.org>
parents: 30800
diff changeset
243 raise error.ParseError(err)
67ee7874e53b revset: factor out getinteger() helper
Yuya Nishihara <yuya@tcha.org>
parents: 30800
diff changeset
244
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
245
31997
11f501f0a213 revsetlang: add a getboolean helper function
Denis Laxalde <denis@laxalde.org>
parents: 31800
diff changeset
246 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
247 value = stringutil.parsebool(getsymbol(x))
31997
11f501f0a213 revsetlang: add a getboolean helper function
Denis Laxalde <denis@laxalde.org>
parents: 31800
diff changeset
248 if value is not None:
11f501f0a213 revsetlang: add a getboolean helper function
Denis Laxalde <denis@laxalde.org>
parents: 31800
diff changeset
249 return value
11f501f0a213 revsetlang: add a getboolean helper function
Denis Laxalde <denis@laxalde.org>
parents: 31800
diff changeset
250 raise error.ParseError(err)
11f501f0a213 revsetlang: add a getboolean helper function
Denis Laxalde <denis@laxalde.org>
parents: 31800
diff changeset
251
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
252
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
253 def getlist(x):
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
254 if not x:
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
255 return []
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
256 if x[0] == b'list':
27987
b19d8d5d6b51 revset: flatten chained 'list' operations (aka function args) (issue5072)
Yuya Nishihara <yuya@tcha.org>
parents: 27945
diff changeset
257 return list(x[1:])
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
258 return [x]
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
259
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
260
30804
4227f80f72b2 revset: abuse x:y syntax to specify line range of followlines()
Yuya Nishihara <yuya@tcha.org>
parents: 30803
diff changeset
261 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
262 if not x:
4227f80f72b2 revset: abuse x:y syntax to specify line range of followlines()
Yuya Nishihara <yuya@tcha.org>
parents: 30803
diff changeset
263 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
264 op = x[0]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
265 if op == b'range':
30804
4227f80f72b2 revset: abuse x:y syntax to specify line range of followlines()
Yuya Nishihara <yuya@tcha.org>
parents: 30803
diff changeset
266 return x[1], x[2]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
267 elif op == b'rangepre':
30804
4227f80f72b2 revset: abuse x:y syntax to specify line range of followlines()
Yuya Nishihara <yuya@tcha.org>
parents: 30803
diff changeset
268 return None, x[1]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
269 elif op == b'rangepost':
30804
4227f80f72b2 revset: abuse x:y syntax to specify line range of followlines()
Yuya Nishihara <yuya@tcha.org>
parents: 30803
diff changeset
270 return x[1], None
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
271 elif op == b'rangeall':
30804
4227f80f72b2 revset: abuse x:y syntax to specify line range of followlines()
Yuya Nishihara <yuya@tcha.org>
parents: 30803
diff changeset
272 return None, None
4227f80f72b2 revset: abuse x:y syntax to specify line range of followlines()
Yuya Nishihara <yuya@tcha.org>
parents: 30803
diff changeset
273 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
274
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
275
41561
59638c6fcb70 revset: extract a helper to parse integer range
Yuya Nishihara <yuya@tcha.org>
parents: 41297
diff changeset
276 def getintrange(x, err1, err2, deffirst=_notset, deflast=_notset):
59638c6fcb70 revset: extract a helper to parse integer range
Yuya Nishihara <yuya@tcha.org>
parents: 41297
diff changeset
277 """Get [first, last] integer range (both inclusive) from a parsed tree
59638c6fcb70 revset: extract a helper to parse integer range
Yuya Nishihara <yuya@tcha.org>
parents: 41297
diff changeset
278
59638c6fcb70 revset: extract a helper to parse integer range
Yuya Nishihara <yuya@tcha.org>
parents: 41297
diff changeset
279 If any of the sides omitted, and if no default provided, ParseError will
59638c6fcb70 revset: extract a helper to parse integer range
Yuya Nishihara <yuya@tcha.org>
parents: 41297
diff changeset
280 be raised.
59638c6fcb70 revset: extract a helper to parse integer range
Yuya Nishihara <yuya@tcha.org>
parents: 41297
diff changeset
281 """
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
282 if x and (x[0] == b'string' or x[0] == b'symbol'):
41562
1c04894e8fe1 revset: allow to parse single integer as a range
Yuya Nishihara <yuya@tcha.org>
parents: 41561
diff changeset
283 n = getinteger(x, err1)
1c04894e8fe1 revset: allow to parse single integer as a range
Yuya Nishihara <yuya@tcha.org>
parents: 41561
diff changeset
284 return n, n
41561
59638c6fcb70 revset: extract a helper to parse integer range
Yuya Nishihara <yuya@tcha.org>
parents: 41297
diff changeset
285 a, b = getrange(x, err1)
59638c6fcb70 revset: extract a helper to parse integer range
Yuya Nishihara <yuya@tcha.org>
parents: 41297
diff changeset
286 return getinteger(a, err2, deffirst), getinteger(b, err2, deflast)
59638c6fcb70 revset: extract a helper to parse integer range
Yuya Nishihara <yuya@tcha.org>
parents: 41297
diff changeset
287
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
288
11339
744d5b73f776 revset: improve filter argument handling
Matt Mackall <mpm@selenic.com>
parents: 11304
diff changeset
289 def getargs(x, min, max, err):
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
290 l = getlist(x)
16161
5a627b49b4d9 graphlog: paths/-I/-X handling requires a new revset
Patrick Mezard <patrick@mezard.eu>
parents: 16096
diff changeset
291 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
292 raise error.ParseError(err)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
293 return l
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
294
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
295
25767
026105c442d7 revset: rename getkwargs() to getargsdict()
Yuya Nishihara <yuya@tcha.org>
parents: 25766
diff changeset
296 def getargsdict(x, funcname, keys):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
297 return parser.buildargsdict(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
298 getlist(x),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
299 funcname,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
300 parser.splitargspec(keys),
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
301 keyvaluenode=b'keyvalue',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
302 keynode=b'symbol',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
303 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
304
25705
48919d246a47 revset: add function to build dict of positional and keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents: 25704
diff changeset
305
34044
b862e6fca7ac revsetlang: build optimized tree by helper function
Yuya Nishihara <yuya@tcha.org>
parents: 34020
diff changeset
306 # 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
307 _treecache = {}
b862e6fca7ac revsetlang: build optimized tree by helper function
Yuya Nishihara <yuya@tcha.org>
parents: 34020
diff changeset
308
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
309
34044
b862e6fca7ac revsetlang: build optimized tree by helper function
Yuya Nishihara <yuya@tcha.org>
parents: 34020
diff changeset
310 def _cachedtree(spec):
b862e6fca7ac revsetlang: build optimized tree by helper function
Yuya Nishihara <yuya@tcha.org>
parents: 34020
diff changeset
311 # 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
312 tree = _treecache.get(spec)
b862e6fca7ac revsetlang: build optimized tree by helper function
Yuya Nishihara <yuya@tcha.org>
parents: 34020
diff changeset
313 if tree is None:
b862e6fca7ac revsetlang: build optimized tree by helper function
Yuya Nishihara <yuya@tcha.org>
parents: 34020
diff changeset
314 _treecache[spec] = tree = parse(spec)
b862e6fca7ac revsetlang: build optimized tree by helper function
Yuya Nishihara <yuya@tcha.org>
parents: 34020
diff changeset
315 return tree
b862e6fca7ac revsetlang: build optimized tree by helper function
Yuya Nishihara <yuya@tcha.org>
parents: 34020
diff changeset
316
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
317
34044
b862e6fca7ac revsetlang: build optimized tree by helper function
Yuya Nishihara <yuya@tcha.org>
parents: 34020
diff changeset
318 def _build(tmplspec, *repls):
b862e6fca7ac revsetlang: build optimized tree by helper function
Yuya Nishihara <yuya@tcha.org>
parents: 34020
diff changeset
319 """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
320
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34069
diff changeset
321 >>> _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
322 ('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
323 """
b862e6fca7ac revsetlang: build optimized tree by helper function
Yuya Nishihara <yuya@tcha.org>
parents: 34020
diff changeset
324 template = _cachedtree(tmplspec)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
325 return parser.buildtree(template, (b'symbol', b'_'), *repls)
34044
b862e6fca7ac revsetlang: build optimized tree by helper function
Yuya Nishihara <yuya@tcha.org>
parents: 34020
diff changeset
326
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
327
34046
f23cbca9b277 revsetlang: match tree by helper function on optimize
Yuya Nishihara <yuya@tcha.org>
parents: 34044
diff changeset
328 def _match(patspec, tree):
f23cbca9b277 revsetlang: match tree by helper function on optimize
Yuya Nishihara <yuya@tcha.org>
parents: 34044
diff changeset
329 """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
330
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34069
diff changeset
331 >>> _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
332 >>> _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
333 [('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
334 >>> _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
335 """
f23cbca9b277 revsetlang: match tree by helper function on optimize
Yuya Nishihara <yuya@tcha.org>
parents: 34044
diff changeset
336 pattern = _cachedtree(patspec)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
337 return parser.matchtree(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
338 pattern, tree, (b'symbol', b'_'), {b'keyvalue', b'list'}
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
339 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
340
34046
f23cbca9b277 revsetlang: match tree by helper function on optimize
Yuya Nishihara <yuya@tcha.org>
parents: 34044
diff changeset
341
29117
7828cadd2873 revset: construct arguments of only() against matched tree
Yuya Nishihara <yuya@tcha.org>
parents: 29116
diff changeset
342 def _matchonly(revs, bases):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
343 return _match(b'ancestors(_) and not ancestors(_)', (b'and', revs, bases))
29116
0c9b05dae010 revset: unnest isonly() closure from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29098
diff changeset
344
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
345
29769
abe4eecc3253 revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents: 29767
diff changeset
346 def _fixops(x):
abe4eecc3253 revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents: 29767
diff changeset
347 """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
348 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
349 if not isinstance(x, tuple):
abe4eecc3253 revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents: 29767
diff changeset
350 return x
abe4eecc3253 revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents: 29767
diff changeset
351
abe4eecc3253 revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents: 29767
diff changeset
352 op = x[0]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
353 if op == b'parent':
29769
abe4eecc3253 revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents: 29767
diff changeset
354 # 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
355 # x^: means (x^) :, not x ^ (:)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
356 post = (b'parentpost', x[1])
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
357 if x[2][0] == b'dagrangepre':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
358 return _fixops((b'dagrange', post, x[2][1]))
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
359 elif x[2][0] == b'dagrangeall':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
360 return _fixops((b'dagrangepost', post))
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
361 elif x[2][0] == b'rangepre':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
362 return _fixops((b'range', post, x[2][1]))
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
363 elif x[2][0] == b'rangeall':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
364 return _fixops((b'rangepost', post))
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
365 elif op == b'or':
29929
b3845cab4ddc revset: wrap arguments of 'or' by 'list' node
Yuya Nishihara <yuya@tcha.org>
parents: 29922
diff changeset
366 # make number of arguments deterministic:
b3845cab4ddc revset: wrap arguments of 'or' by 'list' node
Yuya Nishihara <yuya@tcha.org>
parents: 29922
diff changeset
367 # x + y + z -> (or x y z) -> (or (list x y z))
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
368 return (op, _fixops((b'list',) + x[1:]))
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
369 elif op == b'subscript' and x[1][0] == b'relation':
33416
9467d5337292 revset: add experimental relation and subscript operators
Yuya Nishihara <yuya@tcha.org>
parents: 33415
diff changeset
370 # x#y[z] ternary
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
371 return _fixops((b'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
372
abe4eecc3253 revset: resolve ambiguity of x^:y before alias expansion
Yuya Nishihara <yuya@tcha.org>
parents: 29767
diff changeset
373 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
374
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
375
34011
1b28525e6698 revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents: 34010
diff changeset
376 def _analyze(x):
29904
e4b4168a4f1c revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29898
diff changeset
377 if x is None:
e4b4168a4f1c revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29898
diff changeset
378 return x
e4b4168a4f1c revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29898
diff changeset
379
e4b4168a4f1c revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29898
diff changeset
380 op = x[0]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
381 if op == b'minus':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
382 return _analyze(_build(b'_ and not _', *x[1:]))
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
383 elif op == b'only':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
384 return _analyze(_build(b'only(_, _)', *x[1:]))
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
385 elif op == b'onlypost':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
386 return _analyze(_build(b'only(_)', x[1]))
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
387 elif op == b'dagrangeall':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
388 raise error.ParseError(_(b"can't use '::' in this context"))
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
389 elif op == b'dagrangepre':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
390 return _analyze(_build(b'ancestors(_)', x[1]))
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
391 elif op == b'dagrangepost':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
392 return _analyze(_build(b'descendants(_)', x[1]))
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
393 elif op == b'negate':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
394 s = getstring(x[1], _(b"can't negate that"))
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
395 return _analyze((b'string', b'-' + s))
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
396 elif op in (b'string', b'symbol', b'smartset'):
29904
e4b4168a4f1c revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29898
diff changeset
397 return x
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
398 elif op == b'rangeall':
34011
1b28525e6698 revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents: 34010
diff changeset
399 return (op, None)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
400 elif op in {b'or', b'not', b'rangepre', b'rangepost', b'parentpost'}:
34011
1b28525e6698 revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents: 34010
diff changeset
401 return (op, _analyze(x[1]))
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
402 elif op == b'group':
34011
1b28525e6698 revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents: 34010
diff changeset
403 return _analyze(x[1])
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
404 elif op in {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
405 b'and',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
406 b'dagrange',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
407 b'range',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
408 b'parent',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
409 b'ancestor',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
410 b'relation',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
411 b'subscript',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
412 }:
34011
1b28525e6698 revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents: 34010
diff changeset
413 ta = _analyze(x[1])
1b28525e6698 revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents: 34010
diff changeset
414 tb = _analyze(x[2])
1b28525e6698 revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents: 34010
diff changeset
415 return (op, ta, tb)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
416 elif op == b'relsubscript':
34011
1b28525e6698 revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents: 34010
diff changeset
417 ta = _analyze(x[1])
1b28525e6698 revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents: 34010
diff changeset
418 tb = _analyze(x[2])
1b28525e6698 revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents: 34010
diff changeset
419 tc = _analyze(x[3])
1b28525e6698 revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents: 34010
diff changeset
420 return (op, ta, tb, tc)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
421 elif op == b'list':
34011
1b28525e6698 revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents: 34010
diff changeset
422 return (op,) + tuple(_analyze(y) for y in x[1:])
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
423 elif op == b'keyvalue':
34011
1b28525e6698 revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents: 34010
diff changeset
424 return (op, x[1], _analyze(x[2]))
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
425 elif op == b'func':
34011
1b28525e6698 revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents: 34010
diff changeset
426 return (op, x[1], _analyze(x[2]))
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
427 raise ValueError(b'invalid operator %r' % op)
29904
e4b4168a4f1c revset: extract tree transformation from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29898
diff changeset
428
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
429
34011
1b28525e6698 revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents: 34010
diff changeset
430 def analyze(x):
29905
371c2a39eead revset: make analyze() a separate step from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29904
diff changeset
431 """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
432 optimize() or getset()
371c2a39eead revset: make analyze() a separate step from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29904
diff changeset
433
371c2a39eead revset: make analyze() a separate step from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29904
diff changeset
434 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
435 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
436 """
34011
1b28525e6698 revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents: 34010
diff changeset
437 return _analyze(x)
29905
371c2a39eead revset: make analyze() a separate step from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29904
diff changeset
438
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
439
34272
53fb09c73ba8 revset: remove "small" argument from "_optimize"
Jun Wu <quark@fb.com>
parents: 34131
diff changeset
440 def _optimize(x):
13031
3da456d0c885 code style: prefer 'is' and 'is not' tests with singletons
Martin Geisler <mg@aragost.com>
parents: 12936
diff changeset
441 if x is None:
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
442 return 0, x
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
443
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
444 op = x[0]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
445 if op in (b'string', b'symbol', b'smartset'):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
446 return 0.5, x # single revisions are small
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
447 elif op == b'and':
34272
53fb09c73ba8 revset: remove "small" argument from "_optimize"
Jun Wu <quark@fb.com>
parents: 34131
diff changeset
448 wa, ta = _optimize(x[1])
53fb09c73ba8 revset: remove "small" argument from "_optimize"
Jun Wu <quark@fb.com>
parents: 34131
diff changeset
449 wb, tb = _optimize(x[2])
29116
0c9b05dae010 revset: unnest isonly() closure from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29098
diff changeset
450 w = min(wa, wb)
20499
2efd608473fb revset: optimize missing ancestor expressions
Siddharth Agarwal <sid0@fb.com>
parents: 20498
diff changeset
451
34065
c6c8a52e28c9 revset: optimize "draft() & ::x" pattern
Jun Wu <quark@fb.com>
parents: 34047
diff changeset
452 # (draft/secret/_notpublic() & ::x) have a fast path
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
453 m = _match(b'_() & ancestors(_)', (b'and', ta, tb))
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
454 if m and getsymbol(m[1]) in {b'draft', b'secret', b'_notpublic'}:
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
455 return w, _build(b'_phaseandancestors(_, _)', m[1], m[2])
34065
c6c8a52e28c9 revset: optimize "draft() & ::x" pattern
Jun Wu <quark@fb.com>
parents: 34047
diff changeset
456
20499
2efd608473fb revset: optimize missing ancestor expressions
Siddharth Agarwal <sid0@fb.com>
parents: 20498
diff changeset
457 # (::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
458 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
459 if m:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
460 return w, _build(b'only(_, _)', *m[1:])
20499
2efd608473fb revset: optimize missing ancestor expressions
Siddharth Agarwal <sid0@fb.com>
parents: 20498
diff changeset
461
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
462 m = _match(b'not _', tb)
34046
f23cbca9b277 revsetlang: match tree by helper function on optimize
Yuya Nishihara <yuya@tcha.org>
parents: 34044
diff changeset
463 if m:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
464 return wa, (b'difference', ta, m[1])
11279
62ccf4cd6e7f revset: optimize the parse tree directly
Matt Mackall <mpm@selenic.com>
parents: 11278
diff changeset
465 if wa > wb:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
466 op = b'andsmally'
34011
1b28525e6698 revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents: 34010
diff changeset
467 return w, (op, ta, tb)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
468 elif op == b'or':
25343
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
469 # 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
470 # 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
471 ws, ts, ss = [], [], []
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
472
25343
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
473 def flushss():
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
474 if not ss:
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
475 return
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
476 if len(ss) == 1:
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
477 w, t = ss[0]
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
478 else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
479 s = b'\0'.join(t[1] for w, t in ss)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
480 y = _build(b'_list(_)', (b'string', s))
34272
53fb09c73ba8 revset: remove "small" argument from "_optimize"
Jun Wu <quark@fb.com>
parents: 34131
diff changeset
481 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
482 ws.append(w)
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
483 ts.append(t)
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
484 del ss[:]
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
485
29929
b3845cab4ddc revset: wrap arguments of 'or' by 'list' node
Yuya Nishihara <yuya@tcha.org>
parents: 29922
diff changeset
486 for y in getlist(x[1]):
34272
53fb09c73ba8 revset: remove "small" argument from "_optimize"
Jun Wu <quark@fb.com>
parents: 34131
diff changeset
487 w, t = _optimize(y)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
488 if t is not None and (t[0] == b'string' or t[0] == b'symbol'):
25343
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
489 ss.append((w, t))
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
490 continue
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
491 flushss()
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
492 ws.append(w)
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
493 ts.append(t)
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
494 flushss()
7fbef7932af9 revset: optimize 'or' operation of trivial revisions to a list
Yuya Nishihara <yuya@tcha.org>
parents: 25342
diff changeset
495 if len(ts) == 1:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
496 return ws[0], ts[0] # 'or' operation is fully optimized out
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
497 return max(ws), (op, (b'list',) + tuple(ts))
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
498 elif op == b'not':
25191
08d1ef09ed37 revset: optimize not public revset
Laurent Charignon <lcharignon@fb.com>
parents: 25149
diff changeset
499 # Optimize not public() to _notpublic() because we have a fast version
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
500 if _match(b'public()', x[1]):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
501 o = _optimize(_build(b'_notpublic()'))
25191
08d1ef09ed37 revset: optimize not public revset
Laurent Charignon <lcharignon@fb.com>
parents: 25149
diff changeset
502 return o[0], o[1]
08d1ef09ed37 revset: optimize not public revset
Laurent Charignon <lcharignon@fb.com>
parents: 25149
diff changeset
503 else:
34272
53fb09c73ba8 revset: remove "small" argument from "_optimize"
Jun Wu <quark@fb.com>
parents: 34131
diff changeset
504 o = _optimize(x[1])
34011
1b28525e6698 revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents: 34010
diff changeset
505 return o[0], (op, o[1])
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
506 elif op == b'rangeall':
34272
53fb09c73ba8 revset: remove "small" argument from "_optimize"
Jun Wu <quark@fb.com>
parents: 34131
diff changeset
507 return 1, x
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
508 elif op in (b'rangepre', b'rangepost', b'parentpost'):
34272
53fb09c73ba8 revset: remove "small" argument from "_optimize"
Jun Wu <quark@fb.com>
parents: 34131
diff changeset
509 o = _optimize(x[1])
34011
1b28525e6698 revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents: 34010
diff changeset
510 return o[0], (op, o[1])
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
511 elif op in (b'dagrange', b'range'):
34272
53fb09c73ba8 revset: remove "small" argument from "_optimize"
Jun Wu <quark@fb.com>
parents: 34131
diff changeset
512 wa, ta = _optimize(x[1])
53fb09c73ba8 revset: remove "small" argument from "_optimize"
Jun Wu <quark@fb.com>
parents: 34131
diff changeset
513 wb, tb = _optimize(x[2])
34011
1b28525e6698 revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents: 34010
diff changeset
514 return wa + wb, (op, ta, tb)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
515 elif op in (b'parent', b'ancestor', b'relation', b'subscript'):
34272
53fb09c73ba8 revset: remove "small" argument from "_optimize"
Jun Wu <quark@fb.com>
parents: 34131
diff changeset
516 w, t = _optimize(x[1])
34011
1b28525e6698 revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents: 34010
diff changeset
517 return w, (op, t, x[2])
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
518 elif op == b'relsubscript':
34272
53fb09c73ba8 revset: remove "small" argument from "_optimize"
Jun Wu <quark@fb.com>
parents: 34131
diff changeset
519 w, t = _optimize(x[1])
34011
1b28525e6698 revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents: 34010
diff changeset
520 return w, (op, t, x[2], x[3])
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
521 elif op == b'list':
34272
53fb09c73ba8 revset: remove "small" argument from "_optimize"
Jun Wu <quark@fb.com>
parents: 34131
diff changeset
522 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
523 return sum(ws), (op,) + ts
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
524 elif op == b'keyvalue':
34272
53fb09c73ba8 revset: remove "small" argument from "_optimize"
Jun Wu <quark@fb.com>
parents: 34131
diff changeset
525 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
526 return w, (op, x[1], t)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
527 elif op == b'func':
29441
9e8d258708bb revset: check invalid function syntax "func-name"() explicitly
Yuya Nishihara <yuya@tcha.org>
parents: 29425
diff changeset
528 f = getsymbol(x[1])
34272
53fb09c73ba8 revset: remove "small" argument from "_optimize"
Jun Wu <quark@fb.com>
parents: 34131
diff changeset
529 wa, ta = _optimize(x[2])
34273
b0790bebfcf8 revset: move weight information to predicate
Jun Wu <quark@fb.com>
parents: 34272
diff changeset
530 w = getattr(symbols.get(f), '_weight', 1)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
531 m = _match(b'commonancestors(_)', ta)
38625
52f19a840543 revset: add optimization for heads(commonancestors())
Sean Farley <sean@farley.io>
parents: 37775
diff changeset
532
52f19a840543 revset: add optimization for heads(commonancestors())
Sean Farley <sean@farley.io>
parents: 37775
diff changeset
533 # Optimize heads(commonancestors(_)) because we have a fast version
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
534 if f == b'heads' and m:
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
535 return w + wa, _build(b'_commonancestorheads(_)', m[1])
38625
52f19a840543 revset: add optimization for heads(commonancestors())
Sean Farley <sean@farley.io>
parents: 37775
diff changeset
536
34011
1b28525e6698 revset: remove order information from tree (API)
Jun Wu <quark@fb.com>
parents: 34010
diff changeset
537 return w + wa, (op, x[1], ta)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
538 raise ValueError(b'invalid operator %r' % op)
11275
c9ce8ecd6ca1 revset: introduce revset core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
539
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
540
29119
a032ebea4e97 revset: factor out public optimize() function from recursion
Yuya Nishihara <yuya@tcha.org>
parents: 29118
diff changeset
541 def optimize(tree):
29905
371c2a39eead revset: make analyze() a separate step from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29904
diff changeset
542 """Optimize evaluatable tree
371c2a39eead revset: make analyze() a separate step from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29904
diff changeset
543
371c2a39eead revset: make analyze() a separate step from optimize()
Yuya Nishihara <yuya@tcha.org>
parents: 29904
diff changeset
544 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
545 """
34272
53fb09c73ba8 revset: remove "small" argument from "_optimize"
Jun Wu <quark@fb.com>
parents: 34131
diff changeset
546 _weight, newtree = _optimize(tree)
29119
a032ebea4e97 revset: factor out public optimize() function from recursion
Yuya Nishihara <yuya@tcha.org>
parents: 29118
diff changeset
547 return newtree
a032ebea4e97 revset: factor out public optimize() function from recursion
Yuya Nishihara <yuya@tcha.org>
parents: 29118
diff changeset
548
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
549
23845
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
550 # 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
551 # alias declarations and definitions
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
552 _aliassyminitletters = _syminitletters | {b'$'}
23845
0a7fd54d4e60 revset: introduce "_parsealiasdecl" to parse alias declarations strictly
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23844
diff changeset
553
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
554
29073
81bac118f9e2 revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents: 29072
diff changeset
555 def _parsewith(spec, lookup=None, syminitletters=None):
81bac118f9e2 revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents: 29072
diff changeset
556 """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
557
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34069
diff changeset
558 >>> _parsewith(b'foo($1)', syminitletters=_aliassyminitletters)
29073
81bac118f9e2 revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents: 29072
diff changeset
559 ('func', ('symbol', 'foo'), ('symbol', '$1'))
45886
18489e26d9a0 tests: make doctests not depend on str(ParseError()) format
Martin von Zweigbergk <martinvonz@google.com>
parents: 45776
diff changeset
560 >>> from . import error
18489e26d9a0 tests: make doctests not depend on str(ParseError()) format
Martin von Zweigbergk <martinvonz@google.com>
parents: 45776
diff changeset
561 >>> from . import pycompat
18489e26d9a0 tests: make doctests not depend on str(ParseError()) format
Martin von Zweigbergk <martinvonz@google.com>
parents: 45776
diff changeset
562 >>> try:
18489e26d9a0 tests: make doctests not depend on str(ParseError()) format
Martin von Zweigbergk <martinvonz@google.com>
parents: 45776
diff changeset
563 ... _parsewith(b'$1')
18489e26d9a0 tests: make doctests not depend on str(ParseError()) format
Martin von Zweigbergk <martinvonz@google.com>
parents: 45776
diff changeset
564 ... except error.ParseError as e:
18489e26d9a0 tests: make doctests not depend on str(ParseError()) format
Martin von Zweigbergk <martinvonz@google.com>
parents: 45776
diff changeset
565 ... pycompat.sysstr(e.message)
18489e26d9a0 tests: make doctests not depend on str(ParseError()) format
Martin von Zweigbergk <martinvonz@google.com>
parents: 45776
diff changeset
566 ... e.location
18489e26d9a0 tests: make doctests not depend on str(ParseError()) format
Martin von Zweigbergk <martinvonz@google.com>
parents: 45776
diff changeset
567 "syntax error in revset '$1'"
18489e26d9a0 tests: make doctests not depend on str(ParseError()) format
Martin von Zweigbergk <martinvonz@google.com>
parents: 45776
diff changeset
568 0
18489e26d9a0 tests: make doctests not depend on str(ParseError()) format
Martin von Zweigbergk <martinvonz@google.com>
parents: 45776
diff changeset
569 >>> try:
18489e26d9a0 tests: make doctests not depend on str(ParseError()) format
Martin von Zweigbergk <martinvonz@google.com>
parents: 45776
diff changeset
570 ... _parsewith(b'foo bar')
18489e26d9a0 tests: make doctests not depend on str(ParseError()) format
Martin von Zweigbergk <martinvonz@google.com>
parents: 45776
diff changeset
571 ... except error.ParseError as e:
18489e26d9a0 tests: make doctests not depend on str(ParseError()) format
Martin von Zweigbergk <martinvonz@google.com>
parents: 45776
diff changeset
572 ... pycompat.sysstr(e.message)
18489e26d9a0 tests: make doctests not depend on str(ParseError()) format
Martin von Zweigbergk <martinvonz@google.com>
parents: 45776
diff changeset
573 ... e.location
18489e26d9a0 tests: make doctests not depend on str(ParseError()) format
Martin von Zweigbergk <martinvonz@google.com>
parents: 45776
diff changeset
574 'invalid token'
18489e26d9a0 tests: make doctests not depend on str(ParseError()) format
Martin von Zweigbergk <martinvonz@google.com>
parents: 45776
diff changeset
575 4
29073
81bac118f9e2 revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents: 29072
diff changeset
576 """
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
577 if lookup and spec.startswith(b'revset(') and spec.endswith(b')'):
37760
29eb4cafeeb8 revset: skip legacy lookup for revspec wrapped in 'revset(...)'
Boris Feld <boris.feld@octobus.net>
parents: 37084
diff changeset
578 lookup = None
29073
81bac118f9e2 revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents: 29072
diff changeset
579 p = parser.parser(elements)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
580 tree, pos = p.parse(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
581 tokenize(spec, lookup=lookup, syminitletters=syminitletters)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
582 )
29073
81bac118f9e2 revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents: 29072
diff changeset
583 if pos != len(spec):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
584 raise error.ParseError(_(b'invalid token'), pos)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
585 return _fixops(parser.simplifyinfixops(tree, (b'list', b'or')))
29073
81bac118f9e2 revset: factor out common parsing function
Yuya Nishihara <yuya@tcha.org>
parents: 29072
diff changeset
586
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
587
28870
475dad3432fd parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents: 28869
diff changeset
588 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
589 """Parsing and expansion rule set of revset aliases"""
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
590
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
591 _section = _(b'revset alias')
29074
e7c679738503 revset: define _parsealias() in _aliasrules class
Yuya Nishihara <yuya@tcha.org>
parents: 29073
diff changeset
592
e7c679738503 revset: define _parsealias() in _aliasrules class
Yuya Nishihara <yuya@tcha.org>
parents: 29073
diff changeset
593 @staticmethod
e7c679738503 revset: define _parsealias() in _aliasrules class
Yuya Nishihara <yuya@tcha.org>
parents: 29073
diff changeset
594 def _parse(spec):
e7c679738503 revset: define _parsealias() in _aliasrules class
Yuya Nishihara <yuya@tcha.org>
parents: 29073
diff changeset
595 """Parse alias declaration/definition ``spec``
e7c679738503 revset: define _parsealias() in _aliasrules class
Yuya Nishihara <yuya@tcha.org>
parents: 29073
diff changeset
596
e7c679738503 revset: define _parsealias() in _aliasrules class
Yuya Nishihara <yuya@tcha.org>
parents: 29073
diff changeset
597 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
598 (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
599 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
600 """
e7c679738503 revset: define _parsealias() in _aliasrules class
Yuya Nishihara <yuya@tcha.org>
parents: 29073
diff changeset
601 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
602
1203159c8928 parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents: 28898
diff changeset
603 @staticmethod
1203159c8928 parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents: 28898
diff changeset
604 def _trygetfunc(tree):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
605 if tree[0] == b'func' and tree[1][0] == b'symbol':
28910
1203159c8928 parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents: 28898
diff changeset
606 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
607
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
608
33336
4672db164c98 revset: make repo.anyrevs accept customized alias override (API)
Jun Wu <quark@fb.com>
parents: 32913
diff changeset
609 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
610 """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
611 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
612 tree = _aliasrules.expand(aliases, tree)
29922
ae933e3e2226 revset: remove showwarning option from expandaliases()
Yuya Nishihara <yuya@tcha.org>
parents: 29906
diff changeset
613 # 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
614 if warn is not None:
48913
f254fc73d956 global: bulk replace simple pycompat.iteritems(x) with x.items()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
615 for name, alias in sorted(aliases.items()):
33336
4672db164c98 revset: make repo.anyrevs accept customized alias override (API)
Jun Wu <quark@fb.com>
parents: 32913
diff changeset
616 if alias.error and not alias.warned:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
617 warn(_(b'warning: %s\n') % (alias.error))
33336
4672db164c98 revset: make repo.anyrevs accept customized alias override (API)
Jun Wu <quark@fb.com>
parents: 32913
diff changeset
618 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
619 return tree
14098
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
620
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
621
23742
3a4d8a6ce432 revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23729
diff changeset
622 def foldconcat(tree):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45886
diff changeset
623 """Fold elements to be concatenated by `##`"""
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
624 if not isinstance(tree, tuple) or tree[0] in (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
625 b'string',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
626 b'symbol',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
627 b'smartset',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
628 ):
23742
3a4d8a6ce432 revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23729
diff changeset
629 return tree
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
630 if tree[0] == b'_concat':
23742
3a4d8a6ce432 revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23729
diff changeset
631 pending = [tree]
3a4d8a6ce432 revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23729
diff changeset
632 l = []
3a4d8a6ce432 revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23729
diff changeset
633 while pending:
3a4d8a6ce432 revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23729
diff changeset
634 e = pending.pop()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
635 if e[0] == b'_concat':
23742
3a4d8a6ce432 revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23729
diff changeset
636 pending.extend(reversed(e[1:]))
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
637 elif e[0] in (b'string', b'symbol'):
23742
3a4d8a6ce432 revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23729
diff changeset
638 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
639 else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
640 msg = _(b"\"##\" can't concatenate \"%s\" element") % (e[0])
23742
3a4d8a6ce432 revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23729
diff changeset
641 raise error.ParseError(msg)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
642 return (b'string', b''.join(l))
23742
3a4d8a6ce432 revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23729
diff changeset
643 else:
3a4d8a6ce432 revset: introduce new operator "##" to concatenate strings/symbols at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 23729
diff changeset
644 return tuple(foldconcat(t) for t in tree)
14098
9f5a0acb0056 revset aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 14073
diff changeset
645
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
646
20779
ffc2295c6b80 revset: pass a lookup function to the tokenizer
Matt Mackall <mpm@selenic.com>
parents: 20754
diff changeset
647 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
648 try:
2a258985ffeb revsetlang: add a hint for more useful parse errors
Ryan McElroy <rmcelroy@fb.com>
parents: 35882
diff changeset
649 return _parsewith(spec, lookup=lookup)
2a258985ffeb revsetlang: add a hint for more useful parse errors
Ryan McElroy <rmcelroy@fb.com>
parents: 35882
diff changeset
650 except error.ParseError as inst:
45776
0fc8b066928a errors: name arguments to ParseError constructor
Martin von Zweigbergk <martinvonz@google.com>
parents: 43106
diff changeset
651 if inst.location is not None:
0fc8b066928a errors: name arguments to ParseError constructor
Martin von Zweigbergk <martinvonz@google.com>
parents: 43106
diff changeset
652 loc = inst.location
36685
2a258985ffeb revsetlang: add a hint for more useful parse errors
Ryan McElroy <rmcelroy@fb.com>
parents: 35882
diff changeset
653 # Remove newlines -- spaces are equivalent whitespace.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
654 spec = spec.replace(b'\n', b' ')
36685
2a258985ffeb revsetlang: add a hint for more useful parse errors
Ryan McElroy <rmcelroy@fb.com>
parents: 35882
diff changeset
655 # 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
656 # 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
657 # 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
658 # to line up the caret with the location of the error.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
659 inst.hint = spec + b'\n' + b' ' * (loc + 1) + b'^ ' + _(b'here')
36685
2a258985ffeb revsetlang: add a hint for more useful parse errors
Ryan McElroy <rmcelroy@fb.com>
parents: 35882
diff changeset
660 raise
20779
ffc2295c6b80 revset: pass a lookup function to the tokenizer
Matt Mackall <mpm@selenic.com>
parents: 20754
diff changeset
661
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
662
31604
7eac6fcf2ffa revsetlang: move quoting function to not be a closure
Augie Fackler <augie@google.com>
parents: 31603
diff changeset
663 def _quote(s):
31605
0b94c19b641c revsetlang: add docstring with some tests to _quote
Augie Fackler <augie@google.com>
parents: 31604
diff changeset
664 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
665
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34069
diff changeset
666 >>> _quote(b'asdf')
31605
0b94c19b641c revsetlang: add docstring with some tests to _quote
Augie Fackler <augie@google.com>
parents: 31604
diff changeset
667 "'asdf'"
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34069
diff changeset
668 >>> _quote(b"asdf'\"")
31605
0b94c19b641c revsetlang: add docstring with some tests to _quote
Augie Fackler <augie@google.com>
parents: 31604
diff changeset
669 '\'asdf\\\'"\''
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34069
diff changeset
670 >>> _quote(b'asdf\'')
31606
0b3eb280564b revsetlang: perform quoting using ui.escapestr instead of repr()
Augie Fackler <augie@google.com>
parents: 31605
diff changeset
671 "'asdf\\''"
31605
0b94c19b641c revsetlang: add docstring with some tests to _quote
Augie Fackler <augie@google.com>
parents: 31604
diff changeset
672 >>> _quote(1)
0b94c19b641c revsetlang: add docstring with some tests to _quote
Augie Fackler <augie@google.com>
parents: 31604
diff changeset
673 "'1'"
0b94c19b641c revsetlang: add docstring with some tests to _quote
Augie Fackler <augie@google.com>
parents: 31604
diff changeset
674 """
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
675 return b"'%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
676
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
677
35596
a57acea31b3b revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents: 35595
diff changeset
678 def _formatargtype(c, arg):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
679 if c == b'd':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
680 return b'_rev(%d)' % int(arg)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
681 elif c == b's':
35596
a57acea31b3b revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents: 35595
diff changeset
682 return _quote(arg)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
683 elif c == b'r':
37775
03d7f885d5f2 revsetlang: do not pass in non-bytes to parse()
Yuya Nishihara <yuya@tcha.org>
parents: 37760
diff changeset
684 if not isinstance(arg, bytes):
03d7f885d5f2 revsetlang: do not pass in non-bytes to parse()
Yuya Nishihara <yuya@tcha.org>
parents: 37760
diff changeset
685 raise TypeError
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
686 parse(arg) # make sure syntax errors are confined
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
687 return b'(%s)' % arg
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
688 elif c == b'n':
46113
59fa3890d40a node: import symbols explicitly
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
689 return _quote(hex(arg))
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
690 elif c == b'b':
35596
a57acea31b3b revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents: 35595
diff changeset
691 try:
a57acea31b3b revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents: 35595
diff changeset
692 return _quote(arg.branch())
a57acea31b3b revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents: 35595
diff changeset
693 except AttributeError:
a57acea31b3b revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents: 35595
diff changeset
694 raise TypeError
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
695 raise error.ParseError(_(b'unexpected revspec format character %s') % c)
35596
a57acea31b3b revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents: 35595
diff changeset
696
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
697
35596
a57acea31b3b revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents: 35595
diff changeset
698 def _formatlistexp(s, t):
a57acea31b3b revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents: 35595
diff changeset
699 l = len(s)
a57acea31b3b revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents: 35595
diff changeset
700 if l == 0:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
701 return b"_list('')"
35596
a57acea31b3b revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents: 35595
diff changeset
702 elif l == 1:
a57acea31b3b revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents: 35595
diff changeset
703 return _formatargtype(t, s[0])
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
704 elif t == b'd':
41220
8d26026b3335 revert: extract "%ld" formatting in a _formatintlist function
Boris Feld <boris.feld@octobus.net>
parents: 41219
diff changeset
705 return _formatintlist(s)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
706 elif t == b's':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
707 return b"_list(%s)" % _quote(b"\0".join(s))
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
708 elif t == b'n':
46113
59fa3890d40a node: import symbols explicitly
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
709 return b"_hexlist('%s')" % b"\0".join(hex(a) for a in s)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
710 elif t == b'b':
35596
a57acea31b3b revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents: 35595
diff changeset
711 try:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
712 return b"_list('%s')" % b"\0".join(a.branch() for a in s)
35596
a57acea31b3b revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents: 35595
diff changeset
713 except AttributeError:
a57acea31b3b revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents: 35595
diff changeset
714 raise TypeError
a57acea31b3b revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents: 35595
diff changeset
715
a57acea31b3b revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents: 35595
diff changeset
716 m = l // 2
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
717 return b'(%s or %s)' % (_formatlistexp(s[:m], t), _formatlistexp(s[m:], t))
35596
a57acea31b3b revsetlang: unnest inner functions from formatspec()
Yuya Nishihara <yuya@tcha.org>
parents: 35595
diff changeset
718
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
719
41220
8d26026b3335 revert: extract "%ld" formatting in a _formatintlist function
Boris Feld <boris.feld@octobus.net>
parents: 41219
diff changeset
720 def _formatintlist(data):
8d26026b3335 revert: extract "%ld" formatting in a _formatintlist function
Boris Feld <boris.feld@octobus.net>
parents: 41219
diff changeset
721 try:
8d26026b3335 revert: extract "%ld" formatting in a _formatintlist function
Boris Feld <boris.feld@octobus.net>
parents: 41219
diff changeset
722 l = len(data)
8d26026b3335 revert: extract "%ld" formatting in a _formatintlist function
Boris Feld <boris.feld@octobus.net>
parents: 41219
diff changeset
723 if l == 0:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
724 return b"_list('')"
41220
8d26026b3335 revert: extract "%ld" formatting in a _formatintlist function
Boris Feld <boris.feld@octobus.net>
parents: 41219
diff changeset
725 elif l == 1:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
726 return _formatargtype(b'd', data[0])
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
727 return b"_intlist('%s')" % b"\0".join(b'%d' % int(a) for a in data)
41220
8d26026b3335 revert: extract "%ld" formatting in a _formatintlist function
Boris Feld <boris.feld@octobus.net>
parents: 41219
diff changeset
728 except (TypeError, ValueError):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
729 raise error.ParseError(_(b'invalid argument for revspec'))
41220
8d26026b3335 revert: extract "%ld" formatting in a _formatintlist function
Boris Feld <boris.feld@octobus.net>
parents: 41219
diff changeset
730
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
731
35597
ed0902e8053e revsetlang: add %p specifier to format list of function arguments
Yuya Nishihara <yuya@tcha.org>
parents: 35596
diff changeset
732 def _formatparamexp(args, t):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
733 return b', '.join(_formatargtype(t, a) for a in args)
35597
ed0902e8053e revsetlang: add %p specifier to format list of function arguments
Yuya Nishihara <yuya@tcha.org>
parents: 35596
diff changeset
734
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
735
35597
ed0902e8053e revsetlang: add %p specifier to format list of function arguments
Yuya Nishihara <yuya@tcha.org>
parents: 35596
diff changeset
736 _formatlistfuncs = {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
737 b'l': _formatlistexp,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
738 b'p': _formatparamexp,
35597
ed0902e8053e revsetlang: add %p specifier to format list of function arguments
Yuya Nishihara <yuya@tcha.org>
parents: 35596
diff changeset
739 }
ed0902e8053e revsetlang: add %p specifier to format list of function arguments
Yuya Nishihara <yuya@tcha.org>
parents: 35596
diff changeset
740
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
741
14901
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
742 def formatspec(expr, *args):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45886
diff changeset
743 """
14901
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
744 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
745 escapes arguments appropriately. Aliases are intentionally ignored
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
746 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
747
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
748 Supported arguments:
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
749
15266
8bea39ca9acb revset: add %r for embedded revset support to formatspec
Matt Mackall <mpm@selenic.com>
parents: 15153
diff changeset
750 %r = revset expression, parenthesized
41218
24a1f67bb75a revset: enforce "%d" to be interpreted as literal revision number (API) (BC)
Boris Feld <boris.feld@octobus.net>
parents: 40311
diff changeset
751 %d = rev(int(arg)), no quoting
14901
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
752 %s = string(arg), escaped and single-quoted
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
753 %b = arg.branch(), escaped and single-quoted
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
754 %n = hex(arg), single-quoted
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
755 %% = a literal '%'
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
756
35597
ed0902e8053e revsetlang: add %p specifier to format list of function arguments
Yuya Nishihara <yuya@tcha.org>
parents: 35596
diff changeset
757 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
758 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
759
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34069
diff changeset
760 >>> 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
761 '(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
762 >>> formatspec(b'%d:: and not %d::', 10, 20)
41297
b1ea90613af3 revset: introduce an internal `_rev` predicate for '%d' usage
Boris Feld <boris.feld@octobus.net>
parents: 41239
diff changeset
763 '_rev(10):: and not _rev(20)::'
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34069
diff changeset
764 >>> formatspec(b'%ld or %ld', [], [1])
41297
b1ea90613af3 revset: introduce an internal `_rev` predicate for '%d' usage
Boris Feld <boris.feld@octobus.net>
parents: 41239
diff changeset
765 "_list('') or _rev(1)"
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34069
diff changeset
766 >>> formatspec(b'keyword(%s)', b'foo\\xe9')
14901
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
767 "keyword('foo\\\\xe9')"
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34069
diff changeset
768 >>> b = lambda: b'default'
14901
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
769 >>> b.branch = b
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34069
diff changeset
770 >>> formatspec(b'branch(%b)', b)
14901
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
771 "branch('default')"
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 34069
diff changeset
772 >>> 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
773 "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
774 >>> 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
775 "sort((:), 'desc', 'user')"
35822
4269971b0d26 revsetlang: fix a doctest example on Python 3
Augie Fackler <augie@google.com>
parents: 35597
diff changeset
776 >>> formatspec(b'%ls', [b'a', b"'"])
35595
91201737d07a revsetlang: fix quoting of %ls string
Yuya Nishihara <yuya@tcha.org>
parents: 35594
diff changeset
777 "_list('a\\\\x00\\\\'')"
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45886
diff changeset
778 """
41219
e5b227f41e4a revset: extract parsing logic out of formatspec
Boris Feld <boris.feld@octobus.net>
parents: 41218
diff changeset
779 parsed = _parseargs(expr, args)
e5b227f41e4a revset: extract parsing logic out of formatspec
Boris Feld <boris.feld@octobus.net>
parents: 41218
diff changeset
780 ret = []
e5b227f41e4a revset: extract parsing logic out of formatspec
Boris Feld <boris.feld@octobus.net>
parents: 41218
diff changeset
781 for t, arg in parsed:
e5b227f41e4a revset: extract parsing logic out of formatspec
Boris Feld <boris.feld@octobus.net>
parents: 41218
diff changeset
782 if t is None:
e5b227f41e4a revset: extract parsing logic out of formatspec
Boris Feld <boris.feld@octobus.net>
parents: 41218
diff changeset
783 ret.append(arg)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
784 elif t == b'baseset':
41221
73203cdfe3fe revset: detect integer list on parsing
Boris Feld <boris.feld@octobus.net>
parents: 41220
diff changeset
785 if isinstance(arg, set):
73203cdfe3fe revset: detect integer list on parsing
Boris Feld <boris.feld@octobus.net>
parents: 41220
diff changeset
786 arg = sorted(arg)
73203cdfe3fe revset: detect integer list on parsing
Boris Feld <boris.feld@octobus.net>
parents: 41220
diff changeset
787 ret.append(_formatintlist(list(arg)))
41219
e5b227f41e4a revset: extract parsing logic out of formatspec
Boris Feld <boris.feld@octobus.net>
parents: 41218
diff changeset
788 else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
789 raise error.ProgrammingError(b"unknown revspec item type: %r" % t)
41219
e5b227f41e4a revset: extract parsing logic out of formatspec
Boris Feld <boris.feld@octobus.net>
parents: 41218
diff changeset
790 return b''.join(ret)
e5b227f41e4a revset: extract parsing logic out of formatspec
Boris Feld <boris.feld@octobus.net>
parents: 41218
diff changeset
791
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
792
41222
8aca89a694d4 revset: introduce an API that avoids `formatspec` input serialization
Boris Feld <boris.feld@octobus.net>
parents: 41221
diff changeset
793 def spectree(expr, *args):
8aca89a694d4 revset: introduce an API that avoids `formatspec` input serialization
Boris Feld <boris.feld@octobus.net>
parents: 41221
diff changeset
794 """similar to formatspec but return a parsed and optimized tree"""
8aca89a694d4 revset: introduce an API that avoids `formatspec` input serialization
Boris Feld <boris.feld@octobus.net>
parents: 41221
diff changeset
795 parsed = _parseargs(expr, args)
8aca89a694d4 revset: introduce an API that avoids `formatspec` input serialization
Boris Feld <boris.feld@octobus.net>
parents: 41221
diff changeset
796 ret = []
8aca89a694d4 revset: introduce an API that avoids `formatspec` input serialization
Boris Feld <boris.feld@octobus.net>
parents: 41221
diff changeset
797 inputs = []
8aca89a694d4 revset: introduce an API that avoids `formatspec` input serialization
Boris Feld <boris.feld@octobus.net>
parents: 41221
diff changeset
798 for t, arg in parsed:
8aca89a694d4 revset: introduce an API that avoids `formatspec` input serialization
Boris Feld <boris.feld@octobus.net>
parents: 41221
diff changeset
799 if t is None:
8aca89a694d4 revset: introduce an API that avoids `formatspec` input serialization
Boris Feld <boris.feld@octobus.net>
parents: 41221
diff changeset
800 ret.append(arg)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
801 elif t == b'baseset':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
802 newtree = (b'smartset', smartset.baseset(arg))
41222
8aca89a694d4 revset: introduce an API that avoids `formatspec` input serialization
Boris Feld <boris.feld@octobus.net>
parents: 41221
diff changeset
803 inputs.append(newtree)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
804 ret.append(b"$")
41222
8aca89a694d4 revset: introduce an API that avoids `formatspec` input serialization
Boris Feld <boris.feld@octobus.net>
parents: 41221
diff changeset
805 else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
806 raise error.ProgrammingError(b"unknown revspec item type: %r" % t)
41222
8aca89a694d4 revset: introduce an API that avoids `formatspec` input serialization
Boris Feld <boris.feld@octobus.net>
parents: 41221
diff changeset
807 expr = b''.join(ret)
8aca89a694d4 revset: introduce an API that avoids `formatspec` input serialization
Boris Feld <boris.feld@octobus.net>
parents: 41221
diff changeset
808 tree = _parsewith(expr, syminitletters=_aliassyminitletters)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
809 tree = parser.buildtree(tree, (b'symbol', b'$'), *inputs)
41222
8aca89a694d4 revset: introduce an API that avoids `formatspec` input serialization
Boris Feld <boris.feld@octobus.net>
parents: 41221
diff changeset
810 tree = foldconcat(tree)
8aca89a694d4 revset: introduce an API that avoids `formatspec` input serialization
Boris Feld <boris.feld@octobus.net>
parents: 41221
diff changeset
811 tree = analyze(tree)
8aca89a694d4 revset: introduce an API that avoids `formatspec` input serialization
Boris Feld <boris.feld@octobus.net>
parents: 41221
diff changeset
812 tree = optimize(tree)
8aca89a694d4 revset: introduce an API that avoids `formatspec` input serialization
Boris Feld <boris.feld@octobus.net>
parents: 41221
diff changeset
813 return tree
8aca89a694d4 revset: introduce an API that avoids `formatspec` input serialization
Boris Feld <boris.feld@octobus.net>
parents: 41221
diff changeset
814
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
815
41219
e5b227f41e4a revset: extract parsing logic out of formatspec
Boris Feld <boris.feld@octobus.net>
parents: 41218
diff changeset
816 def _parseargs(expr, args):
e5b227f41e4a revset: extract parsing logic out of formatspec
Boris Feld <boris.feld@octobus.net>
parents: 41218
diff changeset
817 """parse the expression and replace all inexpensive args
e5b227f41e4a revset: extract parsing logic out of formatspec
Boris Feld <boris.feld@octobus.net>
parents: 41218
diff changeset
818
e5b227f41e4a revset: extract parsing logic out of formatspec
Boris Feld <boris.feld@octobus.net>
parents: 41218
diff changeset
819 return a list of tuple [(arg-type, arg-value)]
e5b227f41e4a revset: extract parsing logic out of formatspec
Boris Feld <boris.feld@octobus.net>
parents: 41218
diff changeset
820
e5b227f41e4a revset: extract parsing logic out of formatspec
Boris Feld <boris.feld@octobus.net>
parents: 41218
diff changeset
821 Arg-type can be:
41221
73203cdfe3fe revset: detect integer list on parsing
Boris Feld <boris.feld@octobus.net>
parents: 41220
diff changeset
822 * None: a string ready to be concatenated into a final spec
73203cdfe3fe revset: detect integer list on parsing
Boris Feld <boris.feld@octobus.net>
parents: 41220
diff changeset
823 * 'baseset': an iterable of revisions
41219
e5b227f41e4a revset: extract parsing logic out of formatspec
Boris Feld <boris.feld@octobus.net>
parents: 41218
diff changeset
824 """
31440
f784ba187089 py3: use bytestr wrapper in revsetlang.formatspec()
Yuya Nishihara <yuya@tcha.org>
parents: 31385
diff changeset
825 expr = pycompat.bytestr(expr)
35560
3a8810c1b9bc revsetlang: use iterator to track current argument in formatspec()
Yuya Nishihara <yuya@tcha.org>
parents: 35559
diff changeset
826 argiter = iter(args)
35557
2df8d12f23bc revsetlang: avoid string concatenation in formatspec()
Yuya Nishihara <yuya@tcha.org>
parents: 35542
diff changeset
827 ret = []
14901
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
828 pos = 0
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
829 while pos < len(expr):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
830 q = expr.find(b'%', pos)
35558
dfc628611144 revsetlang: use str.find() to scan expr in formatspec()
Yuya Nishihara <yuya@tcha.org>
parents: 35557
diff changeset
831 if q < 0:
41219
e5b227f41e4a revset: extract parsing logic out of formatspec
Boris Feld <boris.feld@octobus.net>
parents: 41218
diff changeset
832 ret.append((None, expr[pos:]))
35558
dfc628611144 revsetlang: use str.find() to scan expr in formatspec()
Yuya Nishihara <yuya@tcha.org>
parents: 35557
diff changeset
833 break
41219
e5b227f41e4a revset: extract parsing logic out of formatspec
Boris Feld <boris.feld@octobus.net>
parents: 41218
diff changeset
834 ret.append((None, expr[pos:q]))
35558
dfc628611144 revsetlang: use str.find() to scan expr in formatspec()
Yuya Nishihara <yuya@tcha.org>
parents: 35557
diff changeset
835 pos = q + 1
35593
850cd045b1df revsetlang: check incomplete revspec format character
Yuya Nishihara <yuya@tcha.org>
parents: 35592
diff changeset
836 try:
850cd045b1df revsetlang: check incomplete revspec format character
Yuya Nishihara <yuya@tcha.org>
parents: 35592
diff changeset
837 d = expr[pos]
850cd045b1df revsetlang: check incomplete revspec format character
Yuya Nishihara <yuya@tcha.org>
parents: 35592
diff changeset
838 except IndexError:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
839 raise error.ParseError(_(b'incomplete revspec format character'))
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
840 if d == b'%':
41219
e5b227f41e4a revset: extract parsing logic out of formatspec
Boris Feld <boris.feld@octobus.net>
parents: 41218
diff changeset
841 ret.append((None, d))
35592
0fd617afebc0 revsetlang: check number of arguments passed to formatspec()
Yuya Nishihara <yuya@tcha.org>
parents: 35591
diff changeset
842 pos += 1
0fd617afebc0 revsetlang: check number of arguments passed to formatspec()
Yuya Nishihara <yuya@tcha.org>
parents: 35591
diff changeset
843 continue
0fd617afebc0 revsetlang: check number of arguments passed to formatspec()
Yuya Nishihara <yuya@tcha.org>
parents: 35591
diff changeset
844
0fd617afebc0 revsetlang: check number of arguments passed to formatspec()
Yuya Nishihara <yuya@tcha.org>
parents: 35591
diff changeset
845 try:
0fd617afebc0 revsetlang: check number of arguments passed to formatspec()
Yuya Nishihara <yuya@tcha.org>
parents: 35591
diff changeset
846 arg = next(argiter)
0fd617afebc0 revsetlang: check number of arguments passed to formatspec()
Yuya Nishihara <yuya@tcha.org>
parents: 35591
diff changeset
847 except StopIteration:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
848 raise error.ParseError(_(b'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
849 f = _formatlistfuncs.get(d)
ed0902e8053e revsetlang: add %p specifier to format list of function arguments
Yuya Nishihara <yuya@tcha.org>
parents: 35596
diff changeset
850 if f:
41219
e5b227f41e4a revset: extract parsing logic out of formatspec
Boris Feld <boris.feld@octobus.net>
parents: 41218
diff changeset
851 # a list of some type, might be expensive, do not replace
35559
a480551bd1b4 revsetlang: unnest "if True" in formatrevspec()
Yuya Nishihara <yuya@tcha.org>
parents: 35558
diff changeset
852 pos += 1
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
853 islist = d == b'l'
35593
850cd045b1df revsetlang: check incomplete revspec format character
Yuya Nishihara <yuya@tcha.org>
parents: 35592
diff changeset
854 try:
850cd045b1df revsetlang: check incomplete revspec format character
Yuya Nishihara <yuya@tcha.org>
parents: 35592
diff changeset
855 d = expr[pos]
850cd045b1df revsetlang: check incomplete revspec format character
Yuya Nishihara <yuya@tcha.org>
parents: 35592
diff changeset
856 except IndexError:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
857 raise error.ParseError(
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
858 _(b'incomplete revspec format character')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
859 )
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
860 if islist and d == b'd' and arg:
41239
26b0a7514f01 revset: transparently forward _intlist argument in all case
Boris Feld <boris.feld@octobus.net>
parents: 41222
diff changeset
861 # we don't create a baseset yet, because it come with an
26b0a7514f01 revset: transparently forward _intlist argument in all case
Boris Feld <boris.feld@octobus.net>
parents: 41222
diff changeset
862 # extra cost. If we are going to serialize it we better
26b0a7514f01 revset: transparently forward _intlist argument in all case
Boris Feld <boris.feld@octobus.net>
parents: 41222
diff changeset
863 # skip it.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
864 ret.append((b'baseset', arg))
41239
26b0a7514f01 revset: transparently forward _intlist argument in all case
Boris Feld <boris.feld@octobus.net>
parents: 41222
diff changeset
865 pos += 1
26b0a7514f01 revset: transparently forward _intlist argument in all case
Boris Feld <boris.feld@octobus.net>
parents: 41222
diff changeset
866 continue
35594
468d7a1f6633 revsetlang: catch invalid value passed to formatspec()
Yuya Nishihara <yuya@tcha.org>
parents: 35593
diff changeset
867 try:
41219
e5b227f41e4a revset: extract parsing logic out of formatspec
Boris Feld <boris.feld@octobus.net>
parents: 41218
diff changeset
868 ret.append((None, f(list(arg), d)))
35594
468d7a1f6633 revsetlang: catch invalid value passed to formatspec()
Yuya Nishihara <yuya@tcha.org>
parents: 35593
diff changeset
869 except (TypeError, ValueError):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
870 raise error.ParseError(_(b'invalid argument for revspec'))
35559
a480551bd1b4 revsetlang: unnest "if True" in formatrevspec()
Yuya Nishihara <yuya@tcha.org>
parents: 35558
diff changeset
871 else:
41219
e5b227f41e4a revset: extract parsing logic out of formatspec
Boris Feld <boris.feld@octobus.net>
parents: 41218
diff changeset
872 # a single entry, not expensive, replace
35594
468d7a1f6633 revsetlang: catch invalid value passed to formatspec()
Yuya Nishihara <yuya@tcha.org>
parents: 35593
diff changeset
873 try:
41219
e5b227f41e4a revset: extract parsing logic out of formatspec
Boris Feld <boris.feld@octobus.net>
parents: 41218
diff changeset
874 ret.append((None, _formatargtype(d, arg)))
35594
468d7a1f6633 revsetlang: catch invalid value passed to formatspec()
Yuya Nishihara <yuya@tcha.org>
parents: 35593
diff changeset
875 except (TypeError, ValueError):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
876 raise error.ParseError(_(b'invalid argument for revspec'))
14901
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
877 pos += 1
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
878
35592
0fd617afebc0 revsetlang: check number of arguments passed to formatspec()
Yuya Nishihara <yuya@tcha.org>
parents: 35591
diff changeset
879 try:
0fd617afebc0 revsetlang: check number of arguments passed to formatspec()
Yuya Nishihara <yuya@tcha.org>
parents: 35591
diff changeset
880 next(argiter)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
881 raise error.ParseError(_(b'too many revspec arguments specified'))
35592
0fd617afebc0 revsetlang: check number of arguments passed to formatspec()
Yuya Nishihara <yuya@tcha.org>
parents: 35591
diff changeset
882 except StopIteration:
0fd617afebc0 revsetlang: check number of arguments passed to formatspec()
Yuya Nishihara <yuya@tcha.org>
parents: 35591
diff changeset
883 pass
41219
e5b227f41e4a revset: extract parsing logic out of formatspec
Boris Feld <boris.feld@octobus.net>
parents: 41218
diff changeset
884 return ret
14901
a773119f30ba revset: add formatspec convenience query builder
Matt Mackall <mpm@selenic.com>
parents: 14900
diff changeset
885
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
886
16218
81a1a00f5738 debugrevspec: pretty print output
Patrick Mezard <patrick@mezard.eu>
parents: 16185
diff changeset
887 def prettyformat(tree):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
888 return parser.prettyformat(tree, (b'string', b'symbol'))
16218
81a1a00f5738 debugrevspec: pretty print output
Patrick Mezard <patrick@mezard.eu>
parents: 16185
diff changeset
889
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
890
19719
2f9d5c5256ea revset: add helper function to get revset parse tree depth
Alexander Plavin <alexander@plav.in>
parents: 19706
diff changeset
891 def depth(tree):
2f9d5c5256ea revset: add helper function to get revset parse tree depth
Alexander Plavin <alexander@plav.in>
parents: 19706
diff changeset
892 if isinstance(tree, tuple):
2f9d5c5256ea revset: add helper function to get revset parse tree depth
Alexander Plavin <alexander@plav.in>
parents: 19706
diff changeset
893 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
894 else:
2f9d5c5256ea revset: add helper function to get revset parse tree depth
Alexander Plavin <alexander@plav.in>
parents: 19706
diff changeset
895 return 0
2f9d5c5256ea revset: add helper function to get revset parse tree depth
Alexander Plavin <alexander@plav.in>
parents: 19706
diff changeset
896
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
897
19720
f0b992a9be9c revset: add helper function to get functions used in a revset parse tree
Alexander Plavin <alexander@plav.in>
parents: 19719
diff changeset
898 def funcsused(tree):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
899 if not isinstance(tree, tuple) or tree[0] in (b'string', b'symbol'):
19720
f0b992a9be9c revset: add helper function to get functions used in a revset parse tree
Alexander Plavin <alexander@plav.in>
parents: 19719
diff changeset
900 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
901 else:
f0b992a9be9c revset: add helper function to get functions used in a revset parse tree
Alexander Plavin <alexander@plav.in>
parents: 19719
diff changeset
902 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
903 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
904 funcs |= funcsused(s)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
905 if tree[0] == b'func':
19720
f0b992a9be9c revset: add helper function to get functions used in a revset parse tree
Alexander Plavin <alexander@plav.in>
parents: 19719
diff changeset
906 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
907 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
908
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
909
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
910 _hashre = util.re.compile(b'[0-9a-fA-F]{1,40}$')
35494
dd911f95cbda revsetlang: add utility function to return hash like symbols from the tree
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34273
diff changeset
911
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
912
35494
dd911f95cbda revsetlang: add utility function to return hash like symbols from the tree
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34273
diff changeset
913 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
914 """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
915 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
916
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41835
diff changeset
917
35494
dd911f95cbda revsetlang: add utility function to return hash like symbols from the tree
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34273
diff changeset
918 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
919 """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
920
35882
87416288be98 tests: make doctest py3-compatible again
Yuya Nishihara <yuya@tcha.org>
parents: 35822
diff changeset
921 >>> 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
922 ['3', 'abe3ff']
35882
87416288be98 tests: make doctest py3-compatible again
Yuya Nishihara <yuya@tcha.org>
parents: 35822
diff changeset
923 >>> 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
924 []
35882
87416288be98 tests: make doctest py3-compatible again
Yuya Nishihara <yuya@tcha.org>
parents: 35822
diff changeset
925 >>> 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
926 ['34']
35882
87416288be98 tests: make doctest py3-compatible again
Yuya Nishihara <yuya@tcha.org>
parents: 35822
diff changeset
927 >>> 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
928 []
dd911f95cbda revsetlang: add utility function to return hash like symbols from the tree
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34273
diff changeset
929 """
dd911f95cbda revsetlang: add utility function to return hash like symbols from the tree
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34273
diff changeset
930 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
931 return []
dd911f95cbda revsetlang: add utility function to return hash like symbols from the tree
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34273
diff changeset
932
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
933 if tree[0] == b"symbol":
35494
dd911f95cbda revsetlang: add utility function to return hash like symbols from the tree
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34273
diff changeset
934 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
935 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
936 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
937 results = []
dd911f95cbda revsetlang: add utility function to return hash like symbols from the tree
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34273
diff changeset
938 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
939 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
940 return results
dd911f95cbda revsetlang: add utility function to return hash like symbols from the tree
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34273
diff changeset
941 return []