Patchwork [6,of,7] match: compose 'set:' pattern as matcher

login
register
mail settings
Submitter Yuya Nishihara
Date July 5, 2018, 2:14 p.m.
Message ID <e3fd1b0063733cf1f860.1530800071@mimosa>
Download mbox | patch
Permalink /patch/32646/
State New
Headers show

Comments

Yuya Nishihara - July 5, 2018, 2:14 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1528614538 -32400
#      Sun Jun 10 16:08:58 2018 +0900
# Node ID e3fd1b0063733cf1f86053493d3632174197d384
# Parent  c81f8e935af38b19a2004fb507bcf74783b0db06
match: compose 'set:' pattern as matcher

Baby step towards porting fileset to matcher composition.

We can't use the exactmatcher since it would provide a computed set as exact
paths. That's why we use the predicatematcher with fset.__contains__. This
will be cleaned up later.

The test change in test-glog.t means that the "set:copied()" pattern is no
longer be processed as a slow path. That's because the fset is empty. This
will also change in future patches.

Patch

diff --git a/mercurial/match.py b/mercurial/match.py
--- a/mercurial/match.py
+++ b/mercurial/match.py
@@ -95,6 +95,24 @@  def _kindpatsalwaysmatch(kindpats):
             return False
     return True
 
+def _buildkindpatsmatcher(matchercls, root, cwd, kindpats, ctx=None,
+                          listsubrepos=False, badfn=None):
+    fset, kindpats = _expandsets(kindpats, ctx, listsubrepos)
+    matchers = []
+    if kindpats:
+        m = matchercls(root, cwd, kindpats, ctx=ctx, listsubrepos=listsubrepos,
+                       badfn=badfn)
+        matchers.append(m)
+    if fset:
+        m = predicatematcher(root, cwd, fset.__contains__,
+                             predrepr='fileset', badfn=badfn)
+        matchers.append(m)
+    if not matchers:
+        return nevermatcher(root, cwd, badfn=badfn)
+    if len(matchers) == 1:
+        return matchers[0]
+    return unionmatcher(matchers)
+
 def match(root, cwd, patterns=None, include=None, exclude=None, default='glob',
           exact=False, auditor=None, ctx=None, listsubrepos=False, warn=None,
           badfn=None, icasefs=False):
@@ -159,8 +177,9 @@  def match(root, cwd, patterns=None, incl
         if _kindpatsalwaysmatch(kindpats):
             m = alwaysmatcher(root, cwd, badfn, relativeuipath=True)
         else:
-            m = patternmatcher(root, cwd, kindpats, ctx=ctx,
-                               listsubrepos=listsubrepos, badfn=badfn)
+            m = _buildkindpatsmatcher(patternmatcher, root, cwd, kindpats,
+                                      ctx=ctx, listsubrepos=listsubrepos,
+                                      badfn=badfn)
     else:
         # It's a little strange that no patterns means to match everything.
         # Consider changing this to match nothing (probably using nevermatcher).
@@ -168,13 +187,13 @@  def match(root, cwd, patterns=None, incl
 
     if include:
         kindpats = normalize(include, 'glob', root, cwd, auditor, warn)
-        im = includematcher(root, cwd, kindpats, ctx=ctx,
-                            listsubrepos=listsubrepos, badfn=None)
+        im = _buildkindpatsmatcher(includematcher, root, cwd, kindpats, ctx=ctx,
+                                   listsubrepos=listsubrepos, badfn=None)
         m = intersectmatchers(m, im)
     if exclude:
         kindpats = normalize(exclude, 'glob', root, cwd, auditor, warn)
-        em = includematcher(root, cwd, kindpats, ctx=ctx,
-                            listsubrepos=listsubrepos, badfn=None)
+        em = _buildkindpatsmatcher(includematcher, root, cwd, kindpats, ctx=ctx,
+                                   listsubrepos=listsubrepos, badfn=None)
         m = differencematcher(m, em)
     return m
 
@@ -828,10 +847,6 @@  def _buildmatch(ctx, kindpats, globsuffi
     globsuffix is appended to the regexp of globs.'''
     matchfuncs = []
 
-    fset, kindpats = _expandsets(kindpats, ctx, listsubrepos)
-    if fset:
-        matchfuncs.append(fset.__contains__)
-
     subincludes, kindpats = _expandsubinclude(kindpats, root)
     if subincludes:
         submatchers = {}
diff --git a/tests/test-glog-beautifygraph.t b/tests/test-glog-beautifygraph.t
--- a/tests/test-glog-beautifygraph.t
+++ b/tests/test-glog-beautifygraph.t
@@ -2023,25 +2023,14 @@  Test "set:..." and parent revision
   $ testlog "set:copied()"
   []
   (func
-    (symbol '_matchfiles')
-    (list
-      (string 'r:')
-      (string 'd:relpath')
-      (string 'p:set:copied()')))
+    (symbol 'filelog')
+    (string 'set:copied()'))
   <filteredset
-    <spanset- 0:7>,
-    <matchfiles patterns=['set:copied()'], include=[] exclude=[], default='relpath', rev=2147483647>>
+    <spanset- 0:7>, set([])>
   $ testlog --include "set:copied()"
   []
-  (func
-    (symbol '_matchfiles')
-    (list
-      (string 'r:')
-      (string 'd:relpath')
-      (string 'i:set:copied()')))
-  <filteredset
-    <spanset- 0:7>,
-    <matchfiles patterns=[], include=['set:copied()'] exclude=[], default='relpath', rev=2147483647>>
+  []
+  <spanset- 0:7>
   $ testlog -r "sort(file('set:copied()'), -rev)"
   ["sort(file('set:copied()'), -rev)"]
   []
diff --git a/tests/test-glog.t b/tests/test-glog.t
--- a/tests/test-glog.t
+++ b/tests/test-glog.t
@@ -1870,25 +1870,14 @@  Test "set:..." and parent revision
   $ testlog "set:copied()"
   []
   (func
-    (symbol '_matchfiles')
-    (list
-      (string 'r:')
-      (string 'd:relpath')
-      (string 'p:set:copied()')))
+    (symbol 'filelog')
+    (string 'set:copied()'))
   <filteredset
-    <spanset- 0:7>,
-    <matchfiles patterns=['set:copied()'], include=[] exclude=[], default='relpath', rev=2147483647>>
+    <spanset- 0:7>, set([])>
   $ testlog --include "set:copied()"
   []
-  (func
-    (symbol '_matchfiles')
-    (list
-      (string 'r:')
-      (string 'd:relpath')
-      (string 'i:set:copied()')))
-  <filteredset
-    <spanset- 0:7>,
-    <matchfiles patterns=[], include=['set:copied()'] exclude=[], default='relpath', rev=2147483647>>
+  []
+  <spanset- 0:7>
   $ testlog -r "sort(file('set:copied()'), -rev)"
   ["sort(file('set:copied()'), -rev)"]
   []