templater: switch methods table on compileexp() of func args and inner expr
authorYuya Nishihara <yuya@tcha.org>
Sat, 02 May 2015 18:05:04 +0900
changeset 25001 9668c1a433b3
parent 25000 c54248bbe023
child 25002 829faf8ab605
templater: switch methods table on compileexp() of func args and inner expr The next patch will introduce integer literals, but the schemes extension expects that '{1}', '{2}', ... are interpreted as keywords. This patch allows us to process '{foo(1)}' as 'func(integer)', whereas '{1}' as 'symbol'.
mercurial/templater.py
--- a/mercurial/templater.py	Sun May 10 13:33:51 2015 -0400
+++ b/mercurial/templater.py	Sat May 02 18:05:04 2015 +0900
@@ -100,12 +100,12 @@
         parseres, pos = p.parse(pd)
         parsed.append(parseres)
 
-    return [compileexp(e, context) for e in parsed]
+    return [compileexp(e, context, methods) for e in parsed]
 
-def compileexp(exp, context):
+def compileexp(exp, context, curmethods):
     t = exp[0]
-    if t in methods:
-        return methods[t](exp, context)
+    if t in curmethods:
+        return curmethods[t](exp, context)
     raise error.ParseError(_("unknown method '%s'") % t)
 
 # template evaluation
@@ -157,7 +157,7 @@
     return v
 
 def buildfilter(exp, context):
-    func, data = compileexp(exp[1], context)
+    func, data = compileexp(exp[1], context, methods)
     filt = getfilter(exp[2], context)
     return (runfilter, (func, data, filt))
 
@@ -179,7 +179,7 @@
                            "keyword '%s'") % (filt.func_name, dt))
 
 def buildmap(exp, context):
-    func, data = compileexp(exp[1], context)
+    func, data = compileexp(exp[1], context, methods)
     ctmpl = gettemplate(exp[2], context)
     return (runmap, (func, data, ctmpl))
 
@@ -208,7 +208,7 @@
 
 def buildfunc(exp, context):
     n = getsymbol(exp[1])
-    args = [compileexp(x, context) for x in getlist(exp[2])]
+    args = [compileexp(x, context, exprmethods) for x in getlist(exp[2])]
     if n in funcs:
         f = funcs[n]
         return (f, args)
@@ -565,17 +565,21 @@
     else:
         return tokens[num]
 
-methods = {
+# methods to interpret function arguments or inner expressions (e.g. {_(x)})
+exprmethods = {
     "string": lambda e, c: (runstring, e[1]),
     "rawstring": lambda e, c: (runrawstring, e[1]),
     "symbol": lambda e, c: (runsymbol, e[1]),
-    "group": lambda e, c: compileexp(e[1], c),
+    "group": lambda e, c: compileexp(e[1], c, exprmethods),
 #    ".": buildmember,
     "|": buildfilter,
     "%": buildmap,
     "func": buildfunc,
     }
 
+# methods to interpret top-level template (e.g. {x}, {x|_}, {x % "y"})
+methods = exprmethods.copy()
+
 funcs = {
     "date": date,
     "diff": diff,