annotate mercurial/revsetlang.py @ 51479:5bd31e68c7a3

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