Patchwork [1,of,4] templater: switch methods table on compileexp() of func args and inner expr

login
register
mail settings
Submitter Yuya Nishihara
Date May 10, 2015, 11:03 p.m.
Message ID <0d41b8bb164d4942c978.1431298995@mimosa>
Download mbox | patch
Permalink /patch/9011/
State Accepted
Headers show

Comments

Yuya Nishihara - May 10, 2015, 11:03 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1430557504 -32400
#      Sat May 02 18:05:04 2015 +0900
# Node ID 0d41b8bb164d4942c978b92d9f66208aca56ab72
# Parent  015adbcd92f3bc15305a3ed4ee59676ff358eabf
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'.
Augie Fackler - May 15, 2015, 9:08 p.m.
On Mon, May 11, 2015 at 08:03:15AM +0900, Yuya Nishihara wrote:
> # HG changeset patch
> # User Yuya Nishihara <yuya@tcha.org>
> # Date 1430557504 -32400
> #      Sat May 02 18:05:04 2015 +0900
> # Node ID 0d41b8bb164d4942c978b92d9f66208aca56ab72
> # Parent  015adbcd92f3bc15305a3ed4ee59676ff358eabf
> templater: switch methods table on compileexp() of func args and inner expr

This was ninja-queued as 9668c1a433b3.

>
> 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'.
>
> diff --git a/mercurial/templater.py b/mercurial/templater.py
> --- a/mercurial/templater.py
> +++ b/mercurial/templater.py
> @@ -100,12 +100,12 @@ def compiletemplate(tmpl, context, strto
>          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 @@ def runsymbol(context, mapping, key):
>      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 @@ def runfilter(context, mapping, data):
>                             "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 runmap(context, mapping, data):
>
>  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 @@ def word(context, mapping, args):
>      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,
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@selenic.com
> http://selenic.com/mailman/listinfo/mercurial-devel

Patch

diff --git a/mercurial/templater.py b/mercurial/templater.py
--- a/mercurial/templater.py
+++ b/mercurial/templater.py
@@ -100,12 +100,12 @@  def compiletemplate(tmpl, context, strto
         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 @@  def runsymbol(context, mapping, key):
     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 @@  def runfilter(context, mapping, data):
                            "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 runmap(context, mapping, data):
 
 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 @@  def word(context, mapping, args):
     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,