Mercurial > hg
changeset 28910:1203159c8928
parser: factor out _trygetfunc() that extracts function name and arguments
This provides a customization point for templater. In templater, there are
two ways to call a unary function: func(x) and x|func. They are processed
differently in templater due to historical reasons, but they should be
handled in the same way while expanding aliases. In short, x|func should be
processed as syntactic sugar for func(x).
_funcnode and _getlist() are replaced by _trygetfunc().
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Tue, 29 Mar 2016 17:27:34 +0900 |
parents | edbffdc7f6a0 |
children | 35da19348143 |
files | mercurial/parser.py mercurial/revset.py |
diffstat | 2 files changed, 28 insertions(+), 24 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/parser.py Tue Mar 29 17:21:11 2016 +0900 +++ b/mercurial/parser.py Tue Mar 29 17:27:34 2016 +0900 @@ -256,9 +256,8 @@ """ # typically a config section, which will be included in error messages _section = None - # tags of symbol and function nodes + # tag of symbol node _symbolnode = 'symbol' - _funcnode = 'func' def __new__(cls): raise TypeError("'%s' is not instantiatable" % cls.__name__) @@ -269,8 +268,8 @@ raise NotImplementedError @staticmethod - def _getlist(tree): - """Extract a list of arguments from parsed tree""" + def _trygetfunc(tree): + """Return (name, args) if tree is a function; otherwise None""" raise NotImplementedError @classmethod @@ -311,15 +310,17 @@ ... if isinstance(x, Exception): ... raise x ... return x - >>> def getlist(tree): - ... if not tree: - ... return [] - ... if tree[0] == 'list': - ... return list(tree[1:]) - ... return [tree] + >>> def trygetfunc(tree): + ... if not tree or tree[0] != 'func' or tree[1][0] != 'symbol': + ... return None + ... if not tree[2]: + ... return tree[1][1], [] + ... if tree[2][0] == 'list': + ... return tree[1][1], list(tree[2][1:]) + ... return tree[1][1], [tree[2]] >>> class aliasrules(basealiasrules): ... _parse = staticmethod(parse) - ... _getlist = staticmethod(getlist) + ... _trygetfunc = staticmethod(trygetfunc) >>> builddecl = aliasrules._builddecl >>> builddecl('foo') ('foo', None, None) @@ -360,19 +361,17 @@ return (decl, None, _("'$' not for alias arguments")) return (name, None, None) - if tree[0] == cls._funcnode and tree[1][0] == cls._symbolnode: + func = cls._trygetfunc(tree) + if func: # "name(arg, ....) = ...." style - name = tree[1][1] + name, args = func if name.startswith('$'): return (decl, None, _("'$' not for alias arguments")) - args = [] - for arg in cls._getlist(tree[2]): - if arg[0] != cls._symbolnode: - return (decl, None, _("invalid argument list")) - args.append(arg[1]) + if any(t[0] != cls._symbolnode for t in args): + return (decl, None, _("invalid argument list")) if len(args) != len(set(args)): return (name, None, _("argument names collide with each other")) - return (name, args, None) + return (name, [t[1] for t in args], None) return (decl, None, _("invalid format")) @@ -411,7 +410,7 @@ ... } >>> class aliasrules(basealiasrules): ... _parse = staticmethod(parsemap.__getitem__) - ... _getlist = staticmethod(lambda x: []) + ... _trygetfunc = staticmethod(lambda x: None) >>> builddefn = aliasrules._builddefn >>> def pprint(tree): ... print prettyformat(tree, ('_aliasarg', 'string', 'symbol')) @@ -483,11 +482,12 @@ a = aliases.get(name) if a and a.args is None: return a, None - if tree[0] == cls._funcnode and tree[1][0] == cls._symbolnode: - name = tree[1][1] + func = cls._trygetfunc(tree) + if func: + name, args = func a = aliases.get(name) if a and a.args is not None: - return a, cls._getlist(tree[2]) + return a, args return None @classmethod
--- a/mercurial/revset.py Tue Mar 29 17:21:11 2016 +0900 +++ b/mercurial/revset.py Tue Mar 29 17:27:34 2016 +0900 @@ -2254,7 +2254,11 @@ """Parsing and expansion rule set of revset aliases""" _section = _('revset alias') _parse = staticmethod(_parsealias) - _getlist = staticmethod(getlist) + + @staticmethod + def _trygetfunc(tree): + if tree[0] == 'func' and tree[1][0] == 'symbol': + return tree[1][1], getlist(tree[2]) def expandaliases(ui, tree, showwarning=None): aliases = _aliasrules.buildmap(ui.configitems('revsetalias'))