300 pos += 1 |
300 pos += 1 |
301 yield ('end', None, pos) |
301 yield ('end', None, pos) |
302 |
302 |
303 # helpers |
303 # helpers |
304 |
304 |
|
305 def getsymbol(x): |
|
306 if x and x[0] == 'symbol': |
|
307 return x[1] |
|
308 raise error.ParseError(_('not a symbol')) |
|
309 |
305 def getstring(x, err): |
310 def getstring(x, err): |
306 if x and (x[0] == 'string' or x[0] == 'symbol'): |
311 if x and (x[0] == 'string' or x[0] == 'symbol'): |
307 return x[1] |
312 return x[1] |
308 raise error.ParseError(err) |
313 raise error.ParseError(err) |
309 |
314 |
412 |
417 |
413 def keyvaluepair(repo, subset, k, v): |
418 def keyvaluepair(repo, subset, k, v): |
414 raise error.ParseError(_("can't use a key-value pair in this context")) |
419 raise error.ParseError(_("can't use a key-value pair in this context")) |
415 |
420 |
416 def func(repo, subset, a, b): |
421 def func(repo, subset, a, b): |
417 if a[0] == 'symbol' and a[1] in symbols: |
422 f = getsymbol(a) |
418 return symbols[a[1]](repo, subset, b) |
423 if f in symbols: |
|
424 return symbols[f](repo, subset, b) |
419 |
425 |
420 keep = lambda fn: getattr(fn, '__doc__', None) is not None |
426 keep = lambda fn: getattr(fn, '__doc__', None) is not None |
421 |
427 |
422 syms = [s for (s, fn) in symbols.items() if keep(fn)] |
428 syms = [s for (s, fn) in symbols.items() if keep(fn)] |
423 raise error.UnknownIdentifier(a[1], syms) |
429 raise error.UnknownIdentifier(f, syms) |
424 |
430 |
425 # functions |
431 # functions |
426 |
432 |
427 # symbols are callables like: |
433 # symbols are callables like: |
428 # fn(repo, subset, x) |
434 # fn(repo, subset, x) |
2302 >>> f('ancestors(A)', 'not ancestors(B)') |
2308 >>> f('ancestors(A)', 'not ancestors(B)') |
2303 ('list', ('symbol', 'A'), ('symbol', 'B')) |
2309 ('list', ('symbol', 'A'), ('symbol', 'B')) |
2304 """ |
2310 """ |
2305 if (revs is not None |
2311 if (revs is not None |
2306 and revs[0] == 'func' |
2312 and revs[0] == 'func' |
2307 and getstring(revs[1], _('not a symbol')) == 'ancestors' |
2313 and getsymbol(revs[1]) == 'ancestors' |
2308 and bases is not None |
2314 and bases is not None |
2309 and bases[0] == 'not' |
2315 and bases[0] == 'not' |
2310 and bases[1][0] == 'func' |
2316 and bases[1][0] == 'func' |
2311 and getstring(bases[1][1], _('not a symbol')) == 'ancestors'): |
2317 and getsymbol(bases[1][1]) == 'ancestors'): |
2312 return ('list', revs[2], bases[1][2]) |
2318 return ('list', revs[2], bases[1][2]) |
2313 |
2319 |
2314 def _optimize(x, small): |
2320 def _optimize(x, small): |
2315 if x is None: |
2321 if x is None: |
2316 return 0, x |
2322 return 0, x |
2417 return wa + wb, (op, ta, tb) |
2423 return wa + wb, (op, ta, tb) |
2418 elif op == 'list': |
2424 elif op == 'list': |
2419 ws, ts = zip(*(_optimize(y, small) for y in x[1:])) |
2425 ws, ts = zip(*(_optimize(y, small) for y in x[1:])) |
2420 return sum(ws), (op,) + ts |
2426 return sum(ws), (op,) + ts |
2421 elif op == 'func': |
2427 elif op == 'func': |
2422 f = getstring(x[1], _("not a symbol")) |
2428 f = getsymbol(x[1]) |
2423 wa, ta = _optimize(x[2], small) |
2429 wa, ta = _optimize(x[2], small) |
2424 if f in ("author branch closed date desc file grep keyword " |
2430 if f in ("author branch closed date desc file grep keyword " |
2425 "outgoing user"): |
2431 "outgoing user"): |
2426 w = 10 # slow |
2432 w = 10 # slow |
2427 elif f in "modifies adds removes": |
2433 elif f in "modifies adds removes": |