# HG changeset patch # User FUJIWARA Katsunori # Date 1450704676 -32400 # Node ID afa76585c9551e82d5f96469e336a09ed67f8b53 # Parent 11286ac374f3ed8a8d59daf53c9cc5b1082b7987 fileset: use decorator to mark a predicate as "status caller" Before this patch, predicates calling 'matchctx.status()' are listed up by immediate list value in 'getfileset()'. This prevents 3rd party extensions from adding specific predicate calling 'matchctx.status()'. This uses decorator to mark a predicate as "status caller". This can also localize changes for adding (or removing) a "status caller" predicate function in source code. diff -r 11286ac374f3 -r afa76585c955 mercurial/fileset.py --- 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))):