395 return getset(repo, getset(repo, subset, x), y) |
395 return getset(repo, getset(repo, subset, x), y) |
396 |
396 |
397 def differenceset(repo, subset, x, y): |
397 def differenceset(repo, subset, x, y): |
398 return getset(repo, subset, x) - getset(repo, subset, y) |
398 return getset(repo, subset, x) - getset(repo, subset, y) |
399 |
399 |
400 def orset(repo, subset, *xs): |
400 def _orsetlist(repo, subset, xs): |
401 assert xs |
401 assert xs |
402 if len(xs) == 1: |
402 if len(xs) == 1: |
403 return getset(repo, subset, xs[0]) |
403 return getset(repo, subset, xs[0]) |
404 p = len(xs) // 2 |
404 p = len(xs) // 2 |
405 a = orset(repo, subset, *xs[:p]) |
405 a = _orsetlist(repo, subset, xs[:p]) |
406 b = orset(repo, subset, *xs[p:]) |
406 b = _orsetlist(repo, subset, xs[p:]) |
407 return a + b |
407 return a + b |
|
408 |
|
409 def orset(repo, subset, x): |
|
410 return _orsetlist(repo, subset, getlist(x)) |
408 |
411 |
409 def notset(repo, subset, x): |
412 def notset(repo, subset, x): |
410 return subset - getset(repo, subset, x) |
413 return subset - getset(repo, subset, x) |
411 |
414 |
412 def listset(repo, subset, *xs): |
415 def listset(repo, subset, *xs): |
2337 return _fixops(('dagrange', post, x[2][1])) |
2340 return _fixops(('dagrange', post, x[2][1])) |
2338 elif x[2][0] == 'rangepre': |
2341 elif x[2][0] == 'rangepre': |
2339 return _fixops(('range', post, x[2][1])) |
2342 return _fixops(('range', post, x[2][1])) |
2340 elif x[2][0] == 'rangeall': |
2343 elif x[2][0] == 'rangeall': |
2341 return _fixops(('rangepost', post)) |
2344 return _fixops(('rangepost', post)) |
|
2345 elif op == 'or': |
|
2346 # make number of arguments deterministic: |
|
2347 # x + y + z -> (or x y z) -> (or (list x y z)) |
|
2348 return (op, _fixops(('list',) + x[1:])) |
2342 |
2349 |
2343 return (op,) + tuple(_fixops(y) for y in x[1:]) |
2350 return (op,) + tuple(_fixops(y) for y in x[1:]) |
2344 |
2351 |
2345 def _analyze(x): |
2352 def _analyze(x): |
2346 if x is None: |
2353 if x is None: |
2372 elif op == 'and': |
2379 elif op == 'and': |
2373 ta = _analyze(x[1]) |
2380 ta = _analyze(x[1]) |
2374 tb = _analyze(x[2]) |
2381 tb = _analyze(x[2]) |
2375 return (op, ta, tb) |
2382 return (op, ta, tb) |
2376 elif op == 'or': |
2383 elif op == 'or': |
2377 return (op,) + tuple(_analyze(y) for y in x[1:]) |
2384 return (op, _analyze(x[1])) |
2378 elif op == 'not': |
2385 elif op == 'not': |
2379 return (op, _analyze(x[1])) |
2386 return (op, _analyze(x[1])) |
2380 elif op == 'parentpost': |
2387 elif op == 'parentpost': |
2381 return (op, _analyze(x[1])) |
2388 return (op, _analyze(x[1])) |
2382 elif op == 'group': |
2389 elif op == 'group': |
2443 y = ('func', ('symbol', '_list'), ('string', s)) |
2450 y = ('func', ('symbol', '_list'), ('string', s)) |
2444 w, t = _optimize(y, False) |
2451 w, t = _optimize(y, False) |
2445 ws.append(w) |
2452 ws.append(w) |
2446 ts.append(t) |
2453 ts.append(t) |
2447 del ss[:] |
2454 del ss[:] |
2448 for y in x[1:]: |
2455 for y in getlist(x[1]): |
2449 w, t = _optimize(y, False) |
2456 w, t = _optimize(y, False) |
2450 if t is not None and (t[0] == 'string' or t[0] == 'symbol'): |
2457 if t is not None and (t[0] == 'string' or t[0] == 'symbol'): |
2451 ss.append((w, t)) |
2458 ss.append((w, t)) |
2452 continue |
2459 continue |
2453 flushss() |
2460 flushss() |
2457 if len(ts) == 1: |
2464 if len(ts) == 1: |
2458 return ws[0], ts[0] # 'or' operation is fully optimized out |
2465 return ws[0], ts[0] # 'or' operation is fully optimized out |
2459 # we can't reorder trees by weight because it would change the order. |
2466 # we can't reorder trees by weight because it would change the order. |
2460 # ("sort(a + b)" == "sort(b + a)", but "a + b" != "b + a") |
2467 # ("sort(a + b)" == "sort(b + a)", but "a + b" != "b + a") |
2461 # ts = tuple(t for w, t in sorted(zip(ws, ts), key=lambda wt: wt[0])) |
2468 # ts = tuple(t for w, t in sorted(zip(ws, ts), key=lambda wt: wt[0])) |
2462 return max(ws), (op,) + tuple(ts) |
2469 return max(ws), (op, ('list',) + tuple(ts)) |
2463 elif op == 'not': |
2470 elif op == 'not': |
2464 # Optimize not public() to _notpublic() because we have a fast version |
2471 # Optimize not public() to _notpublic() because we have a fast version |
2465 if x[1] == ('func', ('symbol', 'public'), None): |
2472 if x[1] == ('func', ('symbol', 'public'), None): |
2466 newsym = ('func', ('symbol', '_notpublic'), None) |
2473 newsym = ('func', ('symbol', '_notpublic'), None) |
2467 o = _optimize(newsym, not small) |
2474 o = _optimize(newsym, not small) |
2611 if repo: |
2618 if repo: |
2612 lookup = repo.__contains__ |
2619 lookup = repo.__contains__ |
2613 if len(specs) == 1: |
2620 if len(specs) == 1: |
2614 tree = parse(specs[0], lookup) |
2621 tree = parse(specs[0], lookup) |
2615 else: |
2622 else: |
2616 tree = ('or',) + tuple(parse(s, lookup) for s in specs) |
2623 tree = ('or', ('list',) + tuple(parse(s, lookup) for s in specs)) |
2617 |
2624 |
2618 if ui: |
2625 if ui: |
2619 tree = expandaliases(ui, tree) |
2626 tree = expandaliases(ui, tree) |
2620 tree = foldconcat(tree) |
2627 tree = foldconcat(tree) |
2621 tree = analyze(tree) |
2628 tree = analyze(tree) |