Patchwork [3,of,5,V2] templater: add parsing rule for key-value pair

login
register
mail settings
Submitter Yuya Nishihara
Date April 8, 2017, 1:06 p.m.
Message ID <0a547405070213e07516.1491656798@mimosa>
Download mbox | patch
Permalink /patch/20023/
State Accepted
Headers show

Comments

Yuya Nishihara - April 8, 2017, 1:06 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1491220555 -32400
#      Mon Apr 03 20:55:55 2017 +0900
# Node ID 0a547405070213e075162d45f37a2d82877c61c3
# Parent  50cbe5f6c63fb73cdb06f80c9ea5a7e263e0cc84
templater: add parsing rule for key-value pair

Based on the revset implementation, 70a2082f855a. This patch also adjusts
the test as '=' is now a valid token.
Ryan McElroy - April 10, 2017, 9:46 a.m.
On 4/8/17 2:06 PM, Yuya Nishihara wrote:
> # HG changeset patch
> # User Yuya Nishihara <yuya@tcha.org>
> # Date 1491220555 -32400
> #      Mon Apr 03 20:55:55 2017 +0900
> # Node ID 0a547405070213e075162d45f37a2d82877c61c3
> # Parent  50cbe5f6c63fb73cdb06f80c9ea5a7e263e0cc84
> templater: add parsing rule for key-value pair
>
> Based on the revset implementation, 70a2082f855a. This patch also adjusts
> the test as '=' is now a valid token.
>
> diff --git a/mercurial/templater.py b/mercurial/templater.py
> --- a/mercurial/templater.py
> +++ b/mercurial/templater.py
> @@ -39,6 +39,7 @@ elements = {
>       "/": (5, None, None, ("/", 5), None),
>       "+": (4, None, None, ("+", 4), None),
>       "-": (4, None, ("negate", 19), ("-", 4), None),
> +    "=": (3, None, None, ("keyvalue", 3), None),
>       ",": (2, None, None, ("list", 2), None),
>       ")": (0, None, None, None, None),
>       "integer": (0, "integer", None, None, None),
> @@ -56,7 +57,7 @@ def tokenize(program, start, end, term=N
>           c = program[pos]
>           if c.isspace(): # skip inter-token whitespace
>               pass
> -        elif c in "(,)%|+-*/": # handle simple operators
> +        elif c in "(=,)%|+-*/": # handle simple operators
>               yield (c, None, pos)
>           elif c in '"\'': # handle quoted templates
>               s = pos + 1
> @@ -462,6 +463,9 @@ def buildfunc(exp, context):
>           return (runfilter, (args[0], f))
>       raise error.ParseError(_("unknown function '%s'") % n)
>   
> +def buildkeyvaluepair(exp, content):
> +    raise error.ParseError(_("can't use a key-value pair in this context"))
> +
>   # dict of template built-in functions
>   funcs = {}
>   
> @@ -982,6 +986,7 @@ exprmethods = {
>       "|": buildfilter,
>       "%": buildmap,
>       "func": buildfunc,
> +    "keyvalue": buildkeyvaluepair,
>       "+": lambda e, c: buildarithmetic(e, c, lambda a, b: a + b),
>       "-": lambda e, c: buildarithmetic(e, c, lambda a, b: a - b),
>       "negate": buildnegate,
> diff --git a/tests/test-command-template.t b/tests/test-command-template.t
> --- a/tests/test-command-template.t
> +++ b/tests/test-command-template.t
> @@ -134,6 +134,18 @@ But negate binds closer still:
>       ('string', '\n'))
>     -3
>   
> +Keyword arguments:
> +
> +  $ hg debugtemplate -r0 -v '{foo=bar|baz}'
> +  (template
> +    (keyvalue
> +      ('symbol', 'foo')
> +      (|
> +        ('symbol', 'bar')
> +        ('symbol', 'baz'))))
> +  hg: parse error: can't use a key-value pair in this context
> +  [255]
> +
>   Second branch starting at nullrev:
>   
>     $ hg update null
> @@ -2668,7 +2680,7 @@ Error in nested template:
>     hg: parse error at 2: unterminated string
>     [255]
>   
> -  $ hg log -T '{"foo{date|=}"}'
> +  $ hg log -T '{"foo{date|?}"}'
>     hg: parse error at 11: syntax error
>     [255]
>   
>

Why remove the |? test? I'd prefer you just add another for |= as 
opposed to replace the existing test.
Yuya Nishihara - April 10, 2017, 12:19 p.m.
On Mon, 10 Apr 2017 10:46:29 +0100, Ryan McElroy wrote:
> On 4/8/17 2:06 PM, Yuya Nishihara wrote:
> > # HG changeset patch
> > # User Yuya Nishihara <yuya@tcha.org>
> > # Date 1491220555 -32400
> > #      Mon Apr 03 20:55:55 2017 +0900
> > # Node ID 0a547405070213e075162d45f37a2d82877c61c3
> > # Parent  50cbe5f6c63fb73cdb06f80c9ea5a7e263e0cc84
> > templater: add parsing rule for key-value pair

> > @@ -2668,7 +2680,7 @@ Error in nested template:
> >     hg: parse error at 2: unterminated string
> >     [255]
> >   
> > -  $ hg log -T '{"foo{date|=}"}'
> > +  $ hg log -T '{"foo{date|?}"}'
> >     hg: parse error at 11: syntax error
> >     [255]
> 
> Why remove the |? test? I'd prefer you just add another for |= as 
> opposed to replace the existing test.

This checks a parsing error in inner template, so any kind of parsing
errors should be okay. I just prefer using '?' which can trigger more
obvious error than '='.

Patch

diff --git a/mercurial/templater.py b/mercurial/templater.py
--- a/mercurial/templater.py
+++ b/mercurial/templater.py
@@ -39,6 +39,7 @@  elements = {
     "/": (5, None, None, ("/", 5), None),
     "+": (4, None, None, ("+", 4), None),
     "-": (4, None, ("negate", 19), ("-", 4), None),
+    "=": (3, None, None, ("keyvalue", 3), None),
     ",": (2, None, None, ("list", 2), None),
     ")": (0, None, None, None, None),
     "integer": (0, "integer", None, None, None),
@@ -56,7 +57,7 @@  def tokenize(program, start, end, term=N
         c = program[pos]
         if c.isspace(): # skip inter-token whitespace
             pass
-        elif c in "(,)%|+-*/": # handle simple operators
+        elif c in "(=,)%|+-*/": # handle simple operators
             yield (c, None, pos)
         elif c in '"\'': # handle quoted templates
             s = pos + 1
@@ -462,6 +463,9 @@  def buildfunc(exp, context):
         return (runfilter, (args[0], f))
     raise error.ParseError(_("unknown function '%s'") % n)
 
+def buildkeyvaluepair(exp, content):
+    raise error.ParseError(_("can't use a key-value pair in this context"))
+
 # dict of template built-in functions
 funcs = {}
 
@@ -982,6 +986,7 @@  exprmethods = {
     "|": buildfilter,
     "%": buildmap,
     "func": buildfunc,
+    "keyvalue": buildkeyvaluepair,
     "+": lambda e, c: buildarithmetic(e, c, lambda a, b: a + b),
     "-": lambda e, c: buildarithmetic(e, c, lambda a, b: a - b),
     "negate": buildnegate,
diff --git a/tests/test-command-template.t b/tests/test-command-template.t
--- a/tests/test-command-template.t
+++ b/tests/test-command-template.t
@@ -134,6 +134,18 @@  But negate binds closer still:
     ('string', '\n'))
   -3
 
+Keyword arguments:
+
+  $ hg debugtemplate -r0 -v '{foo=bar|baz}'
+  (template
+    (keyvalue
+      ('symbol', 'foo')
+      (|
+        ('symbol', 'bar')
+        ('symbol', 'baz'))))
+  hg: parse error: can't use a key-value pair in this context
+  [255]
+
 Second branch starting at nullrev:
 
   $ hg update null
@@ -2668,7 +2680,7 @@  Error in nested template:
   hg: parse error at 2: unterminated string
   [255]
 
-  $ hg log -T '{"foo{date|=}"}'
+  $ hg log -T '{"foo{date|?}"}'
   hg: parse error at 11: syntax error
   [255]