mercurial/fileset.py
changeset 27461 afa76585c955
parent 27460 11286ac374f3
child 27462 470ea34ba593
--- a/mercurial/fileset.py	Mon Dec 21 22:31:16 2015 +0900
+++ b/mercurial/fileset.py	Mon Dec 21 22:31:16 2015 +0900
@@ -137,11 +137,17 @@
 #  x - argument in tree form
 symbols = {}
 
-def predicate(decl):
+# filesets using matchctx.status()
+_statuscallers = []
+
+def predicate(decl, callstatus=False):
     """Return a decorator for fileset predicate function
 
     'decl' argument is the declaration (including argument list like
     'adds(pattern)') or the name (for internal use only) of predicate.
+
+    Optional 'callstatus' argument indicates whether predicate implies
+    'matchctx.status()' at runtime or not (False, by default).
     """
     def decorator(func):
         i = decl.find('(')
@@ -150,12 +156,14 @@
         else:
             name = decl
         symbols[name] = func
+        if callstatus:
+            _statuscallers.append(name)
         if func.__doc__:
             func.__doc__ = "``%s``\n    %s" % (decl, func.__doc__.strip())
         return func
     return decorator
 
-@predicate('modified()')
+@predicate('modified()', callstatus=True)
 def modified(mctx, x):
     """File that is modified according to :hg:`status`.
     """
@@ -164,7 +172,7 @@
     s = mctx.status().modified
     return [f for f in mctx.subset if f in s]
 
-@predicate('added()')
+@predicate('added()', callstatus=True)
 def added(mctx, x):
     """File that is added according to :hg:`status`.
     """
@@ -173,7 +181,7 @@
     s = mctx.status().added
     return [f for f in mctx.subset if f in s]
 
-@predicate('removed()')
+@predicate('removed()', callstatus=True)
 def removed(mctx, x):
     """File that is removed according to :hg:`status`.
     """
@@ -182,7 +190,7 @@
     s = mctx.status().removed
     return [f for f in mctx.subset if f in s]
 
-@predicate('deleted()')
+@predicate('deleted()', callstatus=True)
 def deleted(mctx, x):
     """Alias for ``missing()``.
     """
@@ -191,7 +199,7 @@
     s = mctx.status().deleted
     return [f for f in mctx.subset if f in s]
 
-@predicate('missing()')
+@predicate('missing()', callstatus=True)
 def missing(mctx, x):
     """File that is missing according to :hg:`status`.
     """
@@ -200,7 +208,7 @@
     s = mctx.status().deleted
     return [f for f in mctx.subset if f in s]
 
-@predicate('unknown()')
+@predicate('unknown()', callstatus=True)
 def unknown(mctx, x):
     """File that is unknown according to :hg:`status`. These files will only be
     considered if this predicate is used.
@@ -210,7 +218,7 @@
     s = mctx.status().unknown
     return [f for f in mctx.subset if f in s]
 
-@predicate('ignored()')
+@predicate('ignored()', callstatus=True)
 def ignored(mctx, x):
     """File that is ignored according to :hg:`status`. These files will only be
     considered if this predicate is used.
@@ -220,7 +228,7 @@
     s = mctx.status().ignored
     return [f for f in mctx.subset if f in s]
 
-@predicate('clean()')
+@predicate('clean()', callstatus=True)
 def clean(mctx, x):
     """File that is clean according to :hg:`status`.
     """
@@ -523,8 +531,7 @@
     tree = parse(expr)
 
     # do we need status info?
-    if (_intree(['modified', 'added', 'removed', 'deleted',
-                 'missing', 'unknown', 'ignored', 'clean'], tree) or
+    if (_intree(_statuscallers, tree) or
         # Using matchctx.existing() on a workingctx requires us to check
         # for deleted files.
         (ctx.rev() is None and _intree(_existingcallers, tree))):