mercurial/revset.py
changeset 29930 90455e7bf543
parent 29929 b3845cab4ddc
child 29931 d2d1be3009ca
equal deleted inserted replaced
29929:b3845cab4ddc 29930:90455e7bf543
  2308     "ancestor": ancestorspec,
  2308     "ancestor": ancestorspec,
  2309     "parent": parentspec,
  2309     "parent": parentspec,
  2310     "parentpost": p1,
  2310     "parentpost": p1,
  2311 }
  2311 }
  2312 
  2312 
       
  2313 # Constants for ordering requirement, used in _analyze():
       
  2314 #
       
  2315 # If 'define', any nested functions and operations can change the ordering of
       
  2316 # the entries in the set. If 'follow', any nested functions and operations
       
  2317 # should take the ordering specified by the first operand to the '&' operator.
       
  2318 #
       
  2319 # For instance,
       
  2320 #
       
  2321 #   X & (Y | Z)
       
  2322 #   ^   ^^^^^^^
       
  2323 #   |   follow
       
  2324 #   define
       
  2325 #
       
  2326 # will be evaluated as 'or(y(x()), z(x()))', where 'x()' can change the order
       
  2327 # of the entries in the set, but 'y()', 'z()' and 'or()' shouldn't.
       
  2328 #
       
  2329 # 'any' means the order doesn't matter. For instance,
       
  2330 #
       
  2331 #   X & !Y
       
  2332 #        ^
       
  2333 #        any
       
  2334 #
       
  2335 # 'y()' can either enforce its ordering requirement or take the ordering
       
  2336 # specified by 'x()' because 'not()' doesn't care the order.
       
  2337 #
       
  2338 # Transition of ordering requirement:
       
  2339 #
       
  2340 # 1. starts with 'define'
       
  2341 # 2. shifts to 'follow' by 'x & y'
       
  2342 # 3. changes back to 'define' on function call 'f(x)' or function-like
       
  2343 #    operation 'x (f) y' because 'f' may have its own ordering requirement
       
  2344 #    for 'x' and 'y' (e.g. 'first(x)')
       
  2345 #
       
  2346 anyorder = 'any'        # don't care the order
       
  2347 defineorder = 'define'  # should define the order
       
  2348 followorder = 'follow'  # must follow the current order
       
  2349 
       
  2350 # transition table for 'x & y', from the current expression 'x' to 'y'
       
  2351 _tofolloworder = {
       
  2352     anyorder: anyorder,
       
  2353     defineorder: followorder,
       
  2354     followorder: followorder,
       
  2355 }
       
  2356 
  2313 def _matchonly(revs, bases):
  2357 def _matchonly(revs, bases):
  2314     """
  2358     """
  2315     >>> f = lambda *args: _matchonly(*map(parse, args))
  2359     >>> f = lambda *args: _matchonly(*map(parse, args))
  2316     >>> f('ancestors(A)', 'not ancestors(B)')
  2360     >>> f('ancestors(A)', 'not ancestors(B)')
  2317     ('list', ('symbol', 'A'), ('symbol', 'B'))
  2361     ('list', ('symbol', 'A'), ('symbol', 'B'))
  2347         # x + y + z -> (or x y z) -> (or (list x y z))
  2391         # x + y + z -> (or x y z) -> (or (list x y z))
  2348         return (op, _fixops(('list',) + x[1:]))
  2392         return (op, _fixops(('list',) + x[1:]))
  2349 
  2393 
  2350     return (op,) + tuple(_fixops(y) for y in x[1:])
  2394     return (op,) + tuple(_fixops(y) for y in x[1:])
  2351 
  2395 
  2352 def _analyze(x):
  2396 def _analyze(x, order):
  2353     if x is None:
  2397     if x is None:
  2354         return x
  2398         return x
  2355 
  2399 
  2356     op = x[0]
  2400     op = x[0]
  2357     if op == 'minus':
  2401     if op == 'minus':
  2358         return _analyze(('and', x[1], ('not', x[2])))
  2402         return _analyze(('and', x[1], ('not', x[2])), order)
  2359     elif op == 'only':
  2403     elif op == 'only':
  2360         t = ('func', ('symbol', 'only'), ('list', x[1], x[2]))
  2404         t = ('func', ('symbol', 'only'), ('list', x[1], x[2]))
  2361         return _analyze(t)
  2405         return _analyze(t, order)
  2362     elif op == 'onlypost':
  2406     elif op == 'onlypost':
  2363         return _analyze(('func', ('symbol', 'only'), x[1]))
  2407         return _analyze(('func', ('symbol', 'only'), x[1]), order)
  2364     elif op == 'dagrangepre':
  2408     elif op == 'dagrangepre':
  2365         return _analyze(('func', ('symbol', 'ancestors'), x[1]))
  2409         return _analyze(('func', ('symbol', 'ancestors'), x[1]), order)
  2366     elif op == 'dagrangepost':
  2410     elif op == 'dagrangepost':
  2367         return _analyze(('func', ('symbol', 'descendants'), x[1]))
  2411         return _analyze(('func', ('symbol', 'descendants'), x[1]), order)
  2368     elif op == 'rangeall':
  2412     elif op == 'rangeall':
  2369         return _analyze(('range', ('string', '0'), ('string', 'tip')))
  2413         return _analyze(('range', ('string', '0'), ('string', 'tip')), order)
  2370     elif op == 'rangepre':
  2414     elif op == 'rangepre':
  2371         return _analyze(('range', ('string', '0'), x[1]))
  2415         return _analyze(('range', ('string', '0'), x[1]), order)
  2372     elif op == 'rangepost':
  2416     elif op == 'rangepost':
  2373         return _analyze(('range', x[1], ('string', 'tip')))
  2417         return _analyze(('range', x[1], ('string', 'tip')), order)
  2374     elif op == 'negate':
  2418     elif op == 'negate':
  2375         s = getstring(x[1], _("can't negate that"))
  2419         s = getstring(x[1], _("can't negate that"))
  2376         return _analyze(('string', '-' + s))
  2420         return _analyze(('string', '-' + s), order)
  2377     elif op in ('string', 'symbol'):
  2421     elif op in ('string', 'symbol'):
  2378         return x
  2422         return x
  2379     elif op == 'and':
  2423     elif op == 'and':
  2380         ta = _analyze(x[1])
  2424         ta = _analyze(x[1], order)
  2381         tb = _analyze(x[2])
  2425         tb = _analyze(x[2], _tofolloworder[order])
  2382         return (op, ta, tb)
  2426         return (op, ta, tb)
  2383     elif op == 'or':
  2427     elif op == 'or':
  2384         return (op, _analyze(x[1]))
  2428         return (op, _analyze(x[1], order))
  2385     elif op == 'not':
  2429     elif op == 'not':
  2386         return (op, _analyze(x[1]))
  2430         return (op, _analyze(x[1], anyorder))
  2387     elif op == 'parentpost':
  2431     elif op == 'parentpost':
  2388         return (op, _analyze(x[1]))
  2432         return (op, _analyze(x[1], defineorder))
  2389     elif op == 'group':
  2433     elif op == 'group':
  2390         return _analyze(x[1])
  2434         return _analyze(x[1], order)
  2391     elif op in ('dagrange', 'range', 'parent', 'ancestor'):
  2435     elif op in ('dagrange', 'range', 'parent', 'ancestor'):
  2392         ta = _analyze(x[1])
  2436         ta = _analyze(x[1], defineorder)
  2393         tb = _analyze(x[2])
  2437         tb = _analyze(x[2], defineorder)
  2394         return (op, ta, tb)
  2438         return (op, ta, tb)
  2395     elif op == 'list':
  2439     elif op == 'list':
  2396         return (op,) + tuple(_analyze(y) for y in x[1:])
  2440         return (op,) + tuple(_analyze(y, order) for y in x[1:])
  2397     elif op == 'keyvalue':
  2441     elif op == 'keyvalue':
  2398         return (op, x[1], _analyze(x[2]))
  2442         return (op, x[1], _analyze(x[2], order))
  2399     elif op == 'func':
  2443     elif op == 'func':
  2400         return (op, x[1], _analyze(x[2]))
  2444         return (op, x[1], _analyze(x[2], defineorder))
  2401     raise ValueError('invalid operator %r' % op)
  2445     raise ValueError('invalid operator %r' % op)
  2402 
  2446 
  2403 def analyze(x):
  2447 def analyze(x, order=defineorder):
  2404     """Transform raw parsed tree to evaluatable tree which can be fed to
  2448     """Transform raw parsed tree to evaluatable tree which can be fed to
  2405     optimize() or getset()
  2449     optimize() or getset()
  2406 
  2450 
  2407     All pseudo operations should be mapped to real operations or functions
  2451     All pseudo operations should be mapped to real operations or functions
  2408     defined in methods or symbols table respectively.
  2452     defined in methods or symbols table respectively.
  2409     """
  2453 
  2410     return _analyze(x)
  2454     'order' specifies how the current expression 'x' is ordered (see the
       
  2455     constants defined above.)
       
  2456     """
       
  2457     return _analyze(x, order)
  2411 
  2458 
  2412 def _optimize(x, small):
  2459 def _optimize(x, small):
  2413     if x is None:
  2460     if x is None:
  2414         return 0, x
  2461         return 0, x
  2415 
  2462