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 @@ -2250,57 +2250,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): @@ -2322,7 +2284,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,