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

bind-gen: Introduce FunctionDefinitionNode

Bug: 839389
Change-Id: Id18d8b2048d757ac0c27f68726d3d4ebee9f02f0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1872072
Commit-Queue: Yuki Shiino <yukishiino@chromium.org>
Reviewed-by: default avatarHitoshi Yoshida <peria@chromium.org>
Cr-Commit-Position: refs/heads/master@{#707823}
parent d97ee8ce
......@@ -712,3 +712,79 @@ class UnlikelyExitNode(ConditionalExitNode):
def __init__(self, cond, body):
ConditionalExitNode.__init__(
self, cond=cond, body=body, body_likeliness=Likeliness.UNLIKELY)
class FunctionDefinitionNode(CodeNode):
"""Represents a function definition."""
def __init__(self,
name,
arg_decls,
return_type,
local_vars=None,
body=None,
comment=None,
renderer=None):
"""
Args:
name: Function name node, which may include nested-name-specifier
(i.e. 'namespace_name::' and/or 'type_name::').
arg_decls: List of argument declaration nodes.
return_type: Return type node.
local_vars: List of SymbolNodes that can be used in the function
body.
body: Function body node (of type SymbolScopeNode).
comment: Function header comment node.
"""
assert isinstance(name, CodeNode)
assert isinstance(arg_decls, (list, tuple))
assert all(isinstance(arg_decl, CodeNode) for arg_decl in arg_decls)
assert isinstance(return_type, CodeNode)
if local_vars is None:
local_vars = []
assert isinstance(local_vars, (list, tuple))
assert all(
isinstance(local_var, SymbolNode) for local_var in local_vars)
if body is None:
body = SymbolScopeNode()
assert isinstance(body, CodeNode)
if comment is None:
comment = LiteralNode("")
assert isinstance(comment, CodeNode)
gensyms = {
"name": CodeNode.gensym(),
"arg_decls": CodeNode.gensym(),
"return_type": CodeNode.gensym(),
"body": CodeNode.gensym(),
"comment": CodeNode.gensym(),
}
template_text = CodeNode.format_template(
"""\
${{{comment} | trim}}
${{{return_type}}} ${{{name}}}(${{{arg_decls}}}) {{
${{{body} | trim}}
}}
""", **gensyms)
template_vars = {
gensyms["name"]: name,
gensyms["arg_decls"]: SequenceNode(arg_decls, separator=", "),
gensyms["return_type"]: return_type,
gensyms["body"]: body,
gensyms["comment"]: comment,
}
CodeNode.__init__(
self,
template_text=template_text,
template_vars=template_vars,
renderer=renderer)
self._body_node = body
self._body_node.register_code_symbols(local_vars)
@property
def body(self):
return self._body_node
......@@ -4,6 +4,7 @@
import unittest
from .code_node import FunctionDefinitionNode
from .code_node import LikelyExitNode
from .code_node import LiteralNode
from .code_node import SequenceNode
......@@ -220,4 +221,61 @@ if (true) {
}
return;
}
""")
def test_function_definition_minimum(self):
renderer = MakoRenderer()
root = FunctionDefinitionNode(
name=LiteralNode("blink::bindings::func"),
arg_decls=[],
return_type=LiteralNode("void"),
renderer=renderer)
self.assertRenderResult(root, """\
void blink::bindings::func() {
}
""")
def test_function_definition_full(self):
renderer = MakoRenderer()
local_vars = [
SymbolNode("var1", "int ${var1} = 1;"),
SymbolNode("var2", "int ${var2} = 2;"),
]
func_body = SymbolScopeNode([
UnlikelyExitNode(
cond=TextNode("${var1}"),
body=SymbolScopeNode([TextNode("return ${var1};")])),
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)
self.assertRenderResult(
root, """\
// comment1
// comment2
void blink::bindings::func(int arg1, int arg2) {
int var1 = 1;
if (var1) {
return var1;
}
int var2 = 2;
return var2;
}
""")
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