fileset: flatten 'or' nodes to unnest unionmatchers
This also makes it easier to compile a union of basic patterns into a single
regexp pattern.
--- a/mercurial/fileset.py Sat Jul 21 15:14:38 2018 +0900
+++ b/mercurial/fileset.py Sat Jul 21 15:23:56 2018 +0900
@@ -103,7 +103,7 @@
tree, pos = p.parse(tokenize(expr))
if pos != len(expr):
raise error.ParseError(_("invalid token"), pos)
- return parser.simplifyinfixops(tree, {'list'})
+ return parser.simplifyinfixops(tree, {'list', 'or'})
def getsymbol(x):
if x and x[0] == 'symbol':
@@ -157,10 +157,9 @@
ym = getmatch(mctx, y)
return matchmod.intersectmatchers(xm, ym)
-def ormatch(mctx, x, y):
- xm = getmatch(mctx, x)
- ym = getmatch(mctx, y)
- return matchmod.unionmatcher([xm, ym])
+def ormatch(mctx, *xs):
+ ms = [getmatch(mctx, x) for x in xs]
+ return matchmod.unionmatcher(ms)
def notmatch(mctx, x):
m = getmatch(mctx, x)
--- a/mercurial/minifileset.py Sat Jul 21 15:14:38 2018 +0900
+++ b/mercurial/minifileset.py Sat Jul 21 15:23:56 2018 +0900
@@ -40,9 +40,8 @@
raise error.ParseError(_("unsupported file pattern: %s") % name,
hint=_('paths must be prefixed with "path:"'))
elif op == 'or':
- func1 = _compile(tree[1])
- func2 = _compile(tree[2])
- return lambda n, s: func1(n, s) or func2(n, s)
+ funcs = [_compile(x) for x in tree[1:]]
+ return lambda n, s: any(f(n, s) for f in funcs)
elif op == 'and':
func1 = _compile(tree[1])
func2 = _compile(tree[2])
--- a/tests/test-fileset.t Sat Jul 21 15:14:38 2018 +0900
+++ b/tests/test-fileset.t Sat Jul 21 15:23:56 2018 +0900
@@ -159,9 +159,8 @@
$ fileset -p all -s 'a1 or a2 or (grep("b") & clean())'
* parsed:
(or
- (or
- (symbol 'a1')
- (symbol 'a2'))
+ (symbol 'a1')
+ (symbol 'a2')
(group
(and
(func
@@ -172,9 +171,8 @@
None))))
* matcher:
<unionmatcher matchers=[
- <unionmatcher matchers=[
- <patternmatcher patterns='(?:a1$)'>,
- <patternmatcher patterns='(?:a2$)'>]>,
+ <patternmatcher patterns='(?:a1$)'>,
+ <patternmatcher patterns='(?:a2$)'>,
<intersectionmatcher
m1=<predicatenmatcher pred=grep('b')>,
m2=<predicatenmatcher pred=clean>>]>