# HG changeset patch # User Yuya Nishihara # Date 1532157096 -32400 # Node ID 6371ab78c3b374821f3bef156fe2defe5a1c7946 # Parent 8a9f6076e60cc10f87f79c2075114769b55726a3 fileset: add phase to transform parsed tree This isn't strictly necessary, but I decided to just follow the strategy of the revset parsing. diff -r 8a9f6076e60c -r 6371ab78c3b3 mercurial/debugcommands.py --- a/mercurial/debugcommands.py Fri Aug 03 11:40:15 2018 -0400 +++ b/mercurial/debugcommands.py Sat Jul 21 16:11:36 2018 +0900 @@ -901,6 +901,7 @@ stages = [ ('parsed', pycompat.identity), + ('analyzed', filesetlang.analyze), ] stagenames = set(n for n, f in stages) diff -r 8a9f6076e60c -r 6371ab78c3b3 mercurial/fileset.py --- a/mercurial/fileset.py Fri Aug 03 11:40:15 2018 -0400 +++ b/mercurial/fileset.py Sat Jul 21 16:11:36 2018 +0900 @@ -528,6 +528,7 @@ def match(ctx, expr, badfn=None): """Create a matcher for a single fileset expression""" tree = filesetlang.parse(expr) + tree = filesetlang.analyze(tree) mctx = matchctx(ctx, _buildstatus(ctx, tree), badfn=badfn) return getmatch(mctx, tree) diff -r 8a9f6076e60c -r 6371ab78c3b3 mercurial/filesetlang.py --- a/mercurial/filesetlang.py Fri Aug 03 11:40:15 2018 -0400 +++ b/mercurial/filesetlang.py Sat Jul 21 16:11:36 2018 +0900 @@ -131,5 +131,41 @@ raise error.ParseError(err) return l +def _analyze(x): + if x is None: + return x + + op = x[0] + if op in {'string', 'symbol'}: + return x + if op == 'kindpat': + getsymbol(x[1]) # kind must be a symbol + t = _analyze(x[2]) + return (op, x[1], t) + if op in {'group', 'not', 'negate'}: + t = _analyze(x[1]) + return (op, t) + if op in {'and', 'minus'}: + ta = _analyze(x[1]) + tb = _analyze(x[2]) + return (op, ta, tb) + if op in {'list', 'or'}: + ts = tuple(_analyze(y) for y in x[1:]) + return (op,) + ts + if op == 'func': + getsymbol(x[1]) # function name must be a symbol + ta = _analyze(x[2]) + return (op, x[1], ta) + raise error.ProgrammingError('invalid operator %r' % op) + +def analyze(x): + """Transform raw parsed tree to evaluatable tree which can be fed to + getmatch() + + All pseudo operations should be mapped to real operations or functions + defined in methods or symbols table respectively. + """ + return _analyze(x) + def prettyformat(tree): return parser.prettyformat(tree, ('string', 'symbol')) diff -r 8a9f6076e60c -r 6371ab78c3b3 mercurial/minifileset.py --- a/mercurial/minifileset.py Fri Aug 03 11:40:15 2018 -0400 +++ b/mercurial/minifileset.py Sat Jul 21 16:11:36 2018 +0900 @@ -89,4 +89,5 @@ root except for "bin/README". """ tree = filesetlang.parse(text) + tree = filesetlang.analyze(tree) return _compile(tree) diff -r 8a9f6076e60c -r 6371ab78c3b3 tests/test-fileset.t --- a/tests/test-fileset.t Fri Aug 03 11:40:15 2018 -0400 +++ b/tests/test-fileset.t Sat Jul 21 16:11:36 2018 +0900 @@ -169,6 +169,18 @@ (func (symbol 'clean') None)))) + * analyzed: + (or + (symbol 'a1') + (symbol 'a2') + (group + (and + (func + (symbol 'grep') + (string 'b')) + (func + (symbol 'clean') + None)))) * matcher: ,