Mercurial > hg
annotate mercurial/parser.py @ 50404:64cdd80d6909
branching: merge stable into default
author | Raphaël Gomès <rgomes@octobus.net> |
---|---|
date | Fri, 24 Mar 2023 10:43:47 +0100 |
parents | 642e31cb55f0 |
children | f4733654f144 |
rev | line source |
---|---|
11274 | 1 # parser.py - simple top-down operator precedence parser for mercurial |
2 # | |
46819
d4ba4d51f85f
contributor: change mentions of mpm to olivia
Raphaël Gomès <rgomes@octobus.net>
parents:
45942
diff
changeset
|
3 # Copyright 2010 Olivia Mackall <olivia@selenic.com> |
11274 | 4 # |
5 # This software may be used and distributed according to the terms of the | |
6 # GNU General Public License version 2 or any later version. | |
7 | |
11449
05af334bac05
parser: fix URL to effbot
Julian Cowley <julian@lava.net>
parents:
11412
diff
changeset
|
8 # see http://effbot.org/zone/simple-top-down-parsing.htm and |
11274 | 9 # http://eli.thegreenplace.net/2010/01/02/top-down-operator-precedence-parsing/ |
10 # for background | |
11 | |
12 # takes a tokenizer and elements | |
25655
b8b73652c1c9
parser: update documentation about tokenizer and elements
Yuya Nishihara <yuya@tcha.org>
parents:
25654
diff
changeset
|
13 # tokenizer is an iterator that returns (type, value, pos) tuples |
25815
e71e5629e006
parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents:
25804
diff
changeset
|
14 # elements is a mapping of types to binding strength, primary, prefix, infix |
e71e5629e006
parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents:
25804
diff
changeset
|
15 # and suffix actions |
11274 | 16 # an action is a tree node name, a tree label, and an optional match |
17500 | 17 # __call__(program) parses program into a labeled tree |
11274 | 18 |
25963
7448df709b2e
parser: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25818
diff
changeset
|
19 |
7448df709b2e
parser: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25818
diff
changeset
|
20 from .i18n import _ |
31484
afb335353d28
util: wrap s.decode('string_escape') calls for future py3 compatibility
Yuya Nishihara <yuya@tcha.org>
parents:
31353
diff
changeset
|
21 from . import ( |
afb335353d28
util: wrap s.decode('string_escape') calls for future py3 compatibility
Yuya Nishihara <yuya@tcha.org>
parents:
31353
diff
changeset
|
22 error, |
afb335353d28
util: wrap s.decode('string_escape') calls for future py3 compatibility
Yuya Nishihara <yuya@tcha.org>
parents:
31353
diff
changeset
|
23 util, |
afb335353d28
util: wrap s.decode('string_escape') calls for future py3 compatibility
Yuya Nishihara <yuya@tcha.org>
parents:
31353
diff
changeset
|
24 ) |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
25 from .utils import stringutil |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
26 |
11289
4215ce511134
revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents:
11278
diff
changeset
|
27 |
48946
642e31cb55f0
py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48875
diff
changeset
|
28 class parser: |
25654
af329a84310c
parser: accept iterator of tokens instead of tokenizer function and program
Yuya Nishihara <yuya@tcha.org>
parents:
25306
diff
changeset
|
29 def __init__(self, elements, methods=None): |
11274 | 30 self._elements = elements |
31 self._methods = methods | |
13176
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
11449
diff
changeset
|
32 self.current = None |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
33 |
11274 | 34 def _advance(self): |
43787
be8552f25cab
cleanup: fix docstring formatting
Matt Harbison <matt_harbison@yahoo.com>
parents:
43117
diff
changeset
|
35 """advance the tokenizer""" |
11274 | 36 t = self.current |
25171
d647f97f88dd
parsers: use 'next' instead of try/except
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20778
diff
changeset
|
37 self.current = next(self._iter, None) |
11274 | 38 return t |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
39 |
25804
f0a77cb6316a
parser: extract function that tests if next token may start new term
Yuya Nishihara <yuya@tcha.org>
parents:
25803
diff
changeset
|
40 def _hasnewterm(self): |
43787
be8552f25cab
cleanup: fix docstring formatting
Matt Harbison <matt_harbison@yahoo.com>
parents:
43117
diff
changeset
|
41 """True if next token may start new term""" |
25815
e71e5629e006
parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents:
25804
diff
changeset
|
42 return any(self._elements[self.current[0]][1:3]) |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
43 |
25802
cc741c76b26a
parser: remove unused parameter 'pos' from _match()
Yuya Nishihara <yuya@tcha.org>
parents:
25801
diff
changeset
|
44 def _match(self, m): |
43787
be8552f25cab
cleanup: fix docstring formatting
Matt Harbison <matt_harbison@yahoo.com>
parents:
43117
diff
changeset
|
45 """make sure the tokenizer matches an end condition""" |
11274 | 46 if self.current[0] != m: |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
47 raise error.ParseError( |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
48 _(b"unexpected token: %s") % self.current[0], self.current[2] |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
49 ) |
11274 | 50 self._advance() |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
51 |
25803
b3004d273874
parser: factor out function that parses right-hand side of prefix/infix ops
Yuya Nishihara <yuya@tcha.org>
parents:
25802
diff
changeset
|
52 def _parseoperand(self, bind, m=None): |
43787
be8552f25cab
cleanup: fix docstring formatting
Matt Harbison <matt_harbison@yahoo.com>
parents:
43117
diff
changeset
|
53 """gather right-hand-side operand until an end condition or binding |
be8552f25cab
cleanup: fix docstring formatting
Matt Harbison <matt_harbison@yahoo.com>
parents:
43117
diff
changeset
|
54 met""" |
25803
b3004d273874
parser: factor out function that parses right-hand side of prefix/infix ops
Yuya Nishihara <yuya@tcha.org>
parents:
25802
diff
changeset
|
55 if m and self.current[0] == m: |
b3004d273874
parser: factor out function that parses right-hand side of prefix/infix ops
Yuya Nishihara <yuya@tcha.org>
parents:
25802
diff
changeset
|
56 expr = None |
b3004d273874
parser: factor out function that parses right-hand side of prefix/infix ops
Yuya Nishihara <yuya@tcha.org>
parents:
25802
diff
changeset
|
57 else: |
b3004d273874
parser: factor out function that parses right-hand side of prefix/infix ops
Yuya Nishihara <yuya@tcha.org>
parents:
25802
diff
changeset
|
58 expr = self._parse(bind) |
b3004d273874
parser: factor out function that parses right-hand side of prefix/infix ops
Yuya Nishihara <yuya@tcha.org>
parents:
25802
diff
changeset
|
59 if m: |
b3004d273874
parser: factor out function that parses right-hand side of prefix/infix ops
Yuya Nishihara <yuya@tcha.org>
parents:
25802
diff
changeset
|
60 self._match(m) |
b3004d273874
parser: factor out function that parses right-hand side of prefix/infix ops
Yuya Nishihara <yuya@tcha.org>
parents:
25802
diff
changeset
|
61 return expr |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
62 |
11274 | 63 def _parse(self, bind=0): |
11289
4215ce511134
revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents:
11278
diff
changeset
|
64 token, value, pos = self._advance() |
25816
43a8a87fc175
parser: resolve ambiguity where both prefix and primary actions are defined
Yuya Nishihara <yuya@tcha.org>
parents:
25815
diff
changeset
|
65 # handle prefix rules on current token, take as primary if unambiguous |
25815
e71e5629e006
parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents:
25804
diff
changeset
|
66 primary, prefix = self._elements[token][1:3] |
25816
43a8a87fc175
parser: resolve ambiguity where both prefix and primary actions are defined
Yuya Nishihara <yuya@tcha.org>
parents:
25815
diff
changeset
|
67 if primary and not (prefix and self._hasnewterm()): |
25815
e71e5629e006
parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents:
25804
diff
changeset
|
68 expr = (primary, value) |
e71e5629e006
parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents:
25804
diff
changeset
|
69 elif prefix: |
e71e5629e006
parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents:
25804
diff
changeset
|
70 expr = (prefix[0], self._parseoperand(*prefix[1:])) |
e71e5629e006
parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents:
25804
diff
changeset
|
71 else: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
72 raise error.ParseError(_(b"not a prefix: %s") % token, pos) |
11274 | 73 # gather tokens until we meet a lower binding strength |
74 while bind < self._elements[self.current[0]][0]: | |
11289
4215ce511134
revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents:
11278
diff
changeset
|
75 token, value, pos = self._advance() |
25817
42ac9d1d1572
parser: reorder infix/suffix handling to be similar to prefix/primary flow
Yuya Nishihara <yuya@tcha.org>
parents:
25816
diff
changeset
|
76 # handle infix rules, take as suffix if unambiguous |
25815
e71e5629e006
parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents:
25804
diff
changeset
|
77 infix, suffix = self._elements[token][3:] |
25818
455190fb4e51
parser: take suffix action if no infix action is defined
Yuya Nishihara <yuya@tcha.org>
parents:
25817
diff
changeset
|
78 if suffix and not (infix and self._hasnewterm()): |
29767
e5b794063fd4
parser: remove unused binding parameter from suffix action
Yuya Nishihara <yuya@tcha.org>
parents:
29059
diff
changeset
|
79 expr = (suffix, expr) |
25817
42ac9d1d1572
parser: reorder infix/suffix handling to be similar to prefix/primary flow
Yuya Nishihara <yuya@tcha.org>
parents:
25816
diff
changeset
|
80 elif infix: |
42ac9d1d1572
parser: reorder infix/suffix handling to be similar to prefix/primary flow
Yuya Nishihara <yuya@tcha.org>
parents:
25816
diff
changeset
|
81 expr = (infix[0], expr, self._parseoperand(*infix[1:])) |
11274 | 82 else: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
83 raise error.ParseError(_(b"not an infix: %s") % token, pos) |
11274 | 84 return expr |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
85 |
25654
af329a84310c
parser: accept iterator of tokens instead of tokenizer function and program
Yuya Nishihara <yuya@tcha.org>
parents:
25306
diff
changeset
|
86 def parse(self, tokeniter): |
43787
be8552f25cab
cleanup: fix docstring formatting
Matt Harbison <matt_harbison@yahoo.com>
parents:
43117
diff
changeset
|
87 """generate a parse tree from tokens""" |
25654
af329a84310c
parser: accept iterator of tokens instead of tokenizer function and program
Yuya Nishihara <yuya@tcha.org>
parents:
25306
diff
changeset
|
88 self._iter = tokeniter |
13176
895f54a79c6e
templater: use the parser.py parser to extend the templater syntax
Matt Mackall <mpm@selenic.com>
parents:
11449
diff
changeset
|
89 self._advance() |
13665
e798e430c5e5
revset: report a parse error if a revset is not parsed completely (issue2654)
Bernhard Leiner <bleiner@gmail.com>
parents:
13176
diff
changeset
|
90 res = self._parse() |
e798e430c5e5
revset: report a parse error if a revset is not parsed completely (issue2654)
Bernhard Leiner <bleiner@gmail.com>
parents:
13176
diff
changeset
|
91 token, value, pos = self.current |
e798e430c5e5
revset: report a parse error if a revset is not parsed completely (issue2654)
Bernhard Leiner <bleiner@gmail.com>
parents:
13176
diff
changeset
|
92 return res, pos |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
93 |
11274 | 94 def eval(self, tree): |
43787
be8552f25cab
cleanup: fix docstring formatting
Matt Harbison <matt_harbison@yahoo.com>
parents:
43117
diff
changeset
|
95 """recursively evaluate a parse tree using node methods""" |
11274 | 96 if not isinstance(tree, tuple): |
97 return tree | |
98 return self._methods[tree[0]](*[self.eval(t) for t in tree[1:]]) | |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
99 |
25654
af329a84310c
parser: accept iterator of tokens instead of tokenizer function and program
Yuya Nishihara <yuya@tcha.org>
parents:
25306
diff
changeset
|
100 def __call__(self, tokeniter): |
43787
be8552f25cab
cleanup: fix docstring formatting
Matt Harbison <matt_harbison@yahoo.com>
parents:
43117
diff
changeset
|
101 """parse tokens into a parse tree and evaluate if methods given""" |
25654
af329a84310c
parser: accept iterator of tokens instead of tokenizer function and program
Yuya Nishihara <yuya@tcha.org>
parents:
25306
diff
changeset
|
102 t = self.parse(tokeniter) |
11274 | 103 if self._methods: |
104 return self.eval(t) | |
105 return t | |
25253
3f1a9b44b8c2
parser: move prettyformat() function from revset module
Yuya Nishihara <yuya@tcha.org>
parents:
25171
diff
changeset
|
106 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
107 |
30753
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
108 def splitargspec(spec): |
31921
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
109 """Parse spec of function arguments into (poskeys, varkey, keys, optkey) |
30753
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
110 |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
111 >>> splitargspec(b'') |
31921
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
112 ([], None, [], None) |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
113 >>> splitargspec(b'foo bar') |
31921
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
114 ([], None, ['foo', 'bar'], None) |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
115 >>> splitargspec(b'foo *bar baz **qux') |
31921
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
116 (['foo'], 'bar', ['baz'], 'qux') |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
117 >>> splitargspec(b'*foo') |
31921
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
118 ([], 'foo', [], None) |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
119 >>> splitargspec(b'**foo') |
31921
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
120 ([], None, [], 'foo') |
30753
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
121 """ |
31921
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
122 optkey = None |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
123 pre, sep, post = spec.partition(b'**') |
31921
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
124 if sep: |
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
125 posts = post.split() |
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
126 if not posts: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
127 raise error.ProgrammingError(b'no **optkey name provided') |
31921
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
128 if len(posts) > 1: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
129 raise error.ProgrammingError(b'excessive **optkey names provided') |
31921
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
130 optkey = posts[0] |
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
131 |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
132 pre, sep, post = pre.partition(b'*') |
30753
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
133 pres = pre.split() |
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
134 posts = post.split() |
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
135 if sep: |
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
136 if not posts: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
137 raise error.ProgrammingError(b'no *varkey name provided') |
31921
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
138 return pres, posts[0], posts[1:], optkey |
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
139 return [], None, pres, optkey |
30753
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
140 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
141 |
30753
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
142 def buildargsdict(trees, funcname, argspec, keyvaluenode, keynode): |
25705
48919d246a47
revset: add function to build dict of positional and keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents:
25655
diff
changeset
|
143 """Build dict from list containing positional and keyword arguments |
48919d246a47
revset: add function to build dict of positional and keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents:
25655
diff
changeset
|
144 |
31921
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
145 Arguments are specified by a tuple of ``(poskeys, varkey, keys, optkey)`` |
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
146 where |
30753
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
147 |
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
148 - ``poskeys``: list of names of positional arguments |
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
149 - ``varkey``: optional argument name that takes up remainder |
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
150 - ``keys``: list of names that can be either positional or keyword arguments |
31921
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
151 - ``optkey``: optional argument name that takes up excess keyword arguments |
30753
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
152 |
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
153 If ``varkey`` specified, all ``keys`` must be given as keyword arguments. |
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
154 |
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
155 Invalid keywords, too few positional arguments, or too many positional |
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
156 arguments are rejected, but missing keyword arguments are just omitted. |
25705
48919d246a47
revset: add function to build dict of positional and keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents:
25655
diff
changeset
|
157 """ |
31921
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
158 poskeys, varkey, keys, optkey = argspec |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
159 kwstart = next( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
160 (i for i, x in enumerate(trees) if x and x[0] == keyvaluenode), |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
161 len(trees), |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
162 ) |
30753
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
163 if kwstart < len(poskeys): |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
164 raise error.ParseError( |
43117
8ff1ecfadcd1
cleanup: join string literals that are already on one line
Martin von Zweigbergk <martinvonz@google.com>
parents:
43077
diff
changeset
|
165 _(b"%(func)s takes at least %(nargs)d positional arguments") |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
166 % {b'func': funcname, b'nargs': len(poskeys)} |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
167 ) |
31920
a98540ea1e42
parser: verify excessive number of args excluding kwargs in buildargsdict()
Yuya Nishihara <yuya@tcha.org>
parents:
31484
diff
changeset
|
168 if not varkey and kwstart > len(poskeys) + len(keys): |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
169 raise error.ParseError( |
43117
8ff1ecfadcd1
cleanup: join string literals that are already on one line
Martin von Zweigbergk <martinvonz@google.com>
parents:
43077
diff
changeset
|
170 _(b"%(func)s takes at most %(nargs)d positional arguments") |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
171 % {b'func': funcname, b'nargs': len(poskeys) + len(keys)} |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
172 ) |
31922
0f41f1e3c75c
parser: preserve order of keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents:
31921
diff
changeset
|
173 args = util.sortdict() |
25705
48919d246a47
revset: add function to build dict of positional and keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents:
25655
diff
changeset
|
174 # consume positional arguments |
30753
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
175 for k, x in zip(poskeys, trees[:kwstart]): |
25705
48919d246a47
revset: add function to build dict of positional and keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents:
25655
diff
changeset
|
176 args[k] = x |
30753
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
177 if varkey: |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
178 args[varkey] = trees[len(args) : kwstart] |
30753
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
179 else: |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
180 for k, x in zip(keys, trees[len(args) : kwstart]): |
30753
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
181 args[k] = x |
25705
48919d246a47
revset: add function to build dict of positional and keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents:
25655
diff
changeset
|
182 # remainder should be keyword arguments |
31921
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
183 if optkey: |
31922
0f41f1e3c75c
parser: preserve order of keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents:
31921
diff
changeset
|
184 args[optkey] = util.sortdict() |
30752
ffd324eaf994
parser: make buildargsdict() precompute position where keyword args start
Yuya Nishihara <yuya@tcha.org>
parents:
30332
diff
changeset
|
185 for x in trees[kwstart:]: |
42232
29798c9ba5c9
parser: fix crash by parsing "()" in keyword argument position
Yuya Nishihara <yuya@tcha.org>
parents:
39050
diff
changeset
|
186 if not x or x[0] != keyvaluenode or x[1][0] != keynode: |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
187 raise error.ParseError( |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
188 _(b"%(func)s got an invalid argument") % {b'func': funcname} |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
189 ) |
25705
48919d246a47
revset: add function to build dict of positional and keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents:
25655
diff
changeset
|
190 k = x[1][1] |
31921
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
191 if k in keys: |
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
192 d = args |
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
193 elif not optkey: |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
194 raise error.ParseError( |
43117
8ff1ecfadcd1
cleanup: join string literals that are already on one line
Martin von Zweigbergk <martinvonz@google.com>
parents:
43077
diff
changeset
|
195 _(b"%(func)s got an unexpected keyword argument '%(key)s'") |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
196 % {b'func': funcname, b'key': k} |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
197 ) |
31921
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
198 else: |
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
199 d = args[optkey] |
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
200 if k in d: |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
201 raise error.ParseError( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
202 _( |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
203 b"%(func)s got multiple values for keyword " |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
204 b"argument '%(key)s'" |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
205 ) |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
206 % {b'func': funcname, b'key': k} |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
207 ) |
31921
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
208 d[k] = x[2] |
25705
48919d246a47
revset: add function to build dict of positional and keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents:
25655
diff
changeset
|
209 return args |
48919d246a47
revset: add function to build dict of positional and keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents:
25655
diff
changeset
|
210 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
211 |
26231
87c9c562c37a
parser: move unescape helper from templater
Yuya Nishihara <yuya@tcha.org>
parents:
25963
diff
changeset
|
212 def unescapestr(s): |
87c9c562c37a
parser: move unescape helper from templater
Yuya Nishihara <yuya@tcha.org>
parents:
25963
diff
changeset
|
213 try: |
37084
f0b6fbea00cf
stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36547
diff
changeset
|
214 return stringutil.unescapestr(s) |
26231
87c9c562c37a
parser: move unescape helper from templater
Yuya Nishihara <yuya@tcha.org>
parents:
25963
diff
changeset
|
215 except ValueError as e: |
87c9c562c37a
parser: move unescape helper from templater
Yuya Nishihara <yuya@tcha.org>
parents:
25963
diff
changeset
|
216 # mangle Python's exception into our format |
48011
8655a77dce94
parser: force a `ValueError` to bytes before passing to `error.ParseError`
Matt Harbison <matt_harbison@yahoo.com>
parents:
46819
diff
changeset
|
217 # TODO: remove this suppression. For some reason, pytype 2021.09.09 |
8655a77dce94
parser: force a `ValueError` to bytes before passing to `error.ParseError`
Matt Harbison <matt_harbison@yahoo.com>
parents:
46819
diff
changeset
|
218 # thinks .lower() is being called on Union[ValueError, bytes]. |
8655a77dce94
parser: force a `ValueError` to bytes before passing to `error.ParseError`
Matt Harbison <matt_harbison@yahoo.com>
parents:
46819
diff
changeset
|
219 # pytype: disable=attribute-error |
8655a77dce94
parser: force a `ValueError` to bytes before passing to `error.ParseError`
Matt Harbison <matt_harbison@yahoo.com>
parents:
46819
diff
changeset
|
220 raise error.ParseError(stringutil.forcebytestr(e).lower()) |
8655a77dce94
parser: force a `ValueError` to bytes before passing to `error.ParseError`
Matt Harbison <matt_harbison@yahoo.com>
parents:
46819
diff
changeset
|
221 # pytype: enable=attribute-error |
26231
87c9c562c37a
parser: move unescape helper from templater
Yuya Nishihara <yuya@tcha.org>
parents:
25963
diff
changeset
|
222 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
223 |
25254
060bdfef2517
parser: extract closure of prettyformat() to a top-level function
Yuya Nishihara <yuya@tcha.org>
parents:
25253
diff
changeset
|
224 def _prettyformat(tree, leafnodes, level, lines): |
34073
7bbc4e113e5f
parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents:
34045
diff
changeset
|
225 if not isinstance(tree, tuple): |
39050
0a2ce5b43574
parser: replace bespoke _brepr with stringutil.pprint
Augie Fackler <augie@google.com>
parents:
37084
diff
changeset
|
226 lines.append((level, stringutil.pprint(tree))) |
34073
7bbc4e113e5f
parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents:
34045
diff
changeset
|
227 elif tree[0] in leafnodes: |
39050
0a2ce5b43574
parser: replace bespoke _brepr with stringutil.pprint
Augie Fackler <augie@google.com>
parents:
37084
diff
changeset
|
228 rs = map(stringutil.pprint, tree[1:]) |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
229 lines.append((level, b'(%s %s)' % (tree[0], b' '.join(rs)))) |
25254
060bdfef2517
parser: extract closure of prettyformat() to a top-level function
Yuya Nishihara <yuya@tcha.org>
parents:
25253
diff
changeset
|
230 else: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
231 lines.append((level, b'(%s' % tree[0])) |
25254
060bdfef2517
parser: extract closure of prettyformat() to a top-level function
Yuya Nishihara <yuya@tcha.org>
parents:
25253
diff
changeset
|
232 for s in tree[1:]: |
060bdfef2517
parser: extract closure of prettyformat() to a top-level function
Yuya Nishihara <yuya@tcha.org>
parents:
25253
diff
changeset
|
233 _prettyformat(s, leafnodes, level + 1, lines) |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
234 lines[-1:] = [(lines[-1][0], lines[-1][1] + b')')] |
25254
060bdfef2517
parser: extract closure of prettyformat() to a top-level function
Yuya Nishihara <yuya@tcha.org>
parents:
25253
diff
changeset
|
235 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
236 |
25253
3f1a9b44b8c2
parser: move prettyformat() function from revset module
Yuya Nishihara <yuya@tcha.org>
parents:
25171
diff
changeset
|
237 def prettyformat(tree, leafnodes): |
3f1a9b44b8c2
parser: move prettyformat() function from revset module
Yuya Nishihara <yuya@tcha.org>
parents:
25171
diff
changeset
|
238 lines = [] |
25254
060bdfef2517
parser: extract closure of prettyformat() to a top-level function
Yuya Nishihara <yuya@tcha.org>
parents:
25253
diff
changeset
|
239 _prettyformat(tree, leafnodes, 0, lines) |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
240 output = b'\n'.join((b' ' * l + s) for l, s in lines) |
25253
3f1a9b44b8c2
parser: move prettyformat() function from revset module
Yuya Nishihara <yuya@tcha.org>
parents:
25171
diff
changeset
|
241 return output |
25306
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
242 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
243 |
25306
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
244 def simplifyinfixops(tree, targetnodes): |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
245 """Flatten chained infix operations to reduce usage of Python stack |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
246 |
34137
a8994d08e4a2
doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents:
34131
diff
changeset
|
247 >>> from . import pycompat |
25306
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
248 >>> def f(tree): |
34137
a8994d08e4a2
doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents:
34131
diff
changeset
|
249 ... s = prettyformat(simplifyinfixops(tree, (b'or',)), (b'symbol',)) |
a8994d08e4a2
doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents:
34131
diff
changeset
|
250 ... print(pycompat.sysstr(s)) |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
251 >>> f((b'or', |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
252 ... (b'or', |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
253 ... (b'symbol', b'1'), |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
254 ... (b'symbol', b'2')), |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
255 ... (b'symbol', b'3'))) |
25306
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
256 (or |
34073
7bbc4e113e5f
parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents:
34045
diff
changeset
|
257 (symbol '1') |
7bbc4e113e5f
parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents:
34045
diff
changeset
|
258 (symbol '2') |
7bbc4e113e5f
parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents:
34045
diff
changeset
|
259 (symbol '3')) |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
260 >>> f((b'func', |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
261 ... (b'symbol', b'p1'), |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
262 ... (b'or', |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
263 ... (b'or', |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
264 ... (b'func', |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
265 ... (b'symbol', b'sort'), |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
266 ... (b'list', |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
267 ... (b'or', |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
268 ... (b'or', |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
269 ... (b'symbol', b'1'), |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
270 ... (b'symbol', b'2')), |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
271 ... (b'symbol', b'3')), |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
272 ... (b'negate', |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
273 ... (b'symbol', b'rev')))), |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
274 ... (b'and', |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
275 ... (b'symbol', b'4'), |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
276 ... (b'group', |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
277 ... (b'or', |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
278 ... (b'or', |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
279 ... (b'symbol', b'5'), |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
280 ... (b'symbol', b'6')), |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
281 ... (b'symbol', b'7'))))), |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
282 ... (b'symbol', b'8')))) |
25306
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
283 (func |
34073
7bbc4e113e5f
parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents:
34045
diff
changeset
|
284 (symbol 'p1') |
25306
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
285 (or |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
286 (func |
34073
7bbc4e113e5f
parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents:
34045
diff
changeset
|
287 (symbol 'sort') |
25306
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
288 (list |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
289 (or |
34073
7bbc4e113e5f
parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents:
34045
diff
changeset
|
290 (symbol '1') |
7bbc4e113e5f
parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents:
34045
diff
changeset
|
291 (symbol '2') |
7bbc4e113e5f
parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents:
34045
diff
changeset
|
292 (symbol '3')) |
25306
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
293 (negate |
34073
7bbc4e113e5f
parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents:
34045
diff
changeset
|
294 (symbol 'rev')))) |
25306
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
295 (and |
34073
7bbc4e113e5f
parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents:
34045
diff
changeset
|
296 (symbol '4') |
25306
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
297 (group |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
298 (or |
34073
7bbc4e113e5f
parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents:
34045
diff
changeset
|
299 (symbol '5') |
7bbc4e113e5f
parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents:
34045
diff
changeset
|
300 (symbol '6') |
7bbc4e113e5f
parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents:
34045
diff
changeset
|
301 (symbol '7')))) |
7bbc4e113e5f
parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents:
34045
diff
changeset
|
302 (symbol '8'))) |
25306
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
303 """ |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
304 if not isinstance(tree, tuple): |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
305 return tree |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
306 op = tree[0] |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
307 if op not in targetnodes: |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
308 return (op,) + tuple(simplifyinfixops(x, targetnodes) for x in tree[1:]) |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
309 |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
310 # walk down left nodes taking each right node. no recursion to left nodes |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
311 # because infix operators are left-associative, i.e. left tree is deep. |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
312 # e.g. '1 + 2 + 3' -> (+ (+ 1 2) 3) -> (+ 1 2 3) |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
313 simplified = [] |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
314 x = tree |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
315 while x[0] == op: |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
316 l, r = x[1:] |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
317 simplified.append(simplifyinfixops(r, targetnodes)) |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
318 x = l |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
319 simplified.append(simplifyinfixops(x, targetnodes)) |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
320 simplified.append(op) |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
321 return tuple(reversed(simplified)) |
28720
639e0f1e8ffa
parser: move parsererrordetail() function from revset module
Yuya Nishihara <yuya@tcha.org>
parents:
26231
diff
changeset
|
322 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
323 |
34043
90896b61fe26
parser: add helper function that constructs parsed tree from template
Yuya Nishihara <yuya@tcha.org>
parents:
31922
diff
changeset
|
324 def _buildtree(template, placeholder, replstack): |
90896b61fe26
parser: add helper function that constructs parsed tree from template
Yuya Nishihara <yuya@tcha.org>
parents:
31922
diff
changeset
|
325 if template == placeholder: |
90896b61fe26
parser: add helper function that constructs parsed tree from template
Yuya Nishihara <yuya@tcha.org>
parents:
31922
diff
changeset
|
326 return replstack.pop() |
90896b61fe26
parser: add helper function that constructs parsed tree from template
Yuya Nishihara <yuya@tcha.org>
parents:
31922
diff
changeset
|
327 if not isinstance(template, tuple): |
90896b61fe26
parser: add helper function that constructs parsed tree from template
Yuya Nishihara <yuya@tcha.org>
parents:
31922
diff
changeset
|
328 return template |
90896b61fe26
parser: add helper function that constructs parsed tree from template
Yuya Nishihara <yuya@tcha.org>
parents:
31922
diff
changeset
|
329 return tuple(_buildtree(x, placeholder, replstack) for x in template) |
90896b61fe26
parser: add helper function that constructs parsed tree from template
Yuya Nishihara <yuya@tcha.org>
parents:
31922
diff
changeset
|
330 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
331 |
34043
90896b61fe26
parser: add helper function that constructs parsed tree from template
Yuya Nishihara <yuya@tcha.org>
parents:
31922
diff
changeset
|
332 def buildtree(template, placeholder, *repls): |
90896b61fe26
parser: add helper function that constructs parsed tree from template
Yuya Nishihara <yuya@tcha.org>
parents:
31922
diff
changeset
|
333 """Create new tree by substituting placeholders by replacements |
90896b61fe26
parser: add helper function that constructs parsed tree from template
Yuya Nishihara <yuya@tcha.org>
parents:
31922
diff
changeset
|
334 |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
335 >>> _ = (b'symbol', b'_') |
34043
90896b61fe26
parser: add helper function that constructs parsed tree from template
Yuya Nishihara <yuya@tcha.org>
parents:
31922
diff
changeset
|
336 >>> def f(template, *repls): |
90896b61fe26
parser: add helper function that constructs parsed tree from template
Yuya Nishihara <yuya@tcha.org>
parents:
31922
diff
changeset
|
337 ... return buildtree(template, _, *repls) |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
338 >>> f((b'func', (b'symbol', b'only'), (b'list', _, _)), |
34043
90896b61fe26
parser: add helper function that constructs parsed tree from template
Yuya Nishihara <yuya@tcha.org>
parents:
31922
diff
changeset
|
339 ... ('symbol', '1'), ('symbol', '2')) |
90896b61fe26
parser: add helper function that constructs parsed tree from template
Yuya Nishihara <yuya@tcha.org>
parents:
31922
diff
changeset
|
340 ('func', ('symbol', 'only'), ('list', ('symbol', '1'), ('symbol', '2'))) |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
341 >>> f((b'and', _, (b'not', _)), (b'symbol', b'1'), (b'symbol', b'2')) |
34043
90896b61fe26
parser: add helper function that constructs parsed tree from template
Yuya Nishihara <yuya@tcha.org>
parents:
31922
diff
changeset
|
342 ('and', ('symbol', '1'), ('not', ('symbol', '2'))) |
90896b61fe26
parser: add helper function that constructs parsed tree from template
Yuya Nishihara <yuya@tcha.org>
parents:
31922
diff
changeset
|
343 """ |
90896b61fe26
parser: add helper function that constructs parsed tree from template
Yuya Nishihara <yuya@tcha.org>
parents:
31922
diff
changeset
|
344 if not isinstance(placeholder, tuple): |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
345 raise error.ProgrammingError(b'placeholder must be a node tuple') |
34043
90896b61fe26
parser: add helper function that constructs parsed tree from template
Yuya Nishihara <yuya@tcha.org>
parents:
31922
diff
changeset
|
346 replstack = list(reversed(repls)) |
90896b61fe26
parser: add helper function that constructs parsed tree from template
Yuya Nishihara <yuya@tcha.org>
parents:
31922
diff
changeset
|
347 r = _buildtree(template, placeholder, replstack) |
90896b61fe26
parser: add helper function that constructs parsed tree from template
Yuya Nishihara <yuya@tcha.org>
parents:
31922
diff
changeset
|
348 if replstack: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
349 raise error.ProgrammingError(b'too many replacements') |
34043
90896b61fe26
parser: add helper function that constructs parsed tree from template
Yuya Nishihara <yuya@tcha.org>
parents:
31922
diff
changeset
|
350 return r |
90896b61fe26
parser: add helper function that constructs parsed tree from template
Yuya Nishihara <yuya@tcha.org>
parents:
31922
diff
changeset
|
351 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
352 |
34045
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
353 def _matchtree(pattern, tree, placeholder, incompletenodes, matches): |
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
354 if pattern == tree: |
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
355 return True |
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
356 if not isinstance(pattern, tuple) or not isinstance(tree, tuple): |
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
357 return False |
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
358 if pattern == placeholder and tree[0] not in incompletenodes: |
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
359 matches.append(tree) |
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
360 return True |
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
361 if len(pattern) != len(tree): |
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
362 return False |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
363 return all( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
364 _matchtree(p, x, placeholder, incompletenodes, matches) |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
365 for p, x in zip(pattern, tree) |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
366 ) |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
367 |
34045
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
368 |
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
369 def matchtree(pattern, tree, placeholder=None, incompletenodes=()): |
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
370 """If a tree matches the pattern, return a list of the tree and nodes |
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
371 matched with the placeholder; Otherwise None |
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
372 |
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
373 >>> def f(pattern, tree): |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
374 ... m = matchtree(pattern, tree, _, {b'keyvalue', b'list'}) |
34045
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
375 ... if m: |
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
376 ... return m[1:] |
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
377 |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
378 >>> _ = (b'symbol', b'_') |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
379 >>> f((b'func', (b'symbol', b'ancestors'), _), |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
380 ... (b'func', (b'symbol', b'ancestors'), (b'symbol', b'1'))) |
34045
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
381 [('symbol', '1')] |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
382 >>> f((b'func', (b'symbol', b'ancestors'), _), |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
383 ... (b'func', (b'symbol', b'ancestors'), None)) |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
384 >>> f((b'range', (b'dagrange', _, _), _), |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
385 ... (b'range', |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
386 ... (b'dagrange', (b'symbol', b'1'), (b'symbol', b'2')), |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
387 ... (b'symbol', b'3'))) |
34045
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
388 [('symbol', '1'), ('symbol', '2'), ('symbol', '3')] |
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
389 |
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
390 The placeholder does not match the specified incomplete nodes because |
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
391 an incomplete node (e.g. argument list) cannot construct an expression. |
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
392 |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
393 >>> f((b'func', (b'symbol', b'ancestors'), _), |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
394 ... (b'func', (b'symbol', b'ancestors'), |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
395 ... (b'list', (b'symbol', b'1'), (b'symbol', b'2')))) |
34045
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
396 |
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
397 The placeholder may be omitted, but which shouldn't match a None node. |
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
398 |
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
399 >>> _ = None |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
400 >>> f((b'func', (b'symbol', b'ancestors'), None), |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
401 ... (b'func', (b'symbol', b'ancestors'), (b'symbol', b'0'))) |
34045
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
402 """ |
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
403 if placeholder is not None and not isinstance(placeholder, tuple): |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
404 raise error.ProgrammingError(b'placeholder must be a node tuple') |
34045
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
405 matches = [tree] |
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
406 if _matchtree(pattern, tree, placeholder, incompletenodes, matches): |
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
407 return matches |
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
408 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
409 |
28720
639e0f1e8ffa
parser: move parsererrordetail() function from revset module
Yuya Nishihara <yuya@tcha.org>
parents:
26231
diff
changeset
|
410 def parseerrordetail(inst): |
45942
89a2afe31e82
formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents:
45776
diff
changeset
|
411 """Compose error message from specified ParseError object""" |
45776
0fc8b066928a
errors: name arguments to ParseError constructor
Martin von Zweigbergk <martinvonz@google.com>
parents:
43787
diff
changeset
|
412 if inst.location is not None: |
0fc8b066928a
errors: name arguments to ParseError constructor
Martin von Zweigbergk <martinvonz@google.com>
parents:
43787
diff
changeset
|
413 return _(b'at %d: %s') % (inst.location, inst.message) |
28720
639e0f1e8ffa
parser: move parsererrordetail() function from revset module
Yuya Nishihara <yuya@tcha.org>
parents:
26231
diff
changeset
|
414 else: |
45776
0fc8b066928a
errors: name arguments to ParseError constructor
Martin von Zweigbergk <martinvonz@google.com>
parents:
43787
diff
changeset
|
415 return inst.message |
28870
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
416 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
417 |
48946
642e31cb55f0
py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48875
diff
changeset
|
418 class alias: |
28892
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
419 """Parsed result of alias""" |
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
420 |
28908
7a772deffa12
parser: drop redundant comparison between alias declaration tree and pattern
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
421 def __init__(self, name, args, err, replacement): |
28892
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
422 self.name = name |
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
423 self.args = args |
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
424 self.error = err |
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
425 self.replacement = replacement |
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
426 # whether own `error` information is already shown or not. |
28898
8d398155bfda
revset: rename findaliases() to expandaliases()
Yuya Nishihara <yuya@tcha.org>
parents:
28897
diff
changeset
|
427 # this avoids showing same warning multiple times at each |
8d398155bfda
revset: rename findaliases() to expandaliases()
Yuya Nishihara <yuya@tcha.org>
parents:
28897
diff
changeset
|
428 # `expandaliases`. |
28892
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
429 self.warned = False |
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
430 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
431 |
48946
642e31cb55f0
py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48875
diff
changeset
|
432 class basealiasrules: |
28870
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
433 """Parsing and expansion rule set of aliases |
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
434 |
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
435 This is a helper for fileset/revset/template aliases. A concrete rule set |
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
436 should be made by sub-classing this and implementing class/static methods. |
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
437 |
30332
318a24b52eeb
spelling: fixes of non-dictionary words
Mads Kiilerich <madski@unity3d.com>
parents:
29767
diff
changeset
|
438 It supports alias expansion of symbol and function-call styles:: |
28870
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
439 |
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
440 # decl = defn |
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
441 h = heads(default) |
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
442 b($1) = ancestors($1) - ancestors(default) |
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
443 """ |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
444 |
28870
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
445 # typically a config section, which will be included in error messages |
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
446 _section = None |
28910
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
447 # tag of symbol node |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
448 _symbolnode = b'symbol' |
28870
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
449 |
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
450 def __new__(cls): |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
451 raise TypeError(b"'%s' is not instantiatable" % cls.__name__) |
28870
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
452 |
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
453 @staticmethod |
28875
2e9f5453ab5a
parser: unify parser function of alias declaration and definition
Yuya Nishihara <yuya@tcha.org>
parents:
28873
diff
changeset
|
454 def _parse(spec): |
2e9f5453ab5a
parser: unify parser function of alias declaration and definition
Yuya Nishihara <yuya@tcha.org>
parents:
28873
diff
changeset
|
455 """Parse an alias name, arguments and definition""" |
28870
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
456 raise NotImplementedError |
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
457 |
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
458 @staticmethod |
28910
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
459 def _trygetfunc(tree): |
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
460 """Return (name, args) if tree is a function; otherwise None""" |
28870
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
461 raise NotImplementedError |
28871
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
462 |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
463 @classmethod |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
464 def _builddecl(cls, decl): |
28908
7a772deffa12
parser: drop redundant comparison between alias declaration tree and pattern
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
465 """Parse an alias declaration into ``(name, args, errorstr)`` |
28871
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
466 |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
467 This function analyzes the parsed tree. The parsing rule is provided |
28875
2e9f5453ab5a
parser: unify parser function of alias declaration and definition
Yuya Nishihara <yuya@tcha.org>
parents:
28873
diff
changeset
|
468 by ``_parse()``. |
28871
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
469 |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
470 - ``name``: of declared alias (may be ``decl`` itself at error) |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
471 - ``args``: list of argument names (or None for symbol declaration) |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
472 - ``errorstr``: detail about detected error (or None) |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
473 |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
474 >>> sym = lambda x: (b'symbol', x) |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
475 >>> symlist = lambda *xs: (b'list',) + tuple(sym(x) for x in xs) |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
476 >>> func = lambda n, a: (b'func', sym(n), a) |
28871
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
477 >>> parsemap = { |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
478 ... b'foo': sym(b'foo'), |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
479 ... b'$foo': sym(b'$foo'), |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
480 ... b'foo::bar': (b'dagrange', sym(b'foo'), sym(b'bar')), |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
481 ... b'foo()': func(b'foo', None), |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
482 ... b'$foo()': func(b'$foo', None), |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
483 ... b'foo($1, $2)': func(b'foo', symlist(b'$1', b'$2')), |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
484 ... b'foo(bar_bar, baz.baz)': |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
485 ... func(b'foo', symlist(b'bar_bar', b'baz.baz')), |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
486 ... b'foo(bar($1, $2))': |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
487 ... func(b'foo', func(b'bar', symlist(b'$1', b'$2'))), |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
488 ... b'foo($1, $2, nested($1, $2))': |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
489 ... func(b'foo', (symlist(b'$1', b'$2') + |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
490 ... (func(b'nested', symlist(b'$1', b'$2')),))), |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
491 ... b'foo("bar")': func(b'foo', (b'string', b'bar')), |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
492 ... b'foo($1, $2': error.ParseError(b'unexpected token: end', 10), |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
493 ... b'foo("bar': error.ParseError(b'unterminated string', 5), |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
494 ... b'foo($1, $2, $1)': func(b'foo', symlist(b'$1', b'$2', b'$1')), |
28871
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
495 ... } |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
496 >>> def parse(expr): |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
497 ... x = parsemap[expr] |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
498 ... if isinstance(x, Exception): |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
499 ... raise x |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
500 ... return x |
28910
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
501 >>> def trygetfunc(tree): |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
502 ... if not tree or tree[0] != b'func' or tree[1][0] != b'symbol': |
28910
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
503 ... return None |
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
504 ... if not tree[2]: |
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
505 ... return tree[1][1], [] |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
506 ... if tree[2][0] == b'list': |
28910
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
507 ... return tree[1][1], list(tree[2][1:]) |
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
508 ... return tree[1][1], [tree[2]] |
28871
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
509 >>> class aliasrules(basealiasrules): |
28875
2e9f5453ab5a
parser: unify parser function of alias declaration and definition
Yuya Nishihara <yuya@tcha.org>
parents:
28873
diff
changeset
|
510 ... _parse = staticmethod(parse) |
28910
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
511 ... _trygetfunc = staticmethod(trygetfunc) |
28871
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
512 >>> builddecl = aliasrules._builddecl |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
513 >>> builddecl(b'foo') |
28908
7a772deffa12
parser: drop redundant comparison between alias declaration tree and pattern
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
514 ('foo', None, None) |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
515 >>> builddecl(b'$foo') |
29058
dbed4c4f48ae
parser: rephrase "'$' not for alias arguments" message
Yuya Nishihara <yuya@tcha.org>
parents:
28910
diff
changeset
|
516 ('$foo', None, "invalid symbol '$foo'") |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
517 >>> builddecl(b'foo::bar') |
28908
7a772deffa12
parser: drop redundant comparison between alias declaration tree and pattern
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
518 ('foo::bar', None, 'invalid format') |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
519 >>> builddecl(b'foo()') |
28908
7a772deffa12
parser: drop redundant comparison between alias declaration tree and pattern
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
520 ('foo', [], None) |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
521 >>> builddecl(b'$foo()') |
29058
dbed4c4f48ae
parser: rephrase "'$' not for alias arguments" message
Yuya Nishihara <yuya@tcha.org>
parents:
28910
diff
changeset
|
522 ('$foo()', None, "invalid function '$foo'") |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
523 >>> builddecl(b'foo($1, $2)') |
28908
7a772deffa12
parser: drop redundant comparison between alias declaration tree and pattern
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
524 ('foo', ['$1', '$2'], None) |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
525 >>> builddecl(b'foo(bar_bar, baz.baz)') |
28908
7a772deffa12
parser: drop redundant comparison between alias declaration tree and pattern
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
526 ('foo', ['bar_bar', 'baz.baz'], None) |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
527 >>> builddecl(b'foo($1, $2, nested($1, $2))') |
28908
7a772deffa12
parser: drop redundant comparison between alias declaration tree and pattern
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
528 ('foo($1, $2, nested($1, $2))', None, 'invalid argument list') |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
529 >>> builddecl(b'foo(bar($1, $2))') |
28908
7a772deffa12
parser: drop redundant comparison between alias declaration tree and pattern
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
530 ('foo(bar($1, $2))', None, 'invalid argument list') |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
531 >>> builddecl(b'foo("bar")') |
28908
7a772deffa12
parser: drop redundant comparison between alias declaration tree and pattern
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
532 ('foo("bar")', None, 'invalid argument list') |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
533 >>> builddecl(b'foo($1, $2') |
28908
7a772deffa12
parser: drop redundant comparison between alias declaration tree and pattern
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
534 ('foo($1, $2', None, 'at 10: unexpected token: end') |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
535 >>> builddecl(b'foo("bar') |
28908
7a772deffa12
parser: drop redundant comparison between alias declaration tree and pattern
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
536 ('foo("bar', None, 'at 5: unterminated string') |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
537 >>> builddecl(b'foo($1, $2, $1)') |
28908
7a772deffa12
parser: drop redundant comparison between alias declaration tree and pattern
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
538 ('foo', None, 'argument names collide with each other') |
28871
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
539 """ |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
540 try: |
28875
2e9f5453ab5a
parser: unify parser function of alias declaration and definition
Yuya Nishihara <yuya@tcha.org>
parents:
28873
diff
changeset
|
541 tree = cls._parse(decl) |
28871
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
542 except error.ParseError as inst: |
28908
7a772deffa12
parser: drop redundant comparison between alias declaration tree and pattern
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
543 return (decl, None, parseerrordetail(inst)) |
28871
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
544 |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
545 if tree[0] == cls._symbolnode: |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
546 # "name = ...." style |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
547 name = tree[1] |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
548 if name.startswith(b'$'): |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
549 return (decl, None, _(b"invalid symbol '%s'") % name) |
28908
7a772deffa12
parser: drop redundant comparison between alias declaration tree and pattern
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
550 return (name, None, None) |
28871
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
551 |
28910
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
552 func = cls._trygetfunc(tree) |
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
553 if func: |
28871
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
554 # "name(arg, ....) = ...." style |
28910
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
555 name, args = func |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
556 if name.startswith(b'$'): |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
557 return (decl, None, _(b"invalid function '%s'") % name) |
28910
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
558 if any(t[0] != cls._symbolnode for t in args): |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
559 return (decl, None, _(b"invalid argument list")) |
28871
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
560 if len(args) != len(set(args)): |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
561 return ( |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
562 name, |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
563 None, |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
564 _(b"argument names collide with each other"), |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
565 ) |
28910
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
566 return (name, [t[1] for t in args], None) |
28871
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
567 |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
568 return (decl, None, _(b"invalid format")) |
28872
5f31d2248745
parser: move _relabelaliasargs() to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28871
diff
changeset
|
569 |
5f31d2248745
parser: move _relabelaliasargs() to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28871
diff
changeset
|
570 @classmethod |
5f31d2248745
parser: move _relabelaliasargs() to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28871
diff
changeset
|
571 def _relabelargs(cls, tree, args): |
5f31d2248745
parser: move _relabelaliasargs() to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28871
diff
changeset
|
572 """Mark alias arguments as ``_aliasarg``""" |
5f31d2248745
parser: move _relabelaliasargs() to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28871
diff
changeset
|
573 if not isinstance(tree, tuple): |
5f31d2248745
parser: move _relabelaliasargs() to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28871
diff
changeset
|
574 return tree |
5f31d2248745
parser: move _relabelaliasargs() to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28871
diff
changeset
|
575 op = tree[0] |
5f31d2248745
parser: move _relabelaliasargs() to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28871
diff
changeset
|
576 if op != cls._symbolnode: |
5f31d2248745
parser: move _relabelaliasargs() to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28871
diff
changeset
|
577 return (op,) + tuple(cls._relabelargs(x, args) for x in tree[1:]) |
5f31d2248745
parser: move _relabelaliasargs() to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28871
diff
changeset
|
578 |
5f31d2248745
parser: move _relabelaliasargs() to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28871
diff
changeset
|
579 assert len(tree) == 2 |
5f31d2248745
parser: move _relabelaliasargs() to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28871
diff
changeset
|
580 sym = tree[1] |
5f31d2248745
parser: move _relabelaliasargs() to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28871
diff
changeset
|
581 if sym in args: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
582 op = b'_aliasarg' |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
583 elif sym.startswith(b'$'): |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
584 raise error.ParseError(_(b"invalid symbol '%s'") % sym) |
28872
5f31d2248745
parser: move _relabelaliasargs() to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28871
diff
changeset
|
585 return (op, sym) |
28873
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
586 |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
587 @classmethod |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
588 def _builddefn(cls, defn, args): |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
589 """Parse an alias definition into a tree and marks substitutions |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
590 |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
591 This function marks alias argument references as ``_aliasarg``. The |
28875
2e9f5453ab5a
parser: unify parser function of alias declaration and definition
Yuya Nishihara <yuya@tcha.org>
parents:
28873
diff
changeset
|
592 parsing rule is provided by ``_parse()``. |
28873
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
593 |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
594 ``args`` is a list of alias argument names, or None if the alias |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
595 is declared as a symbol. |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
596 |
34137
a8994d08e4a2
doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents:
34131
diff
changeset
|
597 >>> from . import pycompat |
28873
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
598 >>> parsemap = { |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
599 ... b'$1 or foo': (b'or', (b'symbol', b'$1'), (b'symbol', b'foo')), |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
600 ... b'$1 or $bar': |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
601 ... (b'or', (b'symbol', b'$1'), (b'symbol', b'$bar')), |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
602 ... b'$10 or baz': |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
603 ... (b'or', (b'symbol', b'$10'), (b'symbol', b'baz')), |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
604 ... b'"$1" or "foo"': |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
605 ... (b'or', (b'string', b'$1'), (b'string', b'foo')), |
28873
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
606 ... } |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
607 >>> class aliasrules(basealiasrules): |
28875
2e9f5453ab5a
parser: unify parser function of alias declaration and definition
Yuya Nishihara <yuya@tcha.org>
parents:
28873
diff
changeset
|
608 ... _parse = staticmethod(parsemap.__getitem__) |
28910
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
609 ... _trygetfunc = staticmethod(lambda x: None) |
28873
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
610 >>> builddefn = aliasrules._builddefn |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
611 >>> def pprint(tree): |
34137
a8994d08e4a2
doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents:
34131
diff
changeset
|
612 ... s = prettyformat(tree, (b'_aliasarg', b'string', b'symbol')) |
a8994d08e4a2
doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents:
34131
diff
changeset
|
613 ... print(pycompat.sysstr(s)) |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
614 >>> args = [b'$1', b'$2', b'foo'] |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
615 >>> pprint(builddefn(b'$1 or foo', args)) |
28873
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
616 (or |
34073
7bbc4e113e5f
parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents:
34045
diff
changeset
|
617 (_aliasarg '$1') |
7bbc4e113e5f
parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents:
34045
diff
changeset
|
618 (_aliasarg 'foo')) |
28873
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
619 >>> try: |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
620 ... builddefn(b'$1 or $bar', args) |
28873
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
621 ... except error.ParseError as inst: |
34137
a8994d08e4a2
doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents:
34131
diff
changeset
|
622 ... print(pycompat.sysstr(parseerrordetail(inst))) |
29058
dbed4c4f48ae
parser: rephrase "'$' not for alias arguments" message
Yuya Nishihara <yuya@tcha.org>
parents:
28910
diff
changeset
|
623 invalid symbol '$bar' |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
624 >>> args = [b'$1', b'$10', b'foo'] |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
625 >>> pprint(builddefn(b'$10 or baz', args)) |
28873
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
626 (or |
34073
7bbc4e113e5f
parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents:
34045
diff
changeset
|
627 (_aliasarg '$10') |
7bbc4e113e5f
parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents:
34045
diff
changeset
|
628 (symbol 'baz')) |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
629 >>> pprint(builddefn(b'"$1" or "foo"', args)) |
28873
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
630 (or |
34073
7bbc4e113e5f
parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents:
34045
diff
changeset
|
631 (string '$1') |
7bbc4e113e5f
parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents:
34045
diff
changeset
|
632 (string 'foo')) |
28873
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
633 """ |
28875
2e9f5453ab5a
parser: unify parser function of alias declaration and definition
Yuya Nishihara <yuya@tcha.org>
parents:
28873
diff
changeset
|
634 tree = cls._parse(defn) |
28873
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
635 if args: |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
636 args = set(args) |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
637 else: |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
638 args = set() |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
639 return cls._relabelargs(tree, args) |
28892
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
640 |
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
641 @classmethod |
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
642 def build(cls, decl, defn): |
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
643 """Parse an alias declaration and definition into an alias object""" |
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
644 repl = efmt = None |
28908
7a772deffa12
parser: drop redundant comparison between alias declaration tree and pattern
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
645 name, args, err = cls._builddecl(decl) |
28892
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
646 if err: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
647 efmt = _(b'bad declaration of %(section)s "%(name)s": %(error)s') |
28892
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
648 else: |
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
649 try: |
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
650 repl = cls._builddefn(defn, args) |
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
651 except error.ParseError as inst: |
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
652 err = parseerrordetail(inst) |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
653 efmt = _(b'bad definition of %(section)s "%(name)s": %(error)s') |
28892
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
654 if err: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
655 err = efmt % { |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
656 b'section': cls._section, |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
657 b'name': name, |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
658 b'error': err, |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
659 } |
28908
7a772deffa12
parser: drop redundant comparison between alias declaration tree and pattern
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
660 return alias(name, args, err, repl) |
28893
ee11167fe1da
parser: extract helper that creates a dict of aliases
Yuya Nishihara <yuya@tcha.org>
parents:
28892
diff
changeset
|
661 |
ee11167fe1da
parser: extract helper that creates a dict of aliases
Yuya Nishihara <yuya@tcha.org>
parents:
28892
diff
changeset
|
662 @classmethod |
ee11167fe1da
parser: extract helper that creates a dict of aliases
Yuya Nishihara <yuya@tcha.org>
parents:
28892
diff
changeset
|
663 def buildmap(cls, items): |
ee11167fe1da
parser: extract helper that creates a dict of aliases
Yuya Nishihara <yuya@tcha.org>
parents:
28892
diff
changeset
|
664 """Parse a list of alias (name, replacement) pairs into a dict of |
ee11167fe1da
parser: extract helper that creates a dict of aliases
Yuya Nishihara <yuya@tcha.org>
parents:
28892
diff
changeset
|
665 alias objects""" |
ee11167fe1da
parser: extract helper that creates a dict of aliases
Yuya Nishihara <yuya@tcha.org>
parents:
28892
diff
changeset
|
666 aliases = {} |
ee11167fe1da
parser: extract helper that creates a dict of aliases
Yuya Nishihara <yuya@tcha.org>
parents:
28892
diff
changeset
|
667 for decl, defn in items: |
ee11167fe1da
parser: extract helper that creates a dict of aliases
Yuya Nishihara <yuya@tcha.org>
parents:
28892
diff
changeset
|
668 a = cls.build(decl, defn) |
ee11167fe1da
parser: extract helper that creates a dict of aliases
Yuya Nishihara <yuya@tcha.org>
parents:
28892
diff
changeset
|
669 aliases[a.name] = a |
ee11167fe1da
parser: extract helper that creates a dict of aliases
Yuya Nishihara <yuya@tcha.org>
parents:
28892
diff
changeset
|
670 return aliases |
28895
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
671 |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
672 @classmethod |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
673 def _getalias(cls, aliases, tree): |
28909
edbffdc7f6a0
parser: make _getalias() return (alias, pattern-args) pair
Yuya Nishihara <yuya@tcha.org>
parents:
28908
diff
changeset
|
674 """If tree looks like an unexpanded alias, return (alias, pattern-args) |
edbffdc7f6a0
parser: make _getalias() return (alias, pattern-args) pair
Yuya Nishihara <yuya@tcha.org>
parents:
28908
diff
changeset
|
675 pair. Return None otherwise. |
28895
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
676 """ |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
677 if not isinstance(tree, tuple): |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
678 return None |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
679 if tree[0] == cls._symbolnode: |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
680 name = tree[1] |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
681 a = aliases.get(name) |
28908
7a772deffa12
parser: drop redundant comparison between alias declaration tree and pattern
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
682 if a and a.args is None: |
28909
edbffdc7f6a0
parser: make _getalias() return (alias, pattern-args) pair
Yuya Nishihara <yuya@tcha.org>
parents:
28908
diff
changeset
|
683 return a, None |
28910
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
684 func = cls._trygetfunc(tree) |
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
685 if func: |
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
686 name, args = func |
28895
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
687 a = aliases.get(name) |
28908
7a772deffa12
parser: drop redundant comparison between alias declaration tree and pattern
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
688 if a and a.args is not None: |
28910
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
689 return a, args |
28895
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
690 return None |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
691 |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
692 @classmethod |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
693 def _expandargs(cls, tree, args): |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
694 """Replace _aliasarg instances with the substitution value of the |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
695 same name in args, recursively. |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
696 """ |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
697 if not isinstance(tree, tuple): |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
698 return tree |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
699 if tree[0] == b'_aliasarg': |
28895
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
700 sym = tree[1] |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
701 return args[sym] |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
702 return tuple(cls._expandargs(t, args) for t in tree) |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
703 |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
704 @classmethod |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
705 def _expand(cls, aliases, tree, expanding, cache): |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
706 if not isinstance(tree, tuple): |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
707 return tree |
28909
edbffdc7f6a0
parser: make _getalias() return (alias, pattern-args) pair
Yuya Nishihara <yuya@tcha.org>
parents:
28908
diff
changeset
|
708 r = cls._getalias(aliases, tree) |
edbffdc7f6a0
parser: make _getalias() return (alias, pattern-args) pair
Yuya Nishihara <yuya@tcha.org>
parents:
28908
diff
changeset
|
709 if r is None: |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
710 return tuple( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
711 cls._expand(aliases, t, expanding, cache) for t in tree |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
712 ) |
28909
edbffdc7f6a0
parser: make _getalias() return (alias, pattern-args) pair
Yuya Nishihara <yuya@tcha.org>
parents:
28908
diff
changeset
|
713 a, l = r |
28896
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
714 if a.error: |
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
715 raise error.Abort(a.error) |
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
716 if a in expanding: |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
717 raise error.ParseError( |
43117
8ff1ecfadcd1
cleanup: join string literals that are already on one line
Martin von Zweigbergk <martinvonz@google.com>
parents:
43077
diff
changeset
|
718 _(b'infinite expansion of %(section)s "%(name)s" detected') |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
719 % {b'section': cls._section, b'name': a.name} |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
720 ) |
28897
c1f254138f44
parser: add short comment how aliases are expanded in phases
Yuya Nishihara <yuya@tcha.org>
parents:
28896
diff
changeset
|
721 # get cacheable replacement tree by expanding aliases recursively |
28896
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
722 expanding.append(a) |
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
723 if a.name not in cache: |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
724 cache[a.name] = cls._expand( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
725 aliases, a.replacement, expanding, cache |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
726 ) |
28896
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
727 result = cache[a.name] |
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
728 expanding.pop() |
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
729 if a.args is None: |
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
730 return result |
28897
c1f254138f44
parser: add short comment how aliases are expanded in phases
Yuya Nishihara <yuya@tcha.org>
parents:
28896
diff
changeset
|
731 # substitute function arguments in replacement tree |
28896
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
732 if len(l) != len(a.args): |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
733 raise error.ParseError( |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
734 _(b'invalid number of arguments: %d') % len(l) |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42232
diff
changeset
|
735 ) |
28896
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
736 l = [cls._expand(aliases, t, [], cache) for t in l] |
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
737 return cls._expandargs(result, dict(zip(a.args, l))) |
28895
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
738 |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
739 @classmethod |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
740 def expand(cls, aliases, tree): |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
741 """Expand aliases in tree, recursively. |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
742 |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
743 'aliases' is a dictionary mapping user defined aliases to alias objects. |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
744 """ |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
745 return cls._expand(aliases, tree, [], {}) |