changeset 38804:d82c4d42b615

fileset: flatten 'or' nodes to unnest unionmatchers This also makes it easier to compile a union of basic patterns into a single regexp pattern.
author Yuya Nishihara <yuya@tcha.org>
date Sat, 21 Jul 2018 15:23:56 +0900
parents 4dc498d61d86
children b9162ea1b815
files mercurial/fileset.py mercurial/minifileset.py tests/test-fileset.t
diffstat 3 files changed, 10 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- 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>>]>