mercurial/revset.py
changeset 23742 3a4d8a6ce432
parent 23729 07a6faf939dc
child 23765 537a2669a113
equal deleted inserted replaced
23741:f2893cd8d1e5 23742:3a4d8a6ce432
   100             if parent in reachable:
   100             if parent in reachable:
   101                 reachable.add(rev)
   101                 reachable.add(rev)
   102     return baseset(sorted(reachable))
   102     return baseset(sorted(reachable))
   103 
   103 
   104 elements = {
   104 elements = {
   105     "(": (20, ("group", 1, ")"), ("func", 1, ")")),
   105     "(": (21, ("group", 1, ")"), ("func", 1, ")")),
       
   106     "##": (20, None, ("_concat", 20)),
   106     "~": (18, None, ("ancestor", 18)),
   107     "~": (18, None, ("ancestor", 18)),
   107     "^": (18, None, ("parent", 18), ("parentpost", 18)),
   108     "^": (18, None, ("parent", 18), ("parentpost", 18)),
   108     "-": (5, ("negate", 19), ("minus", 5)),
   109     "-": (5, ("negate", 19), ("minus", 5)),
   109     "::": (17, ("dagrangepre", 17), ("dagrange", 17),
   110     "::": (17, ("dagrangepre", 17), ("dagrange", 17),
   110            ("dagrangepost", 17)),
   111            ("dagrangepost", 17)),
   145         elif c == ':' and program[pos:pos + 2] == '::': # look ahead carefully
   146         elif c == ':' and program[pos:pos + 2] == '::': # look ahead carefully
   146             yield ('::', None, pos)
   147             yield ('::', None, pos)
   147             pos += 1 # skip ahead
   148             pos += 1 # skip ahead
   148         elif c == '.' and program[pos:pos + 2] == '..': # look ahead carefully
   149         elif c == '.' and program[pos:pos + 2] == '..': # look ahead carefully
   149             yield ('..', None, pos)
   150             yield ('..', None, pos)
       
   151             pos += 1 # skip ahead
       
   152         elif c == '#' and program[pos:pos + 2] == '##': # look ahead carefully
       
   153             yield ('##', None, pos)
   150             pos += 1 # skip ahead
   154             pos += 1 # skip ahead
   151         elif c in "():,-|&+!~^": # handle simple operators
   155         elif c in "():,-|&+!~^": # handle simple operators
   152             yield (c, None, pos)
   156             yield (c, None, pos)
   153         elif (c in '"\'' or c == 'r' and
   157         elif (c in '"\'' or c == 'r' and
   154               program[pos:pos + 2] in ("r'", 'r"')): # handle quoted strings
   158               program[pos:pos + 2] in ("r'", 'r"')): # handle quoted strings
  2154                         ) % (name, alias.error)
  2158                         ) % (name, alias.error)
  2155                 showwarning(_('warning: %s\n') % (msg))
  2159                 showwarning(_('warning: %s\n') % (msg))
  2156                 alias.warned = True
  2160                 alias.warned = True
  2157     return tree
  2161     return tree
  2158 
  2162 
       
  2163 def foldconcat(tree):
       
  2164     """Fold elements to be concatenated by `##`
       
  2165     """
       
  2166     if not isinstance(tree, tuple) or tree[0] in ('string', 'symbol'):
       
  2167         return tree
       
  2168     if tree[0] == '_concat':
       
  2169         pending = [tree]
       
  2170         l = []
       
  2171         while pending:
       
  2172             e = pending.pop()
       
  2173             if e[0] == '_concat':
       
  2174                 pending.extend(reversed(e[1:]))
       
  2175             elif e[0] in ('string', 'symbol'):
       
  2176                 l.append(e[1])
       
  2177             else:
       
  2178                 msg = _("\"##\" can't concatenate \"%s\" element") % (e[0])
       
  2179                 raise error.ParseError(msg)
       
  2180         return ('string', ''.join(l))
       
  2181     else:
       
  2182         return tuple(foldconcat(t) for t in tree)
       
  2183 
  2159 def parse(spec, lookup=None):
  2184 def parse(spec, lookup=None):
  2160     p = parser.parser(tokenize, elements)
  2185     p = parser.parser(tokenize, elements)
  2161     return p.parse(spec, lookup=lookup)
  2186     return p.parse(spec, lookup=lookup)
  2162 
  2187 
  2163 def match(ui, spec, repo=None):
  2188 def match(ui, spec, repo=None):
  2169     tree, pos = parse(spec, lookup)
  2194     tree, pos = parse(spec, lookup)
  2170     if (pos != len(spec)):
  2195     if (pos != len(spec)):
  2171         raise error.ParseError(_("invalid token"), pos)
  2196         raise error.ParseError(_("invalid token"), pos)
  2172     if ui:
  2197     if ui:
  2173         tree = findaliases(ui, tree, showwarning=ui.warn)
  2198         tree = findaliases(ui, tree, showwarning=ui.warn)
       
  2199     tree = foldconcat(tree)
  2174     weight, tree = optimize(tree, True)
  2200     weight, tree = optimize(tree, True)
  2175     def mfunc(repo, subset):
  2201     def mfunc(repo, subset):
  2176         if util.safehasattr(subset, 'isascending'):
  2202         if util.safehasattr(subset, 'isascending'):
  2177             result = getset(repo, subset, tree)
  2203             result = getset(repo, subset, tree)
  2178         else:
  2204         else: