Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/filesetlang.py @ 43076:2372284d9457
formatting: blacken the codebase
This is using my patch to black
(https://github.com/psf/black/pull/826) so we don't un-wrap collection
literals.
Done with:
hg files 'set:**.py - mercurial/thirdparty/** - "contrib/python-zstandard/**"' | xargs black -S
# skip-blame mass-reformatting only
# no-check-commit reformats foo_bar functions
Differential Revision: https://phab.mercurial-scm.org/D6971
author | Augie Fackler <augie@google.com> |
---|---|
date | Sun, 06 Oct 2019 09:45:02 -0400 |
parents | e79a69af1593 |
children | 687b865b95ad |
comparison
equal
deleted
inserted
replaced
43075:57875cf423c9 | 43076:2372284d9457 |
---|---|
44 | 44 |
45 symbols = {} | 45 symbols = {} |
46 | 46 |
47 globchars = ".*{}[]?/\\_" | 47 globchars = ".*{}[]?/\\_" |
48 | 48 |
49 | |
49 def tokenize(program): | 50 def tokenize(program): |
50 pos, l = 0, len(program) | 51 pos, l = 0, len(program) |
51 program = pycompat.bytestr(program) | 52 program = pycompat.bytestr(program) |
52 while pos < l: | 53 while pos < l: |
53 c = program[pos] | 54 c = program[pos] |
54 if c.isspace(): # skip inter-token whitespace | 55 if c.isspace(): # skip inter-token whitespace |
55 pass | 56 pass |
56 elif c in "(),-:|&+!": # handle simple operators | 57 elif c in "(),-:|&+!": # handle simple operators |
57 yield (c, None, pos) | 58 yield (c, None, pos) |
58 elif (c in '"\'' or c == 'r' and | 59 elif ( |
59 program[pos:pos + 2] in ("r'", 'r"')): # handle quoted strings | 60 c in '"\'' or c == 'r' and program[pos : pos + 2] in ("r'", 'r"') |
61 ): # handle quoted strings | |
60 if c == 'r': | 62 if c == 'r': |
61 pos += 1 | 63 pos += 1 |
62 c = program[pos] | 64 c = program[pos] |
63 decode = lambda x: x | 65 decode = lambda x: x |
64 else: | 66 else: |
65 decode = parser.unescapestr | 67 decode = parser.unescapestr |
66 pos += 1 | 68 pos += 1 |
67 s = pos | 69 s = pos |
68 while pos < l: # find closing quote | 70 while pos < l: # find closing quote |
69 d = program[pos] | 71 d = program[pos] |
70 if d == '\\': # skip over escaped characters | 72 if d == '\\': # skip over escaped characters |
71 pos += 2 | 73 pos += 2 |
72 continue | 74 continue |
73 if d == c: | 75 if d == c: |
74 yield ('string', decode(program[s:pos]), s) | 76 yield ('string', decode(program[s:pos]), s) |
75 break | 77 break |
78 raise error.ParseError(_("unterminated string"), s) | 80 raise error.ParseError(_("unterminated string"), s) |
79 elif c.isalnum() or c in globchars or ord(c) > 127: | 81 elif c.isalnum() or c in globchars or ord(c) > 127: |
80 # gather up a symbol/keyword | 82 # gather up a symbol/keyword |
81 s = pos | 83 s = pos |
82 pos += 1 | 84 pos += 1 |
83 while pos < l: # find end of symbol | 85 while pos < l: # find end of symbol |
84 d = program[pos] | 86 d = program[pos] |
85 if not (d.isalnum() or d in globchars or ord(d) > 127): | 87 if not (d.isalnum() or d in globchars or ord(d) > 127): |
86 break | 88 break |
87 pos += 1 | 89 pos += 1 |
88 sym = program[s:pos] | 90 sym = program[s:pos] |
89 if sym in keywords: # operator keywords | 91 if sym in keywords: # operator keywords |
90 yield (sym, None, s) | 92 yield (sym, None, s) |
91 else: | 93 else: |
92 yield ('symbol', sym, s) | 94 yield ('symbol', sym, s) |
93 pos -= 1 | 95 pos -= 1 |
94 else: | 96 else: |
95 raise error.ParseError(_("syntax error"), pos) | 97 raise error.ParseError(_("syntax error"), pos) |
96 pos += 1 | 98 pos += 1 |
97 yield ('end', None, pos) | 99 yield ('end', None, pos) |
98 | 100 |
101 | |
99 def parse(expr): | 102 def parse(expr): |
100 p = parser.parser(elements) | 103 p = parser.parser(elements) |
101 tree, pos = p.parse(tokenize(expr)) | 104 tree, pos = p.parse(tokenize(expr)) |
102 if pos != len(expr): | 105 if pos != len(expr): |
103 raise error.ParseError(_("invalid token"), pos) | 106 raise error.ParseError(_("invalid token"), pos) |
104 return parser.simplifyinfixops(tree, {'list', 'or'}) | 107 return parser.simplifyinfixops(tree, {'list', 'or'}) |
105 | 108 |
109 | |
106 def getsymbol(x): | 110 def getsymbol(x): |
107 if x and x[0] == 'symbol': | 111 if x and x[0] == 'symbol': |
108 return x[1] | 112 return x[1] |
109 raise error.ParseError(_('not a symbol')) | 113 raise error.ParseError(_('not a symbol')) |
110 | 114 |
115 | |
111 def getstring(x, err): | 116 def getstring(x, err): |
112 if x and (x[0] == 'string' or x[0] == 'symbol'): | 117 if x and (x[0] == 'string' or x[0] == 'symbol'): |
113 return x[1] | 118 return x[1] |
114 raise error.ParseError(err) | 119 raise error.ParseError(err) |
120 | |
115 | 121 |
116 def getkindpat(x, y, allkinds, err): | 122 def getkindpat(x, y, allkinds, err): |
117 kind = getsymbol(x) | 123 kind = getsymbol(x) |
118 pat = getstring(y, err) | 124 pat = getstring(y, err) |
119 if kind not in allkinds: | 125 if kind not in allkinds: |
120 raise error.ParseError(_("invalid pattern kind: %s") % kind) | 126 raise error.ParseError(_("invalid pattern kind: %s") % kind) |
121 return '%s:%s' % (kind, pat) | 127 return '%s:%s' % (kind, pat) |
122 | 128 |
129 | |
123 def getpattern(x, allkinds, err): | 130 def getpattern(x, allkinds, err): |
124 if x and x[0] == 'kindpat': | 131 if x and x[0] == 'kindpat': |
125 return getkindpat(x[1], x[2], allkinds, err) | 132 return getkindpat(x[1], x[2], allkinds, err) |
126 return getstring(x, err) | 133 return getstring(x, err) |
134 | |
127 | 135 |
128 def getlist(x): | 136 def getlist(x): |
129 if not x: | 137 if not x: |
130 return [] | 138 return [] |
131 if x[0] == 'list': | 139 if x[0] == 'list': |
132 return list(x[1:]) | 140 return list(x[1:]) |
133 return [x] | 141 return [x] |
134 | 142 |
143 | |
135 def getargs(x, min, max, err): | 144 def getargs(x, min, max, err): |
136 l = getlist(x) | 145 l = getlist(x) |
137 if len(l) < min or len(l) > max: | 146 if len(l) < min or len(l) > max: |
138 raise error.ParseError(err) | 147 raise error.ParseError(err) |
139 return l | 148 return l |
149 | |
140 | 150 |
141 def _analyze(x): | 151 def _analyze(x): |
142 if x is None: | 152 if x is None: |
143 return x | 153 return x |
144 | 154 |
168 if op == 'func': | 178 if op == 'func': |
169 getsymbol(x[1]) # function name must be a symbol | 179 getsymbol(x[1]) # function name must be a symbol |
170 ta = _analyze(x[2]) | 180 ta = _analyze(x[2]) |
171 return (op, x[1], ta) | 181 return (op, x[1], ta) |
172 raise error.ProgrammingError('invalid operator %r' % op) | 182 raise error.ProgrammingError('invalid operator %r' % op) |
183 | |
173 | 184 |
174 def _insertstatushints(x): | 185 def _insertstatushints(x): |
175 """Insert hint nodes where status should be calculated (first path) | 186 """Insert hint nodes where status should be calculated (first path) |
176 | 187 |
177 This works in bottom-up way, summing up status names and inserting hint | 188 This works in bottom-up way, summing up status names and inserting hint |
212 if getattr(symbols.get(f), '_callstatus', False): | 223 if getattr(symbols.get(f), '_callstatus', False): |
213 return (f,), ('withstatus', (op, x[1], ta), ('string', f)) | 224 return (f,), ('withstatus', (op, x[1], ta), ('string', f)) |
214 return (), (op, x[1], ta) | 225 return (), (op, x[1], ta) |
215 raise error.ProgrammingError('invalid operator %r' % op) | 226 raise error.ProgrammingError('invalid operator %r' % op) |
216 | 227 |
228 | |
217 def _mergestatushints(x, instatus): | 229 def _mergestatushints(x, instatus): |
218 """Remove redundant status hint nodes (second path) | 230 """Remove redundant status hint nodes (second path) |
219 | 231 |
220 This is the top-down path to eliminate inner hint nodes. | 232 This is the top-down path to eliminate inner hint nodes. |
221 """ | 233 """ |
245 # don't propagate 'instatus' crossing a function boundary | 257 # don't propagate 'instatus' crossing a function boundary |
246 ta = _mergestatushints(x[2], instatus=False) | 258 ta = _mergestatushints(x[2], instatus=False) |
247 return (op, x[1], ta) | 259 return (op, x[1], ta) |
248 raise error.ProgrammingError('invalid operator %r' % op) | 260 raise error.ProgrammingError('invalid operator %r' % op) |
249 | 261 |
262 | |
250 def analyze(x): | 263 def analyze(x): |
251 """Transform raw parsed tree to evaluatable tree which can be fed to | 264 """Transform raw parsed tree to evaluatable tree which can be fed to |
252 optimize() or getmatch() | 265 optimize() or getmatch() |
253 | 266 |
254 All pseudo operations should be mapped to real operations or functions | 267 All pseudo operations should be mapped to real operations or functions |
256 """ | 269 """ |
257 t = _analyze(x) | 270 t = _analyze(x) |
258 _h, t = _insertstatushints(t) | 271 _h, t = _insertstatushints(t) |
259 return _mergestatushints(t, instatus=False) | 272 return _mergestatushints(t, instatus=False) |
260 | 273 |
274 | |
261 def _optimizeandops(op, ta, tb): | 275 def _optimizeandops(op, ta, tb): |
262 if tb is not None and tb[0] == 'not': | 276 if tb is not None and tb[0] == 'not': |
263 return ('minus', ta, tb[1]) | 277 return ('minus', ta, tb[1]) |
264 return (op, ta, tb) | 278 return (op, ta, tb) |
279 | |
265 | 280 |
266 def _optimizeunion(xs): | 281 def _optimizeunion(xs): |
267 # collect string patterns so they can be compiled into a single regexp | 282 # collect string patterns so they can be compiled into a single regexp |
268 ws, ts, ss = [], [], [] | 283 ws, ts, ss = [], [], [] |
269 for x in xs: | 284 for x in xs: |
275 ts.append(t) | 290 ts.append(t) |
276 if ss: | 291 if ss: |
277 ws.append(WEIGHT_CHECK_FILENAME) | 292 ws.append(WEIGHT_CHECK_FILENAME) |
278 ts.append(('patterns',) + tuple(ss)) | 293 ts.append(('patterns',) + tuple(ss)) |
279 return ws, ts | 294 return ws, ts |
295 | |
280 | 296 |
281 def _optimize(x): | 297 def _optimize(x): |
282 if x is None: | 298 if x is None: |
283 return 0, x | 299 return 0, x |
284 | 300 |
302 else: | 318 else: |
303 return wb, _optimizeandops(op, tb, ta) | 319 return wb, _optimizeandops(op, tb, ta) |
304 if op == 'or': | 320 if op == 'or': |
305 ws, ts = _optimizeunion(x[1:]) | 321 ws, ts = _optimizeunion(x[1:]) |
306 if len(ts) == 1: | 322 if len(ts) == 1: |
307 return ws[0], ts[0] # 'or' operation is fully optimized out | 323 return ws[0], ts[0] # 'or' operation is fully optimized out |
308 ts = tuple(it[1] for it in sorted(enumerate(ts), | 324 ts = tuple( |
309 key=lambda it: ws[it[0]])) | 325 it[1] for it in sorted(enumerate(ts), key=lambda it: ws[it[0]]) |
326 ) | |
310 return max(ws), (op,) + ts | 327 return max(ws), (op,) + ts |
311 if op == 'list': | 328 if op == 'list': |
312 ws, ts = zip(*(_optimize(y) for y in x[1:])) | 329 ws, ts = zip(*(_optimize(y) for y in x[1:])) |
313 return sum(ws), (op,) + ts | 330 return sum(ws), (op,) + ts |
314 if op == 'func': | 331 if op == 'func': |
316 w = getattr(symbols.get(f), '_weight', 1) | 333 w = getattr(symbols.get(f), '_weight', 1) |
317 wa, ta = _optimize(x[2]) | 334 wa, ta = _optimize(x[2]) |
318 return w + wa, (op, x[1], ta) | 335 return w + wa, (op, x[1], ta) |
319 raise error.ProgrammingError('invalid operator %r' % op) | 336 raise error.ProgrammingError('invalid operator %r' % op) |
320 | 337 |
338 | |
321 def optimize(x): | 339 def optimize(x): |
322 """Reorder/rewrite evaluatable tree for optimization | 340 """Reorder/rewrite evaluatable tree for optimization |
323 | 341 |
324 All pseudo operations should be transformed beforehand. | 342 All pseudo operations should be transformed beforehand. |
325 """ | 343 """ |
326 _w, t = _optimize(x) | 344 _w, t = _optimize(x) |
327 return t | 345 return t |
328 | 346 |
347 | |
329 def prettyformat(tree): | 348 def prettyformat(tree): |
330 return parser.prettyformat(tree, ('string', 'symbol')) | 349 return parser.prettyformat(tree, ('string', 'symbol')) |