Show More
@@ -239,6 +239,25 b' def getargsdict(x, funcname, keys):' | |||||
239 | return parser.buildargsdict(getlist(x), funcname, parser.splitargspec(keys), |
|
239 | return parser.buildargsdict(getlist(x), funcname, parser.splitargspec(keys), | |
240 | keyvaluenode='keyvalue', keynode='symbol') |
|
240 | keyvaluenode='keyvalue', keynode='symbol') | |
241 |
|
241 | |||
|
242 | # cache of {spec: raw parsed tree} built internally | |||
|
243 | _treecache = {} | |||
|
244 | ||||
|
245 | def _cachedtree(spec): | |||
|
246 | # thread safe because parse() is reentrant and dict.__setitem__() is atomic | |||
|
247 | tree = _treecache.get(spec) | |||
|
248 | if tree is None: | |||
|
249 | _treecache[spec] = tree = parse(spec) | |||
|
250 | return tree | |||
|
251 | ||||
|
252 | def _build(tmplspec, *repls): | |||
|
253 | """Create raw parsed tree from a template revset statement | |||
|
254 | ||||
|
255 | >>> _build('f(_) and _', ('string', '1'), ('symbol', '2')) | |||
|
256 | ('and', ('func', ('symbol', 'f'), ('string', '1')), ('symbol', '2')) | |||
|
257 | """ | |||
|
258 | template = _cachedtree(tmplspec) | |||
|
259 | return parser.buildtree(template, ('symbol', '_'), *repls) | |||
|
260 | ||||
242 | def _isnamedfunc(x, funcname): |
|
261 | def _isnamedfunc(x, funcname): | |
243 | """Check if given tree matches named function""" |
|
262 | """Check if given tree matches named function""" | |
244 | return x and x[0] == 'func' and getsymbol(x[1]) == funcname |
|
263 | return x and x[0] == 'func' and getsymbol(x[1]) == funcname | |
@@ -302,16 +321,15 b' def _analyze(x):' | |||||
302 |
|
321 | |||
303 | op = x[0] |
|
322 | op = x[0] | |
304 | if op == 'minus': |
|
323 | if op == 'minus': | |
305 |
return _analyze(('and', x[1 |
|
324 | return _analyze(_build('_ and not _', *x[1:])) | |
306 | elif op == 'only': |
|
325 | elif op == 'only': | |
307 | t = ('func', ('symbol', 'only'), ('list', x[1], x[2])) |
|
326 | return _analyze(_build('only(_, _)', *x[1:])) | |
308 | return _analyze(t) |
|
|||
309 | elif op == 'onlypost': |
|
327 | elif op == 'onlypost': | |
310 |
return _analyze((' |
|
328 | return _analyze(_build('only(_)', x[1])) | |
311 | elif op == 'dagrangepre': |
|
329 | elif op == 'dagrangepre': | |
312 |
return _analyze((' |
|
330 | return _analyze(_build('ancestors(_)', x[1])) | |
313 | elif op == 'dagrangepost': |
|
331 | elif op == 'dagrangepost': | |
314 |
return _analyze((' |
|
332 | return _analyze(_build('descendants(_)', x[1])) | |
315 | elif op == 'negate': |
|
333 | elif op == 'negate': | |
316 | s = getstring(x[1], _("can't negate that")) |
|
334 | s = getstring(x[1], _("can't negate that")) | |
317 | return _analyze(('string', '-' + s)) |
|
335 | return _analyze(('string', '-' + s)) | |
@@ -367,9 +385,9 b' def _optimize(x, small):' | |||||
367 | w = min(wa, wb) |
|
385 | w = min(wa, wb) | |
368 |
|
386 | |||
369 | # (::x and not ::y)/(not ::y and ::x) have a fast path |
|
387 | # (::x and not ::y)/(not ::y and ::x) have a fast path | |
370 |
|
|
388 | m = _matchonly(ta, tb) or _matchonly(tb, ta) | |
371 |
if |
|
389 | if m: | |
372 |
return w, (' |
|
390 | return w, _build('only(_, _)', *m[1:]) | |
373 |
|
391 | |||
374 | if tb is not None and tb[0] == 'not': |
|
392 | if tb is not None and tb[0] == 'not': | |
375 | return wa, ('difference', ta, tb[1]) |
|
393 | return wa, ('difference', ta, tb[1]) | |
@@ -387,7 +405,7 b' def _optimize(x, small):' | |||||
387 | w, t = ss[0] |
|
405 | w, t = ss[0] | |
388 | else: |
|
406 | else: | |
389 | s = '\0'.join(t[1] for w, t in ss) |
|
407 | s = '\0'.join(t[1] for w, t in ss) | |
390 |
y = (' |
|
408 | y = _build('_list(_)', ('string', s)) | |
391 | w, t = _optimize(y, False) |
|
409 | w, t = _optimize(y, False) | |
392 | ws.append(w) |
|
410 | ws.append(w) | |
393 | ts.append(t) |
|
411 | ts.append(t) | |
@@ -407,8 +425,7 b' def _optimize(x, small):' | |||||
407 | elif op == 'not': |
|
425 | elif op == 'not': | |
408 | # Optimize not public() to _notpublic() because we have a fast version |
|
426 | # Optimize not public() to _notpublic() because we have a fast version | |
409 | if x[1][:3] == ('func', ('symbol', 'public'), None): |
|
427 | if x[1][:3] == ('func', ('symbol', 'public'), None): | |
410 | newsym = ('func', ('symbol', '_notpublic'), None) |
|
428 | o = _optimize(_build('_notpublic()'), not small) | |
411 | o = _optimize(newsym, not small) |
|
|||
412 | return o[0], o[1] |
|
429 | return o[0], o[1] | |
413 | else: |
|
430 | else: | |
414 | o = _optimize(x[1], not small) |
|
431 | o = _optimize(x[1], not small) |
General Comments 0
You need to be logged in to leave comments.
Login now