annotate mercurial/revsetlang.py @ 44758:45f3f35cefe7

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