mercurial/parser.py
changeset 28873 2ca3b7c563f3
parent 28872 5f31d2248745
child 28875 2e9f5453ab5a
--- a/mercurial/parser.py	Mon Feb 29 18:00:51 2016 +0900
+++ b/mercurial/parser.py	Mon Feb 29 18:10:07 2016 +0900
@@ -386,3 +386,52 @@
         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)