[PATCH 5 of 7 V3 RFC] parser: move alias definition parser to common rule-set class

Yuya Nishihara yuya at tcha.org
Sun Apr 3 05:48:19 EDT 2016


# HG changeset patch
# User Yuya Nishihara <yuya at tcha.org>
# Date 1456737007 -32400
#      Mon Feb 29 18:10:07 2016 +0900
# Node ID d44396be9829c57957470d59177b64a4fd501b54
# Parent  cfdfa5bb37d298d47ee348f9992a9468cd40efaa
parser: move alias definition parser to common rule-set class

The original _parsealiasdefn() function is split into common _builddefn()
and revset-specific _parsealiasdefn(). revset._relabelaliasargs() is removed
as it is no longer used.

The doctests are ported by using the dummy parse().

diff --git a/mercurial/parser.py b/mercurial/parser.py
--- a/mercurial/parser.py
+++ b/mercurial/parser.py
@@ -386,3 +386,52 @@ class basealiasrules(object):
         elif sym.startswith('$'):
             raise error.ParseError(_("'$' not for alias arguments"))
         return (op, sym)
+
+    @classmethod
+    def _builddefn(cls, defn, args):
+        """Parse an alias definition into a tree and marks substitutions
+
+        This function marks alias argument references as ``_aliasarg``. The
+        parsing rule is provided by ``_parsedefn()``.
+
+        ``args`` is a list of alias argument names, or None if the alias
+        is declared as a symbol.
+
+        >>> parsemap = {
+        ...     '$1 or foo': ('or', ('symbol', '$1'), ('symbol', 'foo')),
+        ...     '$1 or $bar': ('or', ('symbol', '$1'), ('symbol', '$bar')),
+        ...     '$10 or baz': ('or', ('symbol', '$10'), ('symbol', 'baz')),
+        ...     '"$1" or "foo"': ('or', ('string', '$1'), ('string', 'foo')),
+        ... }
+        >>> class aliasrules(basealiasrules):
+        ...     _parsedefn = staticmethod(parsemap.__getitem__)
+        ...     _getlist = staticmethod(lambda x: [])
+        >>> builddefn = aliasrules._builddefn
+        >>> def pprint(tree):
+        ...     print prettyformat(tree, ('_aliasarg', 'string', 'symbol'))
+        >>> args = ['$1', '$2', 'foo']
+        >>> pprint(builddefn('$1 or foo', args))
+        (or
+          ('_aliasarg', '$1')
+          ('_aliasarg', 'foo'))
+        >>> try:
+        ...     builddefn('$1 or $bar', args)
+        ... except error.ParseError as inst:
+        ...     print parseerrordetail(inst)
+        '$' not for alias arguments
+        >>> args = ['$1', '$10', 'foo']
+        >>> pprint(builddefn('$10 or baz', args))
+        (or
+          ('_aliasarg', '$10')
+          ('symbol', 'baz'))
+        >>> pprint(builddefn('"$1" or "foo"', args))
+        (or
+          ('string', '$1')
+          ('string', 'foo'))
+        """
+        tree = cls._parsedefn(defn)
+        if args:
+            args = set(args)
+        else:
+            args = set()
+        return cls._relabelargs(tree, args)
diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -2254,57 +2254,19 @@ def _parsealiasdecl(decl):
         raise error.ParseError(_('invalid token'), pos)
     return parser.simplifyinfixops(tree, ('list',))
 
-def _relabelaliasargs(tree, args):
-    return _aliasrules._relabelargs(tree, args)
-
-def _parsealiasdefn(defn, args):
-    """Parse alias definition ``defn``
-
-    This function marks alias argument references as ``_aliasarg``.
-
-    ``args`` is a list of alias argument names, or None if the alias
-    is declared as a symbol.
-
-    This returns "tree" as parsing result.
-
-    >>> def prettyformat(tree):
-    ...     return parser.prettyformat(tree, ('_aliasarg', 'string', 'symbol'))
-    >>> args = ['$1', '$2', 'foo']
-    >>> print prettyformat(_parsealiasdefn('$1 or foo', args))
-    (or
-      ('_aliasarg', '$1')
-      ('_aliasarg', 'foo'))
-    >>> try:
-    ...     _parsealiasdefn('$1 or $bar', args)
-    ... except error.ParseError, inst:
-    ...     print parser.parseerrordetail(inst)
-    '$' not for alias arguments
-    >>> args = ['$1', '$10', 'foo']
-    >>> print prettyformat(_parsealiasdefn('$10 or foobar', args))
-    (or
-      ('_aliasarg', '$10')
-      ('symbol', 'foobar'))
-    >>> print prettyformat(_parsealiasdefn('"$1" or "foo"', args))
-    (or
-      ('string', '$1')
-      ('string', 'foo'))
-    """
-    if args:
-        args = set(args)
-    else:
-        args = set()
-
+def _parsealiasdefn(defn):
+    """Parse alias definition ``defn``"""
     p = parser.parser(elements)
     tree, pos = p.parse(_tokenizealias(defn))
     if pos != len(defn):
         raise error.ParseError(_('invalid token'), pos)
-    tree = parser.simplifyinfixops(tree, ('list', 'or'))
-    return _relabelaliasargs(tree, args)
+    return parser.simplifyinfixops(tree, ('list', 'or'))
 
 class _aliasrules(parser.basealiasrules):
     """Parsing and expansion rule set of revset aliases"""
     _section = _('revset alias')
     _parsedecl = staticmethod(_parsealiasdecl)
+    _parsedefn = staticmethod(_parsealiasdefn)
     _getlist = staticmethod(getlist)
 
 class revsetalias(object):
@@ -2326,7 +2288,7 @@ class revsetalias(object):
             return
 
         try:
-            self.replacement = _parsealiasdefn(value, self.args)
+            self.replacement = _aliasrules._builddefn(value, self.args)
         except error.ParseError as inst:
             self.error = _('failed to parse the definition of revset alias'
                            ' "%s": %s') % (self.name,


More information about the Mercurial-devel mailing list