Commit 6f43880f authored by Yuki Shiino's avatar Yuki Shiino Committed by Commit Bot

bind-gen: Implement CxxClassDefNode and CxxNamespaceNode

Bug: 839389
Change-Id: Idab46cbd5c3fcecd5ceedb5d9104b3024267db5a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1981511
Commit-Queue: Yuki Shiino <yukishiino@chromium.org>
Reviewed-by: default avatarHitoshi Yoshida <peria@chromium.org>
Cr-Commit-Position: refs/heads/master@{#727546}
parent 019a644e
...@@ -152,7 +152,7 @@ class CxxFuncDeclNode(CompositeNode): ...@@ -152,7 +152,7 @@ class CxxFuncDeclNode(CompositeNode):
delete=False): delete=False):
""" """
Args: Args:
name: Function name node, which may include nested-name-specifier name: Function name, which may include nested-name-specifier
(i.e. 'namespace_name::' and/or 'class_name::'). (i.e. 'namespace_name::' and/or 'class_name::').
arg_decls: List of argument declarations. arg_decls: List of argument declarations.
return_type: Return type. return_type: Return type.
...@@ -185,10 +185,10 @@ class CxxFuncDeclNode(CompositeNode): ...@@ -185,10 +185,10 @@ class CxxFuncDeclNode(CompositeNode):
CompositeNode.__init__( CompositeNode.__init__(
self, self,
template_format, template_format,
name=name, name=_to_maybe_text_node(name),
arg_decls=ListNode( arg_decls=ListNode(
_to_node_list(arg_decls, TextNode), separator=", "), map(_to_maybe_text_node, arg_decls), separator=", "),
return_type=return_type, return_type=_to_maybe_text_node(return_type),
const=const, const=const,
override=override, override=override,
default_or_delete=default_or_delete) default_or_delete=default_or_delete)
...@@ -204,7 +204,7 @@ class CxxFuncDefNode(CompositeNode): ...@@ -204,7 +204,7 @@ class CxxFuncDefNode(CompositeNode):
member_initializer_list=None): member_initializer_list=None):
""" """
Args: Args:
name: Function name node, which may include nested-name-specifier name: Function name, which may include nested-name-specifier
(i.e. 'namespace_name::' and/or 'class_name::'). (i.e. 'namespace_name::' and/or 'class_name::').
arg_decls: List of argument declarations. arg_decls: List of argument declarations.
return_type: Return type. return_type: Return type.
...@@ -228,21 +228,20 @@ class CxxFuncDefNode(CompositeNode): ...@@ -228,21 +228,20 @@ class CxxFuncDefNode(CompositeNode):
if member_initializer_list is None: if member_initializer_list is None:
member_initializer_list = "" member_initializer_list = ""
else: else:
initializers = ListNode( member_initializer_list = ListNode(
_to_node_list(member_initializer_list, TextNode), map(_to_maybe_text_node, member_initializer_list),
separator=", ") separator=", ",
member_initializer_list = ListNode([TextNode(" : "), initializers], head=" : ")
separator="")
self._body_node = SymbolScopeNode() self._body_node = SymbolScopeNode()
CompositeNode.__init__( CompositeNode.__init__(
self, self,
template_format, template_format,
name=name, name=_to_maybe_text_node(name),
arg_decls=ListNode( arg_decls=ListNode(
_to_node_list(arg_decls, TextNode), separator=", "), map(_to_maybe_text_node, arg_decls), separator=", "),
return_type=return_type, return_type=_to_maybe_text_node(return_type),
const=const, const=const,
override=override, override=override,
member_initializer_list=member_initializer_list, member_initializer_list=member_initializer_list,
...@@ -253,20 +252,117 @@ class CxxFuncDefNode(CompositeNode): ...@@ -253,20 +252,117 @@ class CxxFuncDefNode(CompositeNode):
return self._body_node return self._body_node
class CxxClassDefNode(CompositeNode):
def __init__(self, name, base_class_names=None, final=False):
"""
Args:
name: The class name to be defined.
base_class_names: The list of base class names.
final: True makes this a final class.
"""
assert isinstance(final, bool)
template_format = ("class {name}{final}{base_clause} {{\n"
" {top_section}\n"
" {public_section}\n"
" {protected_section}\n"
" {private_section}\n"
"}};")
final = " final" if final else ""
if base_class_names is None:
base_clause = ""
else:
base_specifier_list = [
CompositeNode(
"public {base_class_name}",
base_class_name=_to_maybe_text_node(base_class_name))
for base_class_name in base_class_names
]
base_clause = ListNode(
base_specifier_list, separator=", ", head=" : ")
self._top_section = ListNode(tail="\n")
self._public_section = ListNode(head="public:\n", tail="\n")
self._protected_section = ListNode(head="protected:\n", tail="\n")
self._private_section = ListNode(head="private:\n", tail="\n")
CompositeNode.__init__(
self,
template_format,
name=_to_maybe_text_node(name),
final=final,
base_clause=base_clause,
top_section=self._top_section,
public_section=self._public_section,
protected_section=self._protected_section,
private_section=self._private_section)
@property
def top_section(self):
return self._top_section
@property
def public_section(self):
return self._public_section
@property
def protected_section(self):
return self._protected_section
@property
def private_section(self):
return self._private_section
class CxxNamespaceNode(CompositeNode):
def __init__(self, name="", body=None):
template_format = ("namespace {name} {{\n"
"\n"
"{body}\n"
"\n"
"}} // namespace {name}")
if body is None:
self._body = ListNode()
else:
self._body = _to_list_node(body)
CompositeNode.__init__(
self, template_format, name=name, body=self._body)
@property
def body(self):
return self._body
def _to_conditional_node(cond): def _to_conditional_node(cond):
if isinstance(cond, CodeNode): if isinstance(cond, CodeNode):
return cond return cond
elif isinstance(cond, CodeGenExpr): if isinstance(cond, CodeGenExpr):
return TextNode(cond.to_text()) return TextNode(cond.to_text())
elif isinstance(cond, str): if isinstance(cond, str):
return TextNode(cond) return TextNode(cond)
else: assert False
assert False
def _to_list_node(node):
if isinstance(node, ListNode):
return node
if isinstance(node, CodeNode):
return ListNode([node])
if isinstance(node, (list, tuple)):
return ListNode(node)
assert False
def _to_node_list(iterable, constructor): def _to_maybe_text_node(node):
return map(lambda x: x if isinstance(x, CodeNode) else constructor(x), if isinstance(node, CodeNode):
iterable) return node
if isinstance(node, str):
return TextNode(node)
assert False
def _to_symbol_scope_node(node, likeliness): def _to_symbol_scope_node(node, likeliness):
......
...@@ -7,6 +7,7 @@ import unittest ...@@ -7,6 +7,7 @@ import unittest
from .code_node import SymbolNode from .code_node import SymbolNode
from .code_node import SymbolScopeNode from .code_node import SymbolScopeNode
from .code_node import TextNode from .code_node import TextNode
from .code_node_cxx import CxxClassDefNode
from .code_node_cxx import CxxFuncDefNode from .code_node_cxx import CxxFuncDefNode
from .code_node_cxx import CxxLikelyIfNode from .code_node_cxx import CxxLikelyIfNode
from .code_node_cxx import CxxUnlikelyIfNode from .code_node_cxx import CxxUnlikelyIfNode
...@@ -33,7 +34,7 @@ class CodeNodeCxxTest(unittest.TestCase): ...@@ -33,7 +34,7 @@ class CodeNodeCxxTest(unittest.TestCase):
self.assertEqual(actual, expected) self.assertEqual(actual, expected)
def test_symbol_definition_with_branches(self): def test_symbol_definition_with_branches(self):
root = SymbolScopeNode(tail="\n") root = SymbolScopeNode()
root.register_code_symbols([ root.register_code_symbols([
SymbolNode("var1", "int ${var1} = 1;"), SymbolNode("var1", "int ${var1} = 1;"),
...@@ -75,11 +76,11 @@ if (var5) { ...@@ -75,11 +76,11 @@ if (var5) {
int var6 = 6; int var6 = 6;
return var6; return var6;
} }
var3; var3;\
""") """)
def test_symbol_definition_with_nested_branches(self): def test_symbol_definition_with_nested_branches(self):
root = SymbolScopeNode(tail="\n") root = SymbolScopeNode()
root.register_code_symbols([ root.register_code_symbols([
SymbolNode("var1", "int ${var1} = 1;"), SymbolNode("var1", "int ${var1} = 1;"),
...@@ -128,26 +129,21 @@ if (true) { ...@@ -128,26 +129,21 @@ if (true) {
return var2; return var2;
} }
return; return;
} }\
""") """)
def test_function_definition_minimum(self): def test_function_definition_minimum(self):
root = SymbolScopeNode(tail="\n") root = CxxFuncDefNode(
root.append( name="blink::bindings::func", arg_decls=[], return_type="void")
CxxFuncDefNode(
name="blink::bindings::func", arg_decls=[],
return_type="void"))
self.assertRenderResult(root, """\ self.assertRenderResult(root, """\
void blink::bindings::func() { void blink::bindings::func() {
} }\
""") """)
def test_function_definition_full(self): def test_function_definition_full(self):
root = SymbolScopeNode(tail="\n") root = CxxFuncDefNode(
func_def = CxxFuncDefNode(
name="blink::bindings::func", name="blink::bindings::func",
arg_decls=["int arg1", "int arg2"], arg_decls=["int arg1", "int arg2"],
return_type="void", return_type="void",
...@@ -158,19 +154,17 @@ void blink::bindings::func() { ...@@ -158,19 +154,17 @@ void blink::bindings::func() {
"member2(\"str\")", "member2(\"str\")",
]) ])
func_def.body.register_code_symbols([ root.body.register_code_symbols([
SymbolNode("var1", "int ${var1} = 1;"), SymbolNode("var1", "int ${var1} = 1;"),
SymbolNode("var2", "int ${var2} = 2;"), SymbolNode("var2", "int ${var2} = 2;"),
]) ])
func_def.body.extend([ root.body.extend([
CxxUnlikelyIfNode( CxxUnlikelyIfNode(
cond=TextNode("${var1}"), body=[TextNode("return ${var1};")]), cond=TextNode("${var1}"), body=[TextNode("return ${var1};")]),
TextNode("return ${var2};"), TextNode("return ${var2};"),
]) ])
root.append(func_def)
self.assertRenderResult( self.assertRenderResult(
root, """\ root, """\
void blink::bindings::func(int arg1, int arg2) const override\ void blink::bindings::func(int arg1, int arg2) const override\
...@@ -181,5 +175,33 @@ void blink::bindings::func(int arg1, int arg2) const override\ ...@@ -181,5 +175,33 @@ void blink::bindings::func(int arg1, int arg2) const override\
} }
int var2 = 2; int var2 = 2;
return var2; return var2;
} }\
""")
def test_class_definition(self):
root = CxxClassDefNode("X", ["A", "B"], final=True)
root.public_section.extend([
TextNode("void m1();"),
TextNode("void m2();"),
])
root.private_section.extend([
TextNode("int m1_;"),
TextNode("int m2_;"),
])
self.assertRenderResult(
root, """\
class X final : public A, public B {
public:
void m1();
void m2();
private:
int m1_;
int m2_;
};\
""") """)
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