Commit b01a24a4 authored by Yuki Shiino's avatar Yuki Shiino Committed by Commit Bot

bind-gen: Improve newline-handling in code generation

Use of "${ x | trim }" of Mako template unconditionally removes
whitespaces including newlines.  It makes it hard to insert empty
lines in generated code.

This patch revisits the newline problem again, and improves it.

Bug: 839389
Change-Id: If838b4766fe8938e7f7c2bfb2ff8802d56ac9441
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1883830Reviewed-by: default avatarHitoshi Yoshida <peria@chromium.org>
Commit-Queue: Yuki Shiino <yukishiino@chromium.org>
Cr-Commit-Position: refs/heads/master@{#709894}
parent cca2286e
......@@ -264,7 +264,11 @@ class CodeNode(object):
@property
def renderer(self):
return self._renderer or self.outer.renderer
# Always use the renderer of the root node in order not to mix renderers
# during rendering of a single code node tree.
if self.outer is not None:
return self.outer.renderer
return self._renderer
@property
def current_render_state(self):
......@@ -366,7 +370,7 @@ class SequenceNode(CodeNode):
template_text = CodeNode.format_template(
"""\
% for node in {element_nodes}:
${node | trim}\\
${node}\\
% if not loop.last:
{separator}\\
% endif
......@@ -454,12 +458,16 @@ class SymbolScopeNode(SequenceNode):
insert corresponding SymbolDefinitionNodes appropriately.
"""
def __init__(self, code_nodes=None, renderer=None):
def __init__(self,
code_nodes=None,
separator="\n",
separator_last="",
renderer=None):
SequenceNode.__init__(
self,
code_nodes=code_nodes,
separator="\n",
separator_last="\n",
separator=separator,
separator_last=separator_last,
renderer=renderer)
self._registered_code_symbols = set()
......@@ -703,8 +711,8 @@ class ConditionalExitNode(ConditionalNode):
template_text = CodeNode.format_template(
"""\
if (${{{conditional}}}) {{
${{{body} | trim}}
}}
${{{body}}}
}}\\
""", **gensyms)
template_vars = {
gensyms["conditional"]: cond,
......@@ -803,10 +811,10 @@ class FunctionDefinitionNode(CodeNode):
template_text = CodeNode.format_template(
"""\
${{{comment} | trim}}
${{{comment}}}
${{{return_type}}} ${{{name}}}(${{{arg_decls}}}) {{
${{{body} | trim}}
}}
${{{body}}}
}}\\
""", **gensyms)
template_vars = {
gensyms["name"]: name,
......
......@@ -103,7 +103,7 @@ class CodeNodeTest(unittest.TestCase):
appropriately.
"""
renderer = MakoRenderer()
root = SymbolScopeNode(renderer=renderer)
root = SymbolScopeNode(separator_last="\n", renderer=renderer)
root.register_code_symbols([
SymbolNode("var1", "int ${var1} = ${var2} + ${var3};"),
......@@ -127,7 +127,7 @@ int var1 = var2 + var3;
def test_symbol_definition_with_exit_branches(self):
renderer = MakoRenderer()
root = SymbolScopeNode(renderer=renderer)
root = SymbolScopeNode(separator_last="\n", renderer=renderer)
root.register_code_symbols([
SymbolNode("var1", "int ${var1} = 1;"),
......@@ -175,7 +175,7 @@ var3;
def test_symbol_definition_with_nested_exit_branches(self):
renderer = MakoRenderer()
root = SymbolScopeNode(renderer=renderer)
root = SymbolScopeNode(separator_last="\n", renderer=renderer)
root.register_code_symbols([
SymbolNode("var1", "int ${var1} = 1;"),
......@@ -229,11 +229,12 @@ if (true) {
def test_function_definition_minimum(self):
renderer = MakoRenderer()
root = FunctionDefinitionNode(
name=LiteralNode("blink::bindings::func"),
arg_decls=[],
return_type=LiteralNode("void"),
renderer=renderer)
root = SymbolScopeNode(separator_last="\n", renderer=renderer)
root.append(
FunctionDefinitionNode(
name=LiteralNode("blink::bindings::func"),
arg_decls=[],
return_type=LiteralNode("void")))
self.assertRenderResult(root, """\
......@@ -244,6 +245,7 @@ void blink::bindings::func() {
def test_function_definition_full(self):
renderer = MakoRenderer()
root = SymbolScopeNode(separator_last="\n", renderer=renderer)
local_vars = [
SymbolNode("var1", "int ${var1} = 1;"),
......@@ -257,18 +259,15 @@ void blink::bindings::func() {
TextNode("return ${var2};"),
])
root = FunctionDefinitionNode(
name=LiteralNode("blink::bindings::func"),
arg_decls=[LiteralNode("int arg1"),
LiteralNode("int arg2")],
return_type=LiteralNode("void"),
local_vars=local_vars,
body=func_body,
comment=LiteralNode("""\
// comment1
// comment2
"""),
renderer=renderer)
root.append(
FunctionDefinitionNode(
name=LiteralNode("blink::bindings::func"),
arg_decls=[LiteralNode("int arg1"),
LiteralNode("int arg2")],
return_type=LiteralNode("void"),
local_vars=local_vars,
body=func_body,
comment=LiteralNode("// comment1\n// comment2")))
self.assertRenderResult(
root, """\
......@@ -286,8 +285,8 @@ void blink::bindings::func(int arg1, int arg2) {
def test_template_error_handling(self):
renderer = MakoRenderer()
root = SymbolScopeNode(renderer=renderer)
root.append(
SymbolScopeNode([
# Have Mako raise a NameError.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment