Handle expression joining with Jinja joiner in ComputedStyle templates.

When generating ComputedStyle, we often have to generate patterns like:

   foo &&
   bar &&
   baz

So far, we've been doing this using the print_if macro, which allows us
to print the && only if we are not at the last iteration:

   {% for item in list %}
       {{item}}{{print_if(not loop.last, " &&")}}
   {% endfor %}

However, when there's multiple loops involved, this breaks down, e.g.:

   {% for item in list_a %}
       {{item}}{{print_if(not loop.last, " &&")}}
   {% endfor %}
   {% for item in list_b %}
       {{item}}{{print_if(not loop.last, " &&")}}
   {% endfor %}

This could print something like:

   foo &&
   bar
   baz

Currently, we solve this by always ending with && and closing off the
last && with the identity value:

   foo &&
   bar &&
   baz &&
   true

However, this is ugly, and does not work when there's no identity value,
e.g. the commas in C++ constructor initializer lists.

Fortunately, Jinja has a builtin solution: joiner. A joiner is an object
that will print a value everytime it's invoked, except the first time.
By creating a joiner before the loops, we can invoke it every time we
need to print a new line. Note that this means the joiner string is now
a prefix, not a suffix:

   foo
   && bar
   && baz

This patch changes ComputedStyle related templates to use joiners. For
recursive macros, we have to pass the state of the joiner on as an
extra optional argument.

This patch does not change behaviour.

Diff of generated files:
https://gist.github.com/darrnshn/480933b282092bb35ea9f0469f82ceff/revisions

Bug: 628043
Change-Id: I7134ba4cf7e444ed96035bc38983a0057454f37d
Reviewed-on: https://chromium-review.googlesource.com/535296
Reviewed-by: Naina Raisinghani <nainar@chromium.org>
Commit-Queue: Darren Shen <shend@chromium.org>
Cr-Commit-Position: refs/heads/master@{#479319}
4 files changed