Show More
@@ -239,6 +239,25 b' def getargsdict(x, funcname, keys):' | |||
|
239 | 239 | return parser.buildargsdict(getlist(x), funcname, parser.splitargspec(keys), |
|
240 | 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 | 261 | def _isnamedfunc(x, funcname): |
|
243 | 262 | """Check if given tree matches named function""" |
|
244 | 263 | return x and x[0] == 'func' and getsymbol(x[1]) == funcname |
@@ -302,16 +321,15 b' def _analyze(x):' | |||
|
302 | 321 | |
|
303 | 322 | op = x[0] |
|
304 | 323 | if op == 'minus': |
|
305 |
return _analyze(('and', x[1 |
|
|
324 | return _analyze(_build('_ and not _', *x[1:])) | |
|
306 | 325 | elif op == 'only': |
|
307 | t = ('func', ('symbol', 'only'), ('list', x[1], x[2])) | |
|
308 | return _analyze(t) | |
|
326 | return _analyze(_build('only(_, _)', *x[1:])) | |
|
309 | 327 | elif op == 'onlypost': |
|
310 |
return _analyze((' |
|
|
328 | return _analyze(_build('only(_)', x[1])) | |
|
311 | 329 | elif op == 'dagrangepre': |
|
312 |
return _analyze((' |
|
|
330 | return _analyze(_build('ancestors(_)', x[1])) | |
|
313 | 331 | elif op == 'dagrangepost': |
|
314 |
return _analyze((' |
|
|
332 | return _analyze(_build('descendants(_)', x[1])) | |
|
315 | 333 | elif op == 'negate': |
|
316 | 334 | s = getstring(x[1], _("can't negate that")) |
|
317 | 335 | return _analyze(('string', '-' + s)) |
@@ -367,9 +385,9 b' def _optimize(x, small):' | |||
|
367 | 385 | w = min(wa, wb) |
|
368 | 386 | |
|
369 | 387 | # (::x and not ::y)/(not ::y and ::x) have a fast path |
|
370 |
|
|
|
371 |
if |
|
|
372 |
return w, (' |
|
|
388 | m = _matchonly(ta, tb) or _matchonly(tb, ta) | |
|
389 | if m: | |
|
390 | return w, _build('only(_, _)', *m[1:]) | |
|
373 | 391 | |
|
374 | 392 | if tb is not None and tb[0] == 'not': |
|
375 | 393 | return wa, ('difference', ta, tb[1]) |
@@ -387,7 +405,7 b' def _optimize(x, small):' | |||
|
387 | 405 | w, t = ss[0] |
|
388 | 406 | else: |
|
389 | 407 | s = '\0'.join(t[1] for w, t in ss) |
|
390 |
y = (' |
|
|
408 | y = _build('_list(_)', ('string', s)) | |
|
391 | 409 | w, t = _optimize(y, False) |
|
392 | 410 | ws.append(w) |
|
393 | 411 | ts.append(t) |
@@ -407,8 +425,7 b' def _optimize(x, small):' | |||
|
407 | 425 | elif op == 'not': |
|
408 | 426 | # Optimize not public() to _notpublic() because we have a fast version |
|
409 | 427 | if x[1][:3] == ('func', ('symbol', 'public'), None): |
|
410 | newsym = ('func', ('symbol', '_notpublic'), None) | |
|
411 | o = _optimize(newsym, not small) | |
|
428 | o = _optimize(_build('_notpublic()'), not small) | |
|
412 | 429 | return o[0], o[1] |
|
413 | 430 | else: |
|
414 | 431 | o = _optimize(x[1], not small) |
General Comments 0
You need to be logged in to leave comments.
Login now