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().
--- 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)
--- a/mercurial/revset.py Mon Feb 29 18:00:51 2016 +0900
+++ b/mercurial/revset.py Mon Feb 29 18:10:07 2016 +0900
@@ -2250,57 +2250,19 @@
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):
@@ -2322,7 +2284,7 @@
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,