Mercurial > hg
annotate mercurial/parser.py @ 40324:6637b079ae45
lfs: autoload the extension when cloning from repo with lfs enabled
This is based on a patch by Gregory Szorc. I made small adjustments to
clean up the messaging when the server has the extension enabled, but the
client has it disabled (to prevent autoloading). Additionally, I added
a second server capability to distinguish between the server having the
extension enabled, and the server having LFS commits. This helps prevent
unnecessary requirement propagation- the client shouldn't add a requirement
that the server doesn't have, just because the server had the extension
loaded. The TODO I had about advertising a capability when the server can
natively serve up blobs isn't relevant anymore (we've had 2 releases that
support this), so I dropped it.
Currently, we lazily add the "lfs" requirement to a repo when we first
encounter LFS data. Due to a pretxnchangegroup hook that looks for LFS
data, this can happen at the end of clone.
Now that we have more control over how repositories are created, we can
do better.
This commit adds a repo creation option to add the "lfs" requirement.
hg.clone() sets this creation option if the remote peer is advertising
lfs usage (as opposed to just support needed to push).
So, what this change effectively does is have cloned repos
automatically inherit the "lfs" requirement.
Differential Revision: https://phab.mercurial-scm.org/D5130
author | Matt Harbison <matt_harbison@yahoo.com> |
---|---|
date | Thu, 20 Sep 2018 17:27:01 -0700 |
parents | 0a2ce5b43574 |
children | 29798c9ba5c9 |
rev | line source |
---|---|
11274 | 1 # parser.py - simple top-down operator precedence parser for mercurial |
2 # | |
3 # Copyright 2010 Matt Mackall <mpm@selenic.com> | |
4 # | |
5 # This software may be used and distributed according to the terms of the | |
6 # GNU General Public License version 2 or any later version. | |
7 | |
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 |
34137
a8994d08e4a2
doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents:
34131
diff
changeset
|
19 from __future__ import absolute_import, print_function |
25963
7448df709b2e
parser: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25818
diff
changeset
|
20 |
7448df709b2e
parser: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25818
diff
changeset
|
21 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
|
22 from . import ( |
afb335353d28
util: wrap s.decode('string_escape') calls for future py3 compatibility
Yuya Nishihara <yuya@tcha.org>
parents:
31353
diff
changeset
|
23 error, |
36547
7840d8bd0558
py3: byte-stringify ValueError of unescapestr() to reraise as ParseError
Yuya Nishihara <yuya@tcha.org>
parents:
34137
diff
changeset
|
24 pycompat, |
31484
afb335353d28
util: wrap s.decode('string_escape') calls for future py3 compatibility
Yuya Nishihara <yuya@tcha.org>
parents:
31353
diff
changeset
|
25 util, |
afb335353d28
util: wrap s.decode('string_escape') calls for future py3 compatibility
Yuya Nishihara <yuya@tcha.org>
parents:
31353
diff
changeset
|
26 ) |
37084
f0b6fbea00cf
stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36547
diff
changeset
|
27 from .utils import ( |
f0b6fbea00cf
stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36547
diff
changeset
|
28 stringutil, |
f0b6fbea00cf
stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36547
diff
changeset
|
29 ) |
11289
4215ce511134
revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents:
11278
diff
changeset
|
30 |
11274 | 31 class parser(object): |
25654
af329a84310c
parser: accept iterator of tokens instead of tokenizer function and program
Yuya Nishihara <yuya@tcha.org>
parents:
25306
diff
changeset
|
32 def __init__(self, elements, methods=None): |
11274 | 33 self._elements = elements |
34 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
|
35 self.current = None |
11274 | 36 def _advance(self): |
37 'advance the tokenizer' | |
38 t = self.current | |
25171
d647f97f88dd
parsers: use 'next' instead of try/except
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20778
diff
changeset
|
39 self.current = next(self._iter, None) |
11274 | 40 return t |
25804
f0a77cb6316a
parser: extract function that tests if next token may start new term
Yuya Nishihara <yuya@tcha.org>
parents:
25803
diff
changeset
|
41 def _hasnewterm(self): |
f0a77cb6316a
parser: extract function that tests if next token may start new term
Yuya Nishihara <yuya@tcha.org>
parents:
25803
diff
changeset
|
42 '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
|
43 return any(self._elements[self.current[0]][1:3]) |
25802
cc741c76b26a
parser: remove unused parameter 'pos' from _match()
Yuya Nishihara <yuya@tcha.org>
parents:
25801
diff
changeset
|
44 def _match(self, m): |
11274 | 45 'make sure the tokenizer matches an end condition' |
46 if self.current[0] != m: | |
14701
4b93bd041772
parsers: fix localization markup of parser errors
Mads Kiilerich <mads@kiilerich.com>
parents:
13665
diff
changeset
|
47 raise error.ParseError(_("unexpected token: %s") % self.current[0], |
11305
d4cafcb63f77
cleanups: undefined variables
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
11289
diff
changeset
|
48 self.current[2]) |
11274 | 49 self._advance() |
25803
b3004d273874
parser: factor out function that parses right-hand side of prefix/infix ops
Yuya Nishihara <yuya@tcha.org>
parents:
25802
diff
changeset
|
50 def _parseoperand(self, bind, m=None): |
b3004d273874
parser: factor out function that parses right-hand side of prefix/infix ops
Yuya Nishihara <yuya@tcha.org>
parents:
25802
diff
changeset
|
51 'gather right-hand-side operand until an end condition or binding met' |
b3004d273874
parser: factor out function that parses right-hand side of prefix/infix ops
Yuya Nishihara <yuya@tcha.org>
parents:
25802
diff
changeset
|
52 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
|
53 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
|
54 else: |
b3004d273874
parser: factor out function that parses right-hand side of prefix/infix ops
Yuya Nishihara <yuya@tcha.org>
parents:
25802
diff
changeset
|
55 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
|
56 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
|
57 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
|
58 return expr |
11274 | 59 def _parse(self, bind=0): |
11289
4215ce511134
revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents:
11278
diff
changeset
|
60 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
|
61 # 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
|
62 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
|
63 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
|
64 expr = (primary, value) |
e71e5629e006
parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents:
25804
diff
changeset
|
65 elif prefix: |
e71e5629e006
parser: separate actions for primary expression and prefix operator
Yuya Nishihara <yuya@tcha.org>
parents:
25804
diff
changeset
|
66 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
|
67 else: |
14701
4b93bd041772
parsers: fix localization markup of parser errors
Mads Kiilerich <mads@kiilerich.com>
parents:
13665
diff
changeset
|
68 raise error.ParseError(_("not a prefix: %s") % token, pos) |
11274 | 69 # gather tokens until we meet a lower binding strength |
70 while bind < self._elements[self.current[0]][0]: | |
11289
4215ce511134
revset: raise ParseError exceptions
Matt Mackall <mpm@selenic.com>
parents:
11278
diff
changeset
|
71 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
|
72 # 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
|
73 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
|
74 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
|
75 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
|
76 elif infix: |
42ac9d1d1572
parser: reorder infix/suffix handling to be similar to prefix/primary flow
Yuya Nishihara <yuya@tcha.org>
parents:
25816
diff
changeset
|
77 expr = (infix[0], expr, self._parseoperand(*infix[1:])) |
11274 | 78 else: |
25817
42ac9d1d1572
parser: reorder infix/suffix handling to be similar to prefix/primary flow
Yuya Nishihara <yuya@tcha.org>
parents:
25816
diff
changeset
|
79 raise error.ParseError(_("not an infix: %s") % token, pos) |
11274 | 80 return expr |
25654
af329a84310c
parser: accept iterator of tokens instead of tokenizer function and program
Yuya Nishihara <yuya@tcha.org>
parents:
25306
diff
changeset
|
81 def parse(self, tokeniter): |
af329a84310c
parser: accept iterator of tokens instead of tokenizer function and program
Yuya Nishihara <yuya@tcha.org>
parents:
25306
diff
changeset
|
82 'generate a parse tree from tokens' |
af329a84310c
parser: accept iterator of tokens instead of tokenizer function and program
Yuya Nishihara <yuya@tcha.org>
parents:
25306
diff
changeset
|
83 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
|
84 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
|
85 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
|
86 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
|
87 return res, pos |
11274 | 88 def eval(self, tree): |
89 'recursively evaluate a parse tree using node methods' | |
90 if not isinstance(tree, tuple): | |
91 return tree | |
92 return self._methods[tree[0]](*[self.eval(t) for t in tree[1:]]) | |
25654
af329a84310c
parser: accept iterator of tokens instead of tokenizer function and program
Yuya Nishihara <yuya@tcha.org>
parents:
25306
diff
changeset
|
93 def __call__(self, tokeniter): |
af329a84310c
parser: accept iterator of tokens instead of tokenizer function and program
Yuya Nishihara <yuya@tcha.org>
parents:
25306
diff
changeset
|
94 'parse tokens into a parse tree and evaluate if methods given' |
af329a84310c
parser: accept iterator of tokens instead of tokenizer function and program
Yuya Nishihara <yuya@tcha.org>
parents:
25306
diff
changeset
|
95 t = self.parse(tokeniter) |
11274 | 96 if self._methods: |
97 return self.eval(t) | |
98 return t | |
25253
3f1a9b44b8c2
parser: move prettyformat() function from revset module
Yuya Nishihara <yuya@tcha.org>
parents:
25171
diff
changeset
|
99 |
30753
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
100 def splitargspec(spec): |
31921
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
101 """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
|
102 |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
103 >>> splitargspec(b'') |
31921
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
104 ([], None, [], None) |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
105 >>> splitargspec(b'foo bar') |
31921
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
106 ([], 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
|
107 >>> 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
|
108 (['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
|
109 >>> splitargspec(b'*foo') |
31921
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
110 ([], 'foo', [], None) |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
111 >>> splitargspec(b'**foo') |
31921
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
112 ([], None, [], 'foo') |
30753
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
113 """ |
31921
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
114 optkey = None |
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
115 pre, sep, post = spec.partition('**') |
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
116 if sep: |
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
117 posts = post.split() |
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
118 if not posts: |
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
119 raise error.ProgrammingError('no **optkey name provided') |
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
120 if len(posts) > 1: |
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
121 raise error.ProgrammingError('excessive **optkey names provided') |
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
122 optkey = posts[0] |
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
123 |
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
124 pre, sep, post = pre.partition('*') |
30753
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
125 pres = pre.split() |
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
126 posts = post.split() |
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
127 if sep: |
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
128 if not posts: |
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
129 raise error.ProgrammingError('no *varkey name provided') |
31921
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
130 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
|
131 return [], None, pres, optkey |
30753
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
132 |
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
133 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
|
134 """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
|
135 |
31921
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
136 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
|
137 where |
30753
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
138 |
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
139 - ``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
|
140 - ``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
|
141 - ``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
|
142 - ``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
|
143 |
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
144 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
|
145 |
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
146 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
|
147 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
|
148 """ |
31921
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
149 poskeys, varkey, keys, optkey = argspec |
30752
ffd324eaf994
parser: make buildargsdict() precompute position where keyword args start
Yuya Nishihara <yuya@tcha.org>
parents:
30332
diff
changeset
|
150 kwstart = next((i for i, x in enumerate(trees) if x[0] == keyvaluenode), |
ffd324eaf994
parser: make buildargsdict() precompute position where keyword args start
Yuya Nishihara <yuya@tcha.org>
parents:
30332
diff
changeset
|
151 len(trees)) |
30753
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
152 if kwstart < len(poskeys): |
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
153 raise error.ParseError(_("%(func)s takes at least %(nargs)d positional " |
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
154 "arguments") |
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
155 % {'func': funcname, 'nargs': len(poskeys)}) |
31920
a98540ea1e42
parser: verify excessive number of args excluding kwargs in buildargsdict()
Yuya Nishihara <yuya@tcha.org>
parents:
31484
diff
changeset
|
156 if not varkey and kwstart > len(poskeys) + len(keys): |
a98540ea1e42
parser: verify excessive number of args excluding kwargs in buildargsdict()
Yuya Nishihara <yuya@tcha.org>
parents:
31484
diff
changeset
|
157 raise error.ParseError(_("%(func)s takes at most %(nargs)d positional " |
a98540ea1e42
parser: verify excessive number of args excluding kwargs in buildargsdict()
Yuya Nishihara <yuya@tcha.org>
parents:
31484
diff
changeset
|
158 "arguments") |
30753
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
159 % {'func': funcname, |
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
160 'nargs': len(poskeys) + len(keys)}) |
31922
0f41f1e3c75c
parser: preserve order of keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents:
31921
diff
changeset
|
161 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
|
162 # consume positional arguments |
30753
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
163 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
|
164 args[k] = x |
30753
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
165 if varkey: |
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
166 args[varkey] = trees[len(args):kwstart] |
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
167 else: |
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
168 for k, x in zip(keys, trees[len(args):kwstart]): |
c3a3896a9fa8
parser: extend buildargsdict() to support variable-length positional args
Yuya Nishihara <yuya@tcha.org>
parents:
30752
diff
changeset
|
169 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
|
170 # 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
|
171 if optkey: |
31922
0f41f1e3c75c
parser: preserve order of keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents:
31921
diff
changeset
|
172 args[optkey] = util.sortdict() |
30752
ffd324eaf994
parser: make buildargsdict() precompute position where keyword args start
Yuya Nishihara <yuya@tcha.org>
parents:
30332
diff
changeset
|
173 for x in trees[kwstart:]: |
25705
48919d246a47
revset: add function to build dict of positional and keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents:
25655
diff
changeset
|
174 if x[0] != keyvaluenode or x[1][0] != keynode: |
48919d246a47
revset: add function to build dict of positional and keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents:
25655
diff
changeset
|
175 raise error.ParseError(_("%(func)s got an invalid argument") |
48919d246a47
revset: add function to build dict of positional and keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents:
25655
diff
changeset
|
176 % {'func': funcname}) |
48919d246a47
revset: add function to build dict of positional and keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents:
25655
diff
changeset
|
177 k = x[1][1] |
31921
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
178 if k in keys: |
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
179 d = args |
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
180 elif not optkey: |
25705
48919d246a47
revset: add function to build dict of positional and keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents:
25655
diff
changeset
|
181 raise error.ParseError(_("%(func)s got an unexpected keyword " |
48919d246a47
revset: add function to build dict of positional and keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents:
25655
diff
changeset
|
182 "argument '%(key)s'") |
48919d246a47
revset: add function to build dict of positional and keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents:
25655
diff
changeset
|
183 % {'func': funcname, 'key': k}) |
31921
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
184 else: |
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
185 d = args[optkey] |
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
186 if k in d: |
25705
48919d246a47
revset: add function to build dict of positional and keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents:
25655
diff
changeset
|
187 raise error.ParseError(_("%(func)s got multiple values for keyword " |
48919d246a47
revset: add function to build dict of positional and keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents:
25655
diff
changeset
|
188 "argument '%(key)s'") |
48919d246a47
revset: add function to build dict of positional and keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents:
25655
diff
changeset
|
189 % {'func': funcname, 'key': k}) |
31921
2156934b7917
parser: extend buildargsdict() to support arbitrary number of **kwargs
Yuya Nishihara <yuya@tcha.org>
parents:
31920
diff
changeset
|
190 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
|
191 return args |
48919d246a47
revset: add function to build dict of positional and keyword arguments
Yuya Nishihara <yuya@tcha.org>
parents:
25655
diff
changeset
|
192 |
26231
87c9c562c37a
parser: move unescape helper from templater
Yuya Nishihara <yuya@tcha.org>
parents:
25963
diff
changeset
|
193 def unescapestr(s): |
87c9c562c37a
parser: move unescape helper from templater
Yuya Nishihara <yuya@tcha.org>
parents:
25963
diff
changeset
|
194 try: |
37084
f0b6fbea00cf
stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36547
diff
changeset
|
195 return stringutil.unescapestr(s) |
26231
87c9c562c37a
parser: move unescape helper from templater
Yuya Nishihara <yuya@tcha.org>
parents:
25963
diff
changeset
|
196 except ValueError as e: |
87c9c562c37a
parser: move unescape helper from templater
Yuya Nishihara <yuya@tcha.org>
parents:
25963
diff
changeset
|
197 # mangle Python's exception into our format |
36547
7840d8bd0558
py3: byte-stringify ValueError of unescapestr() to reraise as ParseError
Yuya Nishihara <yuya@tcha.org>
parents:
34137
diff
changeset
|
198 raise error.ParseError(pycompat.bytestr(e).lower()) |
26231
87c9c562c37a
parser: move unescape helper from templater
Yuya Nishihara <yuya@tcha.org>
parents:
25963
diff
changeset
|
199 |
25254
060bdfef2517
parser: extract closure of prettyformat() to a top-level function
Yuya Nishihara <yuya@tcha.org>
parents:
25253
diff
changeset
|
200 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
|
201 if not isinstance(tree, tuple): |
39050
0a2ce5b43574
parser: replace bespoke _brepr with stringutil.pprint
Augie Fackler <augie@google.com>
parents:
37084
diff
changeset
|
202 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
|
203 elif tree[0] in leafnodes: |
39050
0a2ce5b43574
parser: replace bespoke _brepr with stringutil.pprint
Augie Fackler <augie@google.com>
parents:
37084
diff
changeset
|
204 rs = map(stringutil.pprint, tree[1:]) |
34073
7bbc4e113e5f
parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents:
34045
diff
changeset
|
205 lines.append((level, '(%s %s)' % (tree[0], ' '.join(rs)))) |
25254
060bdfef2517
parser: extract closure of prettyformat() to a top-level function
Yuya Nishihara <yuya@tcha.org>
parents:
25253
diff
changeset
|
206 else: |
060bdfef2517
parser: extract closure of prettyformat() to a top-level function
Yuya Nishihara <yuya@tcha.org>
parents:
25253
diff
changeset
|
207 lines.append((level, '(%s' % tree[0])) |
060bdfef2517
parser: extract closure of prettyformat() to a top-level function
Yuya Nishihara <yuya@tcha.org>
parents:
25253
diff
changeset
|
208 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
|
209 _prettyformat(s, leafnodes, level + 1, lines) |
060bdfef2517
parser: extract closure of prettyformat() to a top-level function
Yuya Nishihara <yuya@tcha.org>
parents:
25253
diff
changeset
|
210 lines[-1:] = [(lines[-1][0], lines[-1][1] + ')')] |
060bdfef2517
parser: extract closure of prettyformat() to a top-level function
Yuya Nishihara <yuya@tcha.org>
parents:
25253
diff
changeset
|
211 |
25253
3f1a9b44b8c2
parser: move prettyformat() function from revset module
Yuya Nishihara <yuya@tcha.org>
parents:
25171
diff
changeset
|
212 def prettyformat(tree, leafnodes): |
3f1a9b44b8c2
parser: move prettyformat() function from revset module
Yuya Nishihara <yuya@tcha.org>
parents:
25171
diff
changeset
|
213 lines = [] |
25254
060bdfef2517
parser: extract closure of prettyformat() to a top-level function
Yuya Nishihara <yuya@tcha.org>
parents:
25253
diff
changeset
|
214 _prettyformat(tree, leafnodes, 0, lines) |
25253
3f1a9b44b8c2
parser: move prettyformat() function from revset module
Yuya Nishihara <yuya@tcha.org>
parents:
25171
diff
changeset
|
215 output = '\n'.join((' ' * l + s) for l, s in lines) |
3f1a9b44b8c2
parser: move prettyformat() function from revset module
Yuya Nishihara <yuya@tcha.org>
parents:
25171
diff
changeset
|
216 return output |
25306
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
217 |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
218 def simplifyinfixops(tree, targetnodes): |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
219 """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
|
220 |
34137
a8994d08e4a2
doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents:
34131
diff
changeset
|
221 >>> from . import pycompat |
25306
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
222 >>> 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
|
223 ... 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
|
224 ... 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
|
225 >>> f((b'or', |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
226 ... (b'or', |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
227 ... (b'symbol', b'1'), |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
228 ... (b'symbol', b'2')), |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
229 ... (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
|
230 (or |
34073
7bbc4e113e5f
parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents:
34045
diff
changeset
|
231 (symbol '1') |
7bbc4e113e5f
parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents:
34045
diff
changeset
|
232 (symbol '2') |
7bbc4e113e5f
parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents:
34045
diff
changeset
|
233 (symbol '3')) |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
234 >>> f((b'func', |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
235 ... (b'symbol', b'p1'), |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
236 ... (b'or', |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
237 ... (b'or', |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
238 ... (b'func', |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
239 ... (b'symbol', b'sort'), |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
240 ... (b'list', |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
241 ... (b'or', |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
242 ... (b'or', |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
243 ... (b'symbol', b'1'), |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
244 ... (b'symbol', b'2')), |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
245 ... (b'symbol', b'3')), |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
246 ... (b'negate', |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
247 ... (b'symbol', b'rev')))), |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
248 ... (b'and', |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
249 ... (b'symbol', b'4'), |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
250 ... (b'group', |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
251 ... (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'5'), |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
254 ... (b'symbol', b'6')), |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
255 ... (b'symbol', b'7'))))), |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
256 ... (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
|
257 (func |
34073
7bbc4e113e5f
parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents:
34045
diff
changeset
|
258 (symbol 'p1') |
25306
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
259 (or |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
260 (func |
34073
7bbc4e113e5f
parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents:
34045
diff
changeset
|
261 (symbol 'sort') |
25306
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
262 (list |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
263 (or |
34073
7bbc4e113e5f
parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents:
34045
diff
changeset
|
264 (symbol '1') |
7bbc4e113e5f
parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents:
34045
diff
changeset
|
265 (symbol '2') |
7bbc4e113e5f
parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents:
34045
diff
changeset
|
266 (symbol '3')) |
25306
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
267 (negate |
34073
7bbc4e113e5f
parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents:
34045
diff
changeset
|
268 (symbol 'rev')))) |
25306
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
269 (and |
34073
7bbc4e113e5f
parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents:
34045
diff
changeset
|
270 (symbol '4') |
25306
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
271 (group |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
272 (or |
34073
7bbc4e113e5f
parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents:
34045
diff
changeset
|
273 (symbol '5') |
7bbc4e113e5f
parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents:
34045
diff
changeset
|
274 (symbol '6') |
7bbc4e113e5f
parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents:
34045
diff
changeset
|
275 (symbol '7')))) |
7bbc4e113e5f
parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents:
34045
diff
changeset
|
276 (symbol '8'))) |
25306
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
277 """ |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
278 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
|
279 return tree |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
280 op = tree[0] |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
281 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
|
282 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
|
283 |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
284 # 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
|
285 # 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
|
286 # 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
|
287 simplified = [] |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
288 x = tree |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
289 while x[0] == op: |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
290 l, r = x[1:] |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
291 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
|
292 x = l |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
293 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
|
294 simplified.append(op) |
c87b05925054
parser: add helper to reduce nesting of chained infix operations
Yuya Nishihara <yuya@tcha.org>
parents:
25254
diff
changeset
|
295 return tuple(reversed(simplified)) |
28720
639e0f1e8ffa
parser: move parsererrordetail() function from revset module
Yuya Nishihara <yuya@tcha.org>
parents:
26231
diff
changeset
|
296 |
34043
90896b61fe26
parser: add helper function that constructs parsed tree from template
Yuya Nishihara <yuya@tcha.org>
parents:
31922
diff
changeset
|
297 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
|
298 if template == placeholder: |
90896b61fe26
parser: add helper function that constructs parsed tree from template
Yuya Nishihara <yuya@tcha.org>
parents:
31922
diff
changeset
|
299 return replstack.pop() |
90896b61fe26
parser: add helper function that constructs parsed tree from template
Yuya Nishihara <yuya@tcha.org>
parents:
31922
diff
changeset
|
300 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
|
301 return template |
90896b61fe26
parser: add helper function that constructs parsed tree from template
Yuya Nishihara <yuya@tcha.org>
parents:
31922
diff
changeset
|
302 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
|
303 |
90896b61fe26
parser: add helper function that constructs parsed tree from template
Yuya Nishihara <yuya@tcha.org>
parents:
31922
diff
changeset
|
304 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
|
305 """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
|
306 |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
307 >>> _ = (b'symbol', b'_') |
34043
90896b61fe26
parser: add helper function that constructs parsed tree from template
Yuya Nishihara <yuya@tcha.org>
parents:
31922
diff
changeset
|
308 >>> def f(template, *repls): |
90896b61fe26
parser: add helper function that constructs parsed tree from template
Yuya Nishihara <yuya@tcha.org>
parents:
31922
diff
changeset
|
309 ... 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
|
310 >>> 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
|
311 ... ('symbol', '1'), ('symbol', '2')) |
90896b61fe26
parser: add helper function that constructs parsed tree from template
Yuya Nishihara <yuya@tcha.org>
parents:
31922
diff
changeset
|
312 ('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
|
313 >>> 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
|
314 ('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
|
315 """ |
90896b61fe26
parser: add helper function that constructs parsed tree from template
Yuya Nishihara <yuya@tcha.org>
parents:
31922
diff
changeset
|
316 if not isinstance(placeholder, tuple): |
90896b61fe26
parser: add helper function that constructs parsed tree from template
Yuya Nishihara <yuya@tcha.org>
parents:
31922
diff
changeset
|
317 raise error.ProgrammingError('placeholder must be a node tuple') |
90896b61fe26
parser: add helper function that constructs parsed tree from template
Yuya Nishihara <yuya@tcha.org>
parents:
31922
diff
changeset
|
318 replstack = list(reversed(repls)) |
90896b61fe26
parser: add helper function that constructs parsed tree from template
Yuya Nishihara <yuya@tcha.org>
parents:
31922
diff
changeset
|
319 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
|
320 if replstack: |
90896b61fe26
parser: add helper function that constructs parsed tree from template
Yuya Nishihara <yuya@tcha.org>
parents:
31922
diff
changeset
|
321 raise error.ProgrammingError('too many replacements') |
90896b61fe26
parser: add helper function that constructs parsed tree from template
Yuya Nishihara <yuya@tcha.org>
parents:
31922
diff
changeset
|
322 return r |
90896b61fe26
parser: add helper function that constructs parsed tree from template
Yuya Nishihara <yuya@tcha.org>
parents:
31922
diff
changeset
|
323 |
34045
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
324 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
|
325 if pattern == tree: |
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
326 return True |
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
327 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
|
328 return False |
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
329 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
|
330 matches.append(tree) |
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
331 return True |
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
332 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
|
333 return False |
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
334 return all(_matchtree(p, x, placeholder, incompletenodes, matches) |
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
335 for p, x in zip(pattern, tree)) |
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
336 |
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
337 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
|
338 """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
|
339 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
|
340 |
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
341 >>> 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
|
342 ... 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
|
343 ... if m: |
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
344 ... return m[1:] |
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
345 |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
346 >>> _ = (b'symbol', b'_') |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
347 >>> 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
|
348 ... (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
|
349 [('symbol', '1')] |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
350 >>> 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
|
351 ... (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
|
352 >>> 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
|
353 ... (b'range', |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
354 ... (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
|
355 ... (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
|
356 [('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
|
357 |
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
358 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
|
359 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
|
360 |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
361 >>> 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
|
362 ... (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
|
363 ... (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
|
364 |
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
365 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
|
366 |
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
367 >>> _ = None |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
368 >>> 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
|
369 ... (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
|
370 """ |
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
371 if placeholder is not None and not isinstance(placeholder, tuple): |
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
372 raise error.ProgrammingError('placeholder must be a node tuple') |
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
373 matches = [tree] |
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
374 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
|
375 return matches |
79681d8ee587
parser: add helper function to test if pattern matches parsed tree
Yuya Nishihara <yuya@tcha.org>
parents:
34043
diff
changeset
|
376 |
28720
639e0f1e8ffa
parser: move parsererrordetail() function from revset module
Yuya Nishihara <yuya@tcha.org>
parents:
26231
diff
changeset
|
377 def parseerrordetail(inst): |
639e0f1e8ffa
parser: move parsererrordetail() function from revset module
Yuya Nishihara <yuya@tcha.org>
parents:
26231
diff
changeset
|
378 """Compose error message from specified ParseError object |
639e0f1e8ffa
parser: move parsererrordetail() function from revset module
Yuya Nishihara <yuya@tcha.org>
parents:
26231
diff
changeset
|
379 """ |
639e0f1e8ffa
parser: move parsererrordetail() function from revset module
Yuya Nishihara <yuya@tcha.org>
parents:
26231
diff
changeset
|
380 if len(inst.args) > 1: |
31353
089e37802fb3
parser: use %d instead of %s for interpolating error position
Augie Fackler <augie@google.com>
parents:
30753
diff
changeset
|
381 return _('at %d: %s') % (inst.args[1], inst.args[0]) |
28720
639e0f1e8ffa
parser: move parsererrordetail() function from revset module
Yuya Nishihara <yuya@tcha.org>
parents:
26231
diff
changeset
|
382 else: |
639e0f1e8ffa
parser: move parsererrordetail() function from revset module
Yuya Nishihara <yuya@tcha.org>
parents:
26231
diff
changeset
|
383 return inst.args[0] |
28870
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
384 |
28892
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
385 class alias(object): |
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
386 """Parsed result of alias""" |
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
387 |
28908
7a772deffa12
parser: drop redundant comparison between alias declaration tree and pattern
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
388 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
|
389 self.name = name |
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
390 self.args = args |
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
391 self.error = err |
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
392 self.replacement = replacement |
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
393 # 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
|
394 # this avoids showing same warning multiple times at each |
8d398155bfda
revset: rename findaliases() to expandaliases()
Yuya Nishihara <yuya@tcha.org>
parents:
28897
diff
changeset
|
395 # `expandaliases`. |
28892
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
396 self.warned = False |
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
397 |
28870
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
398 class basealiasrules(object): |
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
399 """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
|
400 |
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
401 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
|
402 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
|
403 |
30332
318a24b52eeb
spelling: fixes of non-dictionary words
Mads Kiilerich <madski@unity3d.com>
parents:
29767
diff
changeset
|
404 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
|
405 |
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
406 # decl = defn |
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
407 h = heads(default) |
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
408 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
|
409 """ |
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
410 # 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
|
411 _section = None |
28910
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
412 # tag of symbol node |
28870
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
413 _symbolnode = 'symbol' |
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
414 |
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
415 def __new__(cls): |
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
416 raise TypeError("'%s' is not instantiatable" % cls.__name__) |
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
417 |
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
418 @staticmethod |
28875
2e9f5453ab5a
parser: unify parser function of alias declaration and definition
Yuya Nishihara <yuya@tcha.org>
parents:
28873
diff
changeset
|
419 def _parse(spec): |
2e9f5453ab5a
parser: unify parser function of alias declaration and definition
Yuya Nishihara <yuya@tcha.org>
parents:
28873
diff
changeset
|
420 """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
|
421 raise NotImplementedError |
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
422 |
475dad3432fd
parser: add stub class that will host alias parsing and expansion
Yuya Nishihara <yuya@tcha.org>
parents:
28720
diff
changeset
|
423 @staticmethod |
28910
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
424 def _trygetfunc(tree): |
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
425 """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
|
426 raise NotImplementedError |
28871
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
427 |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
428 @classmethod |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
429 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
|
430 """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
|
431 |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
432 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
|
433 by ``_parse()``. |
28871
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
434 |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
435 - ``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
|
436 - ``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
|
437 - ``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
|
438 |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
439 >>> 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
|
440 >>> 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
|
441 >>> 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
|
442 >>> parsemap = { |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
443 ... 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
|
444 ... 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
|
445 ... 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
|
446 ... 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
|
447 ... 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
|
448 ... 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
|
449 ... 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
|
450 ... 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
|
451 ... 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
|
452 ... 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
|
453 ... 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
|
454 ... 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
|
455 ... (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
|
456 ... 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
|
457 ... 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
|
458 ... 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
|
459 ... 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
|
460 ... } |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
461 >>> def parse(expr): |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
462 ... x = parsemap[expr] |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
463 ... if isinstance(x, Exception): |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
464 ... raise x |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
465 ... return x |
28910
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
466 >>> def trygetfunc(tree): |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
467 ... 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
|
468 ... return None |
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
469 ... if not tree[2]: |
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
470 ... 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
|
471 ... 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
|
472 ... 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
|
473 ... 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
|
474 >>> class aliasrules(basealiasrules): |
28875
2e9f5453ab5a
parser: unify parser function of alias declaration and definition
Yuya Nishihara <yuya@tcha.org>
parents:
28873
diff
changeset
|
475 ... _parse = staticmethod(parse) |
28910
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
476 ... _trygetfunc = staticmethod(trygetfunc) |
28871
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
477 >>> builddecl = aliasrules._builddecl |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
478 >>> builddecl(b'foo') |
28908
7a772deffa12
parser: drop redundant comparison between alias declaration tree and pattern
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
479 ('foo', None, None) |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
480 >>> builddecl(b'$foo') |
29058
dbed4c4f48ae
parser: rephrase "'$' not for alias arguments" message
Yuya Nishihara <yuya@tcha.org>
parents:
28910
diff
changeset
|
481 ('$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
|
482 >>> 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
|
483 ('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
|
484 >>> builddecl(b'foo()') |
28908
7a772deffa12
parser: drop redundant comparison between alias declaration tree and pattern
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
485 ('foo', [], None) |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
486 >>> builddecl(b'$foo()') |
29058
dbed4c4f48ae
parser: rephrase "'$' not for alias arguments" message
Yuya Nishihara <yuya@tcha.org>
parents:
28910
diff
changeset
|
487 ('$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
|
488 >>> 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
|
489 ('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
|
490 >>> 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
|
491 ('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
|
492 >>> 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
|
493 ('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
|
494 >>> 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
|
495 ('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
|
496 >>> 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
|
497 ('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
|
498 >>> 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
|
499 ('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
|
500 >>> 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
|
501 ('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
|
502 >>> 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
|
503 ('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
|
504 """ |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
505 try: |
28875
2e9f5453ab5a
parser: unify parser function of alias declaration and definition
Yuya Nishihara <yuya@tcha.org>
parents:
28873
diff
changeset
|
506 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
|
507 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
|
508 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
|
509 |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
510 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
|
511 # "name = ...." style |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
512 name = tree[1] |
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
513 if name.startswith('$'): |
29058
dbed4c4f48ae
parser: rephrase "'$' not for alias arguments" message
Yuya Nishihara <yuya@tcha.org>
parents:
28910
diff
changeset
|
514 return (decl, None, _("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
|
515 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
|
516 |
28910
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
517 func = cls._trygetfunc(tree) |
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
518 if func: |
28871
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
519 # "name(arg, ....) = ...." style |
28910
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
520 name, args = func |
28871
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
521 if name.startswith('$'): |
29058
dbed4c4f48ae
parser: rephrase "'$' not for alias arguments" message
Yuya Nishihara <yuya@tcha.org>
parents:
28910
diff
changeset
|
522 return (decl, None, _("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
|
523 if any(t[0] != cls._symbolnode for t in args): |
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
524 return (decl, None, _("invalid argument list")) |
28871
6d6201fc5aae
parser: move alias declaration parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28870
diff
changeset
|
525 if len(args) != len(set(args)): |
28908
7a772deffa12
parser: drop redundant comparison between alias declaration tree and pattern
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
526 return (name, None, _("argument names collide with each other")) |
28910
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
527 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
|
528 |
28908
7a772deffa12
parser: drop redundant comparison between alias declaration tree and pattern
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
529 return (decl, None, _("invalid format")) |
28872
5f31d2248745
parser: move _relabelaliasargs() to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28871
diff
changeset
|
530 |
5f31d2248745
parser: move _relabelaliasargs() to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28871
diff
changeset
|
531 @classmethod |
5f31d2248745
parser: move _relabelaliasargs() to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28871
diff
changeset
|
532 def _relabelargs(cls, tree, args): |
5f31d2248745
parser: move _relabelaliasargs() to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28871
diff
changeset
|
533 """Mark alias arguments as ``_aliasarg``""" |
5f31d2248745
parser: move _relabelaliasargs() to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28871
diff
changeset
|
534 if not isinstance(tree, tuple): |
5f31d2248745
parser: move _relabelaliasargs() to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28871
diff
changeset
|
535 return tree |
5f31d2248745
parser: move _relabelaliasargs() to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28871
diff
changeset
|
536 op = tree[0] |
5f31d2248745
parser: move _relabelaliasargs() to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28871
diff
changeset
|
537 if op != cls._symbolnode: |
5f31d2248745
parser: move _relabelaliasargs() to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28871
diff
changeset
|
538 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
|
539 |
5f31d2248745
parser: move _relabelaliasargs() to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28871
diff
changeset
|
540 assert len(tree) == 2 |
5f31d2248745
parser: move _relabelaliasargs() to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28871
diff
changeset
|
541 sym = tree[1] |
5f31d2248745
parser: move _relabelaliasargs() to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28871
diff
changeset
|
542 if sym in args: |
5f31d2248745
parser: move _relabelaliasargs() to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28871
diff
changeset
|
543 op = '_aliasarg' |
5f31d2248745
parser: move _relabelaliasargs() to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28871
diff
changeset
|
544 elif sym.startswith('$'): |
29058
dbed4c4f48ae
parser: rephrase "'$' not for alias arguments" message
Yuya Nishihara <yuya@tcha.org>
parents:
28910
diff
changeset
|
545 raise error.ParseError(_("invalid symbol '%s'") % sym) |
28872
5f31d2248745
parser: move _relabelaliasargs() to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28871
diff
changeset
|
546 return (op, sym) |
28873
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
547 |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
548 @classmethod |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
549 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
|
550 """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
|
551 |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
552 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
|
553 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
|
554 |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
555 ``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
|
556 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
|
557 |
34137
a8994d08e4a2
doctest: use print_function and convert bytes to unicode where needed
Yuya Nishihara <yuya@tcha.org>
parents:
34131
diff
changeset
|
558 >>> from . import pycompat |
28873
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
559 >>> parsemap = { |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
560 ... 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
|
561 ... b'$1 or $bar': |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
562 ... (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
|
563 ... b'$10 or baz': |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
564 ... (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
|
565 ... b'"$1" or "foo"': |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
566 ... (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
|
567 ... } |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
568 >>> class aliasrules(basealiasrules): |
28875
2e9f5453ab5a
parser: unify parser function of alias declaration and definition
Yuya Nishihara <yuya@tcha.org>
parents:
28873
diff
changeset
|
569 ... _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
|
570 ... _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
|
571 >>> builddefn = aliasrules._builddefn |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
572 >>> 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
|
573 ... 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
|
574 ... 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
|
575 >>> 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
|
576 >>> 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
|
577 (or |
34073
7bbc4e113e5f
parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents:
34045
diff
changeset
|
578 (_aliasarg '$1') |
7bbc4e113e5f
parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents:
34045
diff
changeset
|
579 (_aliasarg 'foo')) |
28873
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
580 >>> try: |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
581 ... 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
|
582 ... 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
|
583 ... print(pycompat.sysstr(parseerrordetail(inst))) |
29058
dbed4c4f48ae
parser: rephrase "'$' not for alias arguments" message
Yuya Nishihara <yuya@tcha.org>
parents:
28910
diff
changeset
|
584 invalid symbol '$bar' |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
585 >>> 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
|
586 >>> 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
|
587 (or |
34073
7bbc4e113e5f
parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents:
34045
diff
changeset
|
588 (_aliasarg '$10') |
7bbc4e113e5f
parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents:
34045
diff
changeset
|
589 (symbol 'baz')) |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34073
diff
changeset
|
590 >>> 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
|
591 (or |
34073
7bbc4e113e5f
parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents:
34045
diff
changeset
|
592 (string '$1') |
7bbc4e113e5f
parser: stabilize output of prettyformat() by using byte-safe repr()
Yuya Nishihara <yuya@tcha.org>
parents:
34045
diff
changeset
|
593 (string 'foo')) |
28873
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
594 """ |
28875
2e9f5453ab5a
parser: unify parser function of alias declaration and definition
Yuya Nishihara <yuya@tcha.org>
parents:
28873
diff
changeset
|
595 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
|
596 if args: |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
597 args = set(args) |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
598 else: |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
599 args = set() |
2ca3b7c563f3
parser: move alias definition parser to common rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28872
diff
changeset
|
600 return cls._relabelargs(tree, args) |
28892
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
601 |
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
602 @classmethod |
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
603 def build(cls, decl, defn): |
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
604 """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
|
605 repl = efmt = None |
28908
7a772deffa12
parser: drop redundant comparison between alias declaration tree and pattern
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
606 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
|
607 if err: |
29059
8eba4cdcfd81
parser: shorten prefix of alias parsing errors
Yuya Nishihara <yuya@tcha.org>
parents:
29058
diff
changeset
|
608 efmt = _('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
|
609 else: |
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
610 try: |
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
611 repl = cls._builddefn(defn, args) |
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
612 except error.ParseError as inst: |
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
613 err = parseerrordetail(inst) |
29059
8eba4cdcfd81
parser: shorten prefix of alias parsing errors
Yuya Nishihara <yuya@tcha.org>
parents:
29058
diff
changeset
|
614 efmt = _('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
|
615 if err: |
0c135f37c6f8
parser: construct alias object by rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28875
diff
changeset
|
616 err = efmt % {'section': cls._section, 'name': name, 'error': err} |
28908
7a772deffa12
parser: drop redundant comparison between alias declaration tree and pattern
Yuya Nishihara <yuya@tcha.org>
parents:
28898
diff
changeset
|
617 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
|
618 |
ee11167fe1da
parser: extract helper that creates a dict of aliases
Yuya Nishihara <yuya@tcha.org>
parents:
28892
diff
changeset
|
619 @classmethod |
ee11167fe1da
parser: extract helper that creates a dict of aliases
Yuya Nishihara <yuya@tcha.org>
parents:
28892
diff
changeset
|
620 def buildmap(cls, items): |
ee11167fe1da
parser: extract helper that creates a dict of aliases
Yuya Nishihara <yuya@tcha.org>
parents:
28892
diff
changeset
|
621 """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
|
622 alias objects""" |
ee11167fe1da
parser: extract helper that creates a dict of aliases
Yuya Nishihara <yuya@tcha.org>
parents:
28892
diff
changeset
|
623 aliases = {} |
ee11167fe1da
parser: extract helper that creates a dict of aliases
Yuya Nishihara <yuya@tcha.org>
parents:
28892
diff
changeset
|
624 for decl, defn in items: |
ee11167fe1da
parser: extract helper that creates a dict of aliases
Yuya Nishihara <yuya@tcha.org>
parents:
28892
diff
changeset
|
625 a = cls.build(decl, defn) |
ee11167fe1da
parser: extract helper that creates a dict of aliases
Yuya Nishihara <yuya@tcha.org>
parents:
28892
diff
changeset
|
626 aliases[a.name] = a |
ee11167fe1da
parser: extract helper that creates a dict of aliases
Yuya Nishihara <yuya@tcha.org>
parents:
28892
diff
changeset
|
627 return aliases |
28895
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
628 |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
629 @classmethod |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
630 def _getalias(cls, aliases, tree): |
28909
edbffdc7f6a0
parser: make _getalias() return (alias, pattern-args) pair
Yuya Nishihara <yuya@tcha.org>
parents:
28908
diff
changeset
|
631 """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
|
632 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
|
633 """ |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
634 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
|
635 return None |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
636 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
|
637 name = tree[1] |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
638 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
|
639 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
|
640 return a, None |
28910
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
641 func = cls._trygetfunc(tree) |
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
642 if func: |
1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
Yuya Nishihara <yuya@tcha.org>
parents:
28909
diff
changeset
|
643 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
|
644 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
|
645 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
|
646 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
|
647 return None |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
648 |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
649 @classmethod |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
650 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
|
651 """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
|
652 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
|
653 """ |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
654 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
|
655 return tree |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
656 if tree[0] == '_aliasarg': |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
657 sym = tree[1] |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
658 return args[sym] |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
659 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
|
660 |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
661 @classmethod |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
662 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
|
663 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
|
664 return tree |
28909
edbffdc7f6a0
parser: make _getalias() return (alias, pattern-args) pair
Yuya Nishihara <yuya@tcha.org>
parents:
28908
diff
changeset
|
665 r = cls._getalias(aliases, tree) |
edbffdc7f6a0
parser: make _getalias() return (alias, pattern-args) pair
Yuya Nishihara <yuya@tcha.org>
parents:
28908
diff
changeset
|
666 if r is None: |
28896
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
667 return tuple(cls._expand(aliases, t, expanding, cache) |
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
668 for t in tree) |
28909
edbffdc7f6a0
parser: make _getalias() return (alias, pattern-args) pair
Yuya Nishihara <yuya@tcha.org>
parents:
28908
diff
changeset
|
669 a, l = r |
28896
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
670 if a.error: |
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
671 raise error.Abort(a.error) |
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
672 if a in expanding: |
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
673 raise error.ParseError(_('infinite expansion of %(section)s ' |
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
674 '"%(name)s" detected') |
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
675 % {'section': cls._section, 'name': a.name}) |
28897
c1f254138f44
parser: add short comment how aliases are expanded in phases
Yuya Nishihara <yuya@tcha.org>
parents:
28896
diff
changeset
|
676 # 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
|
677 expanding.append(a) |
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
678 if a.name not in cache: |
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
679 cache[a.name] = cls._expand(aliases, a.replacement, expanding, |
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
680 cache) |
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
681 result = cache[a.name] |
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
682 expanding.pop() |
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
683 if a.args is None: |
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
684 return result |
28897
c1f254138f44
parser: add short comment how aliases are expanded in phases
Yuya Nishihara <yuya@tcha.org>
parents:
28896
diff
changeset
|
685 # 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
|
686 if len(l) != len(a.args): |
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
687 raise error.ParseError(_('invalid number of arguments: %d') |
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
688 % len(l)) |
4c76a032ec7e
parser: reorder alias expansion routine to return early
Yuya Nishihara <yuya@tcha.org>
parents:
28895
diff
changeset
|
689 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
|
690 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
|
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 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
|
694 """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
|
695 |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
696 '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
|
697 """ |
4bf9ed7a260e
parser: move functions that process alias expansion to rule-set class
Yuya Nishihara <yuya@tcha.org>
parents:
28893
diff
changeset
|
698 return cls._expand(aliases, tree, [], {}) |