Commit 32088ffb authored by Hitoshi Yoshida's avatar Hitoshi Yoshida Committed by Commit Bot

CodeGen: Refactoring of dictionary.py

- Uses (CxxFuncDeclNode and) CxxFuncDefNode for all functions.
- Makes a function declaration and its definition together.


Bug: 839389
Change-Id: I8e0d8c981c03bb5f7ed65478cdf6cdd19e02ab56
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2040974Reviewed-by: default avatarYuki Shiino <yukishiino@chromium.org>
Commit-Queue: Hitoshi Yoshida <peria@chromium.org>
Cr-Commit-Position: refs/heads/master@{#738951}
parent fb854429
......@@ -90,8 +90,6 @@ def _member_presence_expr(member):
def make_dict_member_get_def(cg_context):
assert isinstance(cg_context, CodeGenContext)
T = TextNode
member = cg_context.dict_member
blink_member_name = _blink_member_name(member)
......@@ -101,12 +99,11 @@ def make_dict_member_get_def(cg_context):
return_type=blink_type_info(member.idl_type).ref_t,
const=True)
func_def.set_base_template_vars(cg_context.template_bindings())
body = func_def.body
body.extend([
T(_format("DCHECK({}());", blink_member_name.has_api)),
T(_format("return {};", blink_member_name.value_var)),
TextNode(_format("DCHECK({}());", blink_member_name.has_api)),
TextNode(_format("return {};", blink_member_name.value_var)),
])
return func_def
......@@ -115,8 +112,6 @@ def make_dict_member_get_def(cg_context):
def make_dict_member_has_def(cg_context):
assert isinstance(cg_context, CodeGenContext)
T = TextNode
member = cg_context.dict_member
func_def = CxxFuncDefNode(
......@@ -125,11 +120,10 @@ def make_dict_member_has_def(cg_context):
return_type="bool",
const=True)
func_def.set_base_template_vars(cg_context.template_bindings())
body = func_def.body
_1 = _member_presence_expr(member)
body.append(T(_format("return {_1};", _1=_1)))
body.append(TextNode(_format("return {_1};", _1=_1)))
return func_def
......@@ -150,7 +144,6 @@ def make_dict_member_set_def(cg_context):
],
return_type="void")
func_def.set_base_template_vars(cg_context.template_bindings())
body = func_def.body
_1 = blink_member_name.value_var
......@@ -163,20 +156,53 @@ def make_dict_member_set_def(cg_context):
return func_def
def make_get_v8_dict_member_names_def(cg_context):
def make_dict_member_defs(cg_context):
assert isinstance(cg_context, CodeGenContext)
T = TextNode
member = cg_context.dict_member
get_def = make_dict_member_get_def(cg_context)
has_def = make_dict_member_has_def(cg_context)
set_def = make_dict_member_set_def(cg_context)
default_value_initializer = ""
if member.default_value:
default_expr = make_default_value_expr(member.idl_type,
member.default_value)
if default_expr.initializer is not None:
default_value_initializer = _format("{{{}}}",
default_expr.initializer)
_1 = blink_type_info(member.idl_type).member_t
_2 = _blink_member_name(member).value_var
_3 = default_value_initializer
value_var_def = TextNode(_format("{_1} {_2}{_3};", _1=_1, _2=_2, _3=_3))
if _does_use_presence_flag(member):
_1 = _blink_member_name(member).presence_var
presense_var_def = TextNode(_format("bool {_1} = false;", _1=_1))
else:
presense_var_def = None
return (get_def, has_def, set_def, value_var_def, presense_var_def)
def make_get_v8_dict_member_names_func(cg_context):
assert isinstance(cg_context, CodeGenContext)
dictionary = cg_context.dictionary
name = "GetV8MemberNames"
arg_decls = ["v8::Isolate* isolate"]
return_type = "const v8::Eternal<v8::Name>*"
func_decl = CxxFuncDeclNode(
name=name, arg_decls=arg_decls, return_type=return_type)
func_def = CxxFuncDefNode(
name="GetV8MemberNames",
name=name,
class_name=cg_context.class_name,
arg_decls=["v8::Isolate* isolate"],
return_type="const v8::Eternal<v8::Name>*")
func_def.add_template_vars(cg_context.template_bindings())
arg_decls=arg_decls,
return_type=return_type)
func_def.set_base_template_vars(cg_context.template_bindings())
body = func_def.body
pattern = ("static const char* kKeyStrings[] = {{{_1}}};")
......@@ -184,34 +210,36 @@ def make_get_v8_dict_member_names_def(cg_context):
_format("\"{}\"", member.identifier)
for member in dictionary.own_members)
body.extend([
T(_format(pattern, _1=_1)),
T("return V8PerIsolateData::From(isolate)"
"->FindOrCreateEternalNameCache("
"kKeyStrings, kKeyStrings, base::size(kKeyStrings));")
TextNode(_format(pattern, _1=_1)),
TextNode("return V8PerIsolateData::From(isolate)"
"->FindOrCreateEternalNameCache("
"kKeyStrings, kKeyStrings, base::size(kKeyStrings));"),
])
return func_def
return func_decl, func_def
def make_fill_with_dict_members_def(cg_context):
def make_fill_with_dict_members_func(cg_context):
assert isinstance(cg_context, CodeGenContext)
T = TextNode
dictionary = cg_context.dictionary
name = "FillWithMembers"
arg_decls = [
"v8::Isolate* isolate",
"v8::Local<v8::Object> creation_context",
"v8::Local<v8::Object> v8_dictionary",
]
return_type = "bool"
func_decl = CxxFuncDeclNode(
name=name, arg_decls=arg_decls, return_type=return_type, const=True)
func_def = CxxFuncDefNode(
name="FillWithMembers",
name=name,
class_name=cg_context.class_name,
arg_decls=[
"v8::Isolate* isolate",
"v8::Local<v8::Object> creation_context",
"v8::Local<v8::Object> v8_dictionary",
],
return_type="bool",
arg_decls=arg_decls,
return_type=return_type,
const=True)
func_def.add_template_vars(cg_context.template_bindings())
func_def.set_base_template_vars(cg_context.template_bindings())
body = func_def.body
if dictionary.inherited:
......@@ -219,36 +247,41 @@ def make_fill_with_dict_members_def(cg_context):
if (!BaseClass::FillWithMembers(isolate, creation_context, v8_dictionary)) {
return false;
}"""
body.append(T(text))
body.append(TextNode(text))
body.append(
T("return FillWithOwnMembers("
"isolate, creation_context, v8_dictionary);"))
TextNode("return FillWithOwnMembers("
"isolate, creation_context, v8_dictionary);"))
return func_def
return func_decl, func_def
def make_fill_with_own_dict_members_def(cg_context):
def make_fill_with_own_dict_members_func(cg_context):
assert isinstance(cg_context, CodeGenContext)
T = TextNode
dictionary = cg_context.dictionary
own_members = dictionary.own_members
name = "FillWithOwnMembers"
arg_decls = [
"v8::Isolate* isolate",
"v8::Local<v8::Object> creation_context",
"v8::Local<v8::Object> v8_dictionary",
]
return_type = "bool"
func_decl = CxxFuncDeclNode(
name=name, arg_decls=arg_decls, return_type=return_type, const=True)
func_def = CxxFuncDefNode(
name="FillWithOwnMembers",
name=name,
class_name=cg_context.class_name,
arg_decls=[
"v8::Isolate* isolate",
"v8::Local<v8::Object> creation_context",
"v8::Local<v8::Object> v8_dictionary",
],
return_type="bool",
arg_decls=arg_decls,
return_type=return_type,
const=True)
func_def.add_template_vars(cg_context.template_bindings())
func_def.set_base_template_vars(cg_context.template_bindings())
body = func_def.body
body.add_template_var("current_context", "current_context")
body.register_code_symbol(
SymbolNode(
......@@ -286,31 +319,38 @@ if ({_1}()) {{
body.append(T("return true;"))
return func_def
return func_decl, func_def
def make_dict_create_def(cg_context):
def make_dict_create_funcs(cg_context):
assert isinstance(cg_context, CodeGenContext)
T = TextNode
dictionary = cg_context.dictionary
func_def = CxxFuncDefNode(
name="Create",
name = "Create"
arg_decls = [
"v8::Isolate* isolate",
"v8::Local<v8::Value> v8_value",
"ExceptionState& exception_state",
]
return_type = "${class_name}*"
default_create_def = CxxFuncDefNode(
name=name, arg_decls=[], return_type=return_type, static=True)
default_create_def.set_base_template_vars(cg_context.template_bindings())
default_create_def.body.append(
TextNode("return MakeGarbageCollected<${class_name}>();"))
create_decl = CxxFuncDeclNode(
name=name, arg_decls=arg_decls, return_type=return_type, static=True)
create_def = CxxFuncDefNode(
name=name,
class_name=cg_context.class_name,
arg_decls=[
"v8::Isolate* isolate",
"v8::Local<v8::Value> v8_value",
"ExceptionState& exception_state",
],
return_type=T("${class_name}*"))
func_def.add_template_vars(cg_context.template_bindings())
body = func_def.body
arg_decls=arg_decls,
return_type=return_type)
create_def.set_base_template_vars(cg_context.template_bindings())
body.append(
T("""\
create_def.body.append(
TextNode("""\
DCHECK(!v8_value.IsEmpty());
${class_name}* dictionary = MakeGarbageCollected<${class_name}>();
......@@ -320,10 +360,18 @@ if (exception_state.HadException()) {
}
return dictionary;"""))
return func_def
decls = ListNode([
default_create_def,
create_decl,
])
defs = ListNode([
create_def,
])
return decls, defs
def make_fill_dict_members_def(cg_context):
def make_fill_dict_members_func(cg_context):
assert isinstance(cg_context, CodeGenContext)
T = TextNode
......@@ -332,19 +380,24 @@ def make_fill_dict_members_def(cg_context):
own_members = dictionary.own_members
required_own_members = list(
member for member in own_members if member.is_required)
name = "FillMembers"
arg_decls = [
"v8::Isolate* isolate",
"v8::Local<v8::Value> v8_value",
"ExceptionState& exception_state",
]
return_type = "void"
func_decl = CxxFuncDeclNode(
name=name, arg_decls=arg_decls, return_type=return_type)
func_def = CxxFuncDefNode(
name="FillMembers",
name=name,
class_name=cg_context.class_name,
arg_decls=[
"v8::Isolate* isolate",
"v8::Local<v8::Value> v8_value",
"ExceptionState& exception_state",
],
return_type="void")
func_def.add_template_vars(cg_context.template_bindings())
arg_decls=arg_decls,
return_type=return_type)
func_def.set_base_template_vars(cg_context.template_bindings())
if len(required_own_members) > 0:
if required_own_members:
check_required_members_node = T("""\
if (v8_value->IsNullOrUndefined()) {
exception_state.ThrowTypeError(ExceptionMessages::FailedToConstruct(
......@@ -383,28 +436,31 @@ FillMembersInternal(isolate, v8_value.As<v8::Object>(), exception_state);""")
call_internal_func_node,
])
return func_def
return func_decl, func_def
def make_fill_dict_members_internal_def(cg_context):
def make_fill_dict_members_internal_func(cg_context):
assert isinstance(cg_context, CodeGenContext)
T = TextNode
dictionary = cg_context.dictionary
own_members = dictionary.own_members
name = "FillMembersInternal"
arg_decls = [
"v8::Isolate* isolate",
"v8::Local<v8::Object> v8_dictionary",
"ExceptionState& exception_state",
]
return_type = "void"
func_decl = CxxFuncDeclNode(
name=name, arg_decls=arg_decls, return_type=return_type)
func_def = CxxFuncDefNode(
name="FillMembersInternal",
name=name,
class_name=cg_context.class_name,
arg_decls=[
"v8::Isolate* isolate",
"v8::Local<v8::Object> v8_dictionary",
"ExceptionState& exception_state",
],
return_type="void")
func_def.add_template_vars(cg_context.template_bindings())
arg_decls=arg_decls,
return_type=return_type)
func_def.set_base_template_vars(cg_context.template_bindings())
body = func_def.body
body.add_template_var("isolate", "isolate")
body.add_template_var("exception_state", "exception_state")
......@@ -435,7 +491,7 @@ if (${exception_state}.HadException()) {
for key_index, member in enumerate(own_members):
body.append(make_fill_own_dict_member(key_index, member))
return func_def
return func_decl, func_def
def make_fill_own_dict_member(key_index, member):
......@@ -488,137 +544,43 @@ ${exception_state}.ThrowTypeError(
return node
def make_dict_trace_def(cg_context):
def make_dict_trace_func(cg_context):
assert isinstance(cg_context, CodeGenContext)
T = TextNode
dictionary = cg_context.dictionary
own_members = dictionary.own_members
name = "Trace"
arg_decls = ["Visitor* visitor"]
return_type = "void"
func_decl = CxxFuncDeclNode(
name=name, arg_decls=arg_decls, return_type=return_type, override=True)
func_def = CxxFuncDefNode(
name="Trace",
name=name,
class_name=cg_context.class_name,
arg_decls=["Visitor* visitor"],
return_type="void")
func_def.add_template_vars(cg_context.template_bindings())
arg_decls=arg_decls,
return_type=return_type)
func_def.set_base_template_vars(cg_context.template_bindings())
body = func_def.body
def trace_member_node(member):
def make_trace_member_node(member):
pattern = "TraceIfNeeded<{_1}>::Trace(visitor, {_2});"
_1 = blink_type_info(member.idl_type).member_t
_2 = _blink_member_name(member).value_var
return T(_format(pattern, _1=_1, _2=_2))
body.extend(map(trace_member_node, own_members))
body.append(T("BaseClass::Trace(visitor);"))
return func_def
return TextNode(_format(pattern, _1=_1, _2=_2))
body.extend(map(make_trace_member_node, own_members))
body.append(TextNode("BaseClass::Trace(visitor);"))
def make_dict_class_def(cg_context):
assert isinstance(cg_context, CodeGenContext)
T = TextNode
dictionary = cg_context.dictionary
component = dictionary.components[0]
class_def = CxxClassDefNode(
cg_context.class_name,
base_class_names=[cg_context.base_class_name],
export=component_export(component))
class_def.set_base_template_vars(cg_context.template_bindings())
class_def.top_section.append(
TextNode("using BaseClass = ${base_class_name};"))
public_section = class_def.public_section
public_section.append(
T("""\
static ${class_name}* Create() {
return MakeGarbageCollected<${class_name}>();
}
static ${class_name}* Create(
v8::Isolate* isolate,
v8::Local<v8::Value> v8_value,
ExceptionState& exception_state);
${class_name}() = default;
~${class_name}() = default;
void Trace(Visitor* visitor) override;
"""))
for member in dictionary.own_members:
member_cg_context = cg_context.make_copy(dict_member=member)
public_section.extend([
T(""),
make_dict_member_get_def(member_cg_context),
make_dict_member_has_def(member_cg_context),
make_dict_member_set_def(member_cg_context),
])
protected_section = class_def.protected_section
protected_section.append(
T("""\
bool FillWithMembers(
v8::Isolate* isolate,
v8::Local<v8::Object> creation_context,
v8::Local<v8::Object> v8_dictionary) const override;
void FillMembersInternal(
v8::Isolate* isolate,
v8::Local<v8::Object> v8_dictionary,
ExceptionState& exception_state);
"""))
private_section = class_def.private_section
private_section.append(
T("""\
static const v8::Eternal<v8::Name>* GetV8MemberNames(v8::Isolate*);
bool FillWithOwnMembers(
v8::Isolate* isolate,
v8::Local<v8::Object> creation_context,
v8::Local<v8::Object> v8_dictionary) const;
void FillMembers(
v8::Isolate* isolate,
v8::Local<v8::Value> v8_value,
ExceptionState& exception_state);
"""))
# C++ member variables for values
for member in dictionary.own_members:
default_value_initializer = ""
if member.default_value:
default_expr = make_default_value_expr(member.idl_type,
member.default_value)
if default_expr.initializer is not None:
default_value_initializer = _format("{{{}}}",
default_expr.initializer)
_1 = blink_type_info(member.idl_type).member_t
_2 = _blink_member_name(member).value_var
_3 = default_value_initializer
private_section.append(
T(_format("{_1} {_2}{_3};", _1=_1, _2=_2, _3=_3)))
private_section.append(T(""))
# C++ member variables for precences
for member in dictionary.own_members:
if _does_use_presence_flag(member):
_1 = _blink_member_name(member).presence_var
private_section.append(T(_format("bool {_1} = false;", _1=_1)))
return class_def
return func_decl, func_def
def generate_dictionary(dictionary):
assert len(dictionary.components) == 1, (
"We don't support partial dictionaries across components yet.")
component = dictionary.components[0]
path_manager = PathManager(dictionary)
class_name = name_style.class_(blink_class_name(dictionary))
......@@ -650,7 +612,55 @@ def generate_dictionary(dictionary):
source_blink_ns = CxxNamespaceNode(name_style.namespace("blink"))
# Class definitions
class_def = make_dict_class_def(cg_context)
class_def = CxxClassDefNode(
cg_context.class_name,
base_class_names=[cg_context.base_class_name],
export=component_export(component))
class_def.set_base_template_vars(cg_context.template_bindings())
class_def.top_section.append(
TextNode("using BaseClass = ${base_class_name};"))
# Create functions
create_decl, create_def = make_dict_create_funcs(cg_context)
# Constructor and destructor
constructor_decl = CxxFuncDeclNode(
name=cg_context.class_name, arg_decls=[], return_type="", default=True)
destructor_decl = CxxFuncDeclNode(
name="~${class_name}", arg_decls=[], return_type="", default=True)
# Fill with members (Blink -> V8 conversion)
(fill_with_members_decl,
fill_with_members_def) = make_fill_with_dict_members_func(cg_context)
(fill_with_own_members_decl, fill_with_own_members_def
) = make_fill_with_own_dict_members_func(cg_context)
# Fill members (V8 -> Blink conversion)
(fill_members_decl,
fill_members_def) = make_fill_dict_members_func(cg_context)
(fill_members_internal_decl, fill_members_internal_def
) = make_fill_dict_members_internal_func(cg_context)
# Misc. functions
(get_v8_member_names_decl,
get_v8_member_names_def) = make_get_v8_dict_member_names_func(cg_context)
trace_decl, trace_def = make_dict_trace_func(cg_context)
member_accessor_defs = ListNode()
member_value_var_defs = ListNode()
member_presense_var_defs = ListNode()
for member in cg_context.dictionary.own_members:
(member_get_def, member_has_def, member_set_def, member_value_var,
member_presense_var) = make_dict_member_defs(
cg_context.make_copy(dict_member=member))
member_accessor_defs.extend([
TextNode(""),
member_get_def,
member_has_def,
member_set_def,
])
member_value_var_defs.append(member_value_var)
member_presense_var_defs.append(member_presense_var)
# Header part (copyright, include directives, and forward declarations)
if dictionary.inherited:
......@@ -663,7 +673,7 @@ def generate_dictionary(dictionary):
[member.idl_type for member in dictionary.own_members]))
header_node.accumulator.add_include_headers([
base_class_header,
component_export_header(dictionary.components[0]),
component_export_header(component),
"v8/include/v8.h",
])
header_node.accumulator.add_class_decls([
......@@ -708,20 +718,45 @@ def generate_dictionary(dictionary):
# Assemble the parts.
header_blink_ns.body.append(class_def)
class_def.public_section.extend([
create_decl,
constructor_decl,
destructor_decl,
TextNode(""),
trace_decl,
TextNode(""),
member_accessor_defs,
])
class_def.protected_section.extend([
fill_with_members_decl,
TextNode(""),
fill_members_internal_decl,
])
class_def.private_section.extend([
get_v8_member_names_decl,
TextNode(""),
fill_with_own_members_decl,
TextNode(""),
fill_members_decl,
TextNode(""),
member_value_var_defs,
TextNode(""),
member_presense_var_defs,
])
source_blink_ns.body.extend([
make_get_v8_dict_member_names_def(cg_context),
get_v8_member_names_def,
TextNode(""),
make_dict_create_def(cg_context),
create_def,
TextNode(""),
make_fill_dict_members_def(cg_context),
fill_with_members_def,
TextNode(""),
make_fill_dict_members_internal_def(cg_context),
fill_with_own_members_def,
TextNode(""),
make_fill_with_dict_members_def(cg_context),
fill_members_def,
TextNode(""),
make_fill_with_own_dict_members_def(cg_context),
fill_members_internal_def,
TextNode(""),
make_dict_trace_def(cg_context),
trace_def,
])
# Write down to the files.
......
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