mercurial/fileset.py
changeset 38880 80fd7371f2d8
parent 38879 e79a69af1593
child 38881 dec16c0cce50
--- a/mercurial/fileset.py	Sat Jul 21 20:27:53 2018 +0900
+++ b/mercurial/fileset.py	Sun Jul 22 11:20:48 2018 +0900
@@ -44,7 +44,8 @@
     return methods[x[0]](mctx, *x[1:])
 
 def getmatchwithstatus(mctx, x, hint):
-    return getmatch(mctx, x)
+    keys = set(getstring(hint, 'status hint must be a string').split())
+    return getmatch(mctx.withstatus(keys), x)
 
 def stringmatch(mctx, x):
     return mctx.matcher([x])
@@ -98,9 +99,6 @@
 #  x - argument in tree form
 symbols = filesetlang.symbols
 
-# filesets using matchctx.status()
-_statuscallers = set()
-
 predicate = registrar.filesetpredicate()
 
 @predicate('modified()', callstatus=True, weight=_WEIGHT_STATUS)
@@ -390,7 +388,6 @@
     for r in revs:
         ctx = repo[r]
         mc = mctx.switch(ctx.p1(), ctx)
-        mc.buildstatus(x)
         matchers.append(getmatch(mc, x))
     if not matchers:
         return mctx.never()
@@ -419,7 +416,6 @@
         raise error.ParseError(reverr)
     basectx, ctx = scmutil.revpair(repo, [baserevspec, revspec])
     mc = mctx.switch(basectx, ctx)
-    mc.buildstatus(x)
     return getmatch(mc, x)
 
 @predicate('subrepo([pattern])')
@@ -466,15 +462,17 @@
         self._badfn = badfn
         self._status = None
 
-    def buildstatus(self, tree):
-        if not _intree(_statuscallers, tree):
-            return
-        unknown = _intree(['unknown'], tree)
-        ignored = _intree(['ignored'], tree)
+    def withstatus(self, keys):
+        """Create matchctx which has precomputed status specified by the keys"""
+        mctx = matchctx(self._basectx, self.ctx, self._badfn)
+        mctx._buildstatus(keys)
+        return mctx
+
+    def _buildstatus(self, keys):
         self._status = self._basectx.status(self.ctx,
-                                            listignored=ignored,
+                                            listignored='ignored' in keys,
                                             listclean=True,
-                                            listunknown=unknown)
+                                            listunknown='unknown' in keys)
 
     def status(self):
         return self._status
@@ -533,32 +531,12 @@
     def switch(self, basectx, ctx):
         return matchctx(basectx, ctx, self._badfn)
 
-# filesets using matchctx.switch()
-_switchcallers = [
-    'revs',
-    'status',
-]
-
-def _intree(funcs, tree):
-    if isinstance(tree, tuple):
-        if tree[0] == 'func' and tree[1][0] == 'symbol':
-            if tree[1][1] in funcs:
-                return True
-            if tree[1][1] in _switchcallers:
-                # arguments won't be evaluated in the current context
-                return False
-        for s in tree[1:]:
-            if _intree(funcs, s):
-                return True
-    return False
-
 def match(ctx, expr, badfn=None):
     """Create a matcher for a single fileset expression"""
     tree = filesetlang.parse(expr)
     tree = filesetlang.analyze(tree)
     tree = filesetlang.optimize(tree)
     mctx = matchctx(ctx.p1(), ctx, badfn=badfn)
-    mctx.buildstatus(tree)
     return getmatch(mctx, tree)
 
 
@@ -567,10 +545,8 @@
     """
     for name, func in registrarobj._table.iteritems():
         symbols[name] = func
-        if func._callstatus:
-            _statuscallers.add(name)
 
-# load built-in predicates explicitly to setup _statuscallers
+# load built-in predicates explicitly
 loadpredicate(None, None, predicate)
 
 # tell hggettext to extract docstrings from these functions: