[PATCH 1 of 7] fileset: add phase to transform parsed tree
Yuya Nishihara
yuya at tcha.org
Fri Aug 3 15:01:38 UTC 2018
# HG changeset patch
# User Yuya Nishihara <yuya at tcha.org>
# Date 1532157096 -32400
# Sat Jul 21 16:11:36 2018 +0900
# Node ID 78c669de8c435c0594ab4f849f591aacad074097
# Parent d814bbd229467f7e5d866fd3af41df8beb131b9a
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 --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py
--- a/mercurial/debugcommands.py
+++ b/mercurial/debugcommands.py
@@ -901,6 +901,7 @@ def debugfileset(ui, repo, expr, **opts)
stages = [
('parsed', pycompat.identity),
+ ('analyzed', filesetlang.analyze),
]
stagenames = set(n for n, f in stages)
diff --git a/mercurial/fileset.py b/mercurial/fileset.py
--- a/mercurial/fileset.py
+++ b/mercurial/fileset.py
@@ -528,6 +528,7 @@ def _intree(funcs, tree):
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 --git a/mercurial/filesetlang.py b/mercurial/filesetlang.py
--- a/mercurial/filesetlang.py
+++ b/mercurial/filesetlang.py
@@ -131,5 +131,41 @@ def getargs(x, min, max, err):
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 --git a/mercurial/minifileset.py b/mercurial/minifileset.py
--- a/mercurial/minifileset.py
+++ b/mercurial/minifileset.py
@@ -89,4 +89,5 @@ def compile(text):
root except for "bin/README".
"""
tree = filesetlang.parse(text)
+ tree = filesetlang.analyze(tree)
return _compile(tree)
diff --git a/tests/test-fileset.t b/tests/test-fileset.t
--- a/tests/test-fileset.t
+++ b/tests/test-fileset.t
@@ -169,6 +169,18 @@ Show parsed tree at stages:
(func
(symbol 'clean')
None))))
+ * analyzed:
+ (or
+ (symbol 'a1')
+ (symbol 'a2')
+ (group
+ (and
+ (func
+ (symbol 'grep')
+ (string 'b'))
+ (func
+ (symbol 'clean')
+ None))))
* matcher:
<unionmatcher matchers=[
<patternmatcher patterns='(?:a1$)'>,
More information about the Mercurial-devel
mailing list