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

bind-gen: Refactor collect_forward_decls_and_include_headers

It turned out that a single function
collect_forward_decls_and_include_headers does the job for
IDL callback functions, IDL callback interfaces, IDL dictionaries,
and upcoming IDL unions, so moves the function into
codegen_utils.py to be shared among them.

Bug: 839389
Change-Id: Ieee0e75388a90367c04da9c2adb40ce4bfad072a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2521873Reviewed-by: default avatarHitoshi Yoshida <peria@chromium.org>
Commit-Queue: Yuki Shiino <yukishiino@chromium.org>
Cr-Commit-Position: refs/heads/master@{#824827}
parent 810e42d6
...@@ -25,6 +25,7 @@ from .code_node_cxx import CxxUnlikelyIfNode ...@@ -25,6 +25,7 @@ from .code_node_cxx import CxxUnlikelyIfNode
from .codegen_accumulator import CodeGenAccumulator from .codegen_accumulator import CodeGenAccumulator
from .codegen_context import CodeGenContext from .codegen_context import CodeGenContext
from .codegen_format import format_template as _format from .codegen_format import format_template as _format
from .codegen_utils import collect_forward_decls_and_include_headers
from .codegen_utils import component_export from .codegen_utils import component_export
from .codegen_utils import component_export_header from .codegen_utils import component_export_header
from .codegen_utils import enclose_with_header_guard from .codegen_utils import enclose_with_header_guard
...@@ -473,52 +474,6 @@ return false;\ ...@@ -473,52 +474,6 @@ return false;\
return decls, defs return decls, defs
def collect_forward_decls_and_include_headers(func_like):
assert isinstance(func_like, web_idl.FunctionLike)
header_forward_decls = set()
header_include_headers = set()
source_forward_decls = set()
source_include_headers = set()
def collect(idl_type):
if idl_type.is_any or idl_type.is_object:
header_include_headers.add(
"third_party/blink/renderer/bindings/core/v8/script_value.h")
elif idl_type.is_buffer_source_type:
header_include_headers.update([
"third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h",
"third_party/blink/renderer/core/typed_arrays/dom_typed_array.h",
])
elif idl_type.is_promise:
header_include_headers.add(
"third_party/blink/renderer/bindings/core/v8/script_promise.h")
elif idl_type.is_string:
header_include_headers.add(
"third_party/blink/renderer/platform/wtf/text/wtf_string.h")
elif idl_type.type_definition_object:
type_def_obj = idl_type.type_definition_object
header_forward_decls.add(blink_class_name(type_def_obj))
if isinstance(type_def_obj, web_idl.Interface):
source_include_headers.add(
PathManager(type_def_obj).blink_path(ext="h"))
else:
source_include_headers.add(
PathManager(type_def_obj).api_path(ext="h"))
elif idl_type.union_definition_object:
union_def_obj = idl_type.union_definition_object
header_include_headers.add(
PathManager(union_def_obj).api_path(ext="h"))
if func_like.return_type:
func_like.return_type.apply_to_all_composing_elements(collect)
for argument in func_like.arguments:
argument.idl_type.apply_to_all_composing_elements(collect)
return (header_forward_decls, header_include_headers, source_forward_decls,
source_include_headers)
def generate_callback_function(callback_function_identifier): def generate_callback_function(callback_function_identifier):
assert isinstance(callback_function_identifier, web_idl.Identifier) assert isinstance(callback_function_identifier, web_idl.Identifier)
...@@ -636,8 +591,9 @@ def generate_callback_function(callback_function_identifier): ...@@ -636,8 +591,9 @@ def generate_callback_function(callback_function_identifier):
"third_party/blink/renderer/bindings/core/v8/generated_code_helper.h", "third_party/blink/renderer/bindings/core/v8/generated_code_helper.h",
]) ])
(header_forward_decls, header_include_headers, source_forward_decls, (header_forward_decls, header_include_headers, source_forward_decls,
source_include_headers source_include_headers) = collect_forward_decls_and_include_headers(
) = collect_forward_decls_and_include_headers(callback_function) [callback_function.return_type] +
map(lambda argument: argument.idl_type, callback_function.arguments))
header_node.accumulator.add_class_decls(header_forward_decls) header_node.accumulator.add_class_decls(header_forward_decls)
header_node.accumulator.add_include_headers(header_include_headers) header_node.accumulator.add_include_headers(header_include_headers)
source_node.accumulator.add_class_decls(source_forward_decls) source_node.accumulator.add_class_decls(source_forward_decls)
......
...@@ -16,6 +16,7 @@ from .code_node_cxx import CxxFuncDefNode ...@@ -16,6 +16,7 @@ from .code_node_cxx import CxxFuncDefNode
from .code_node_cxx import CxxNamespaceNode from .code_node_cxx import CxxNamespaceNode
from .codegen_accumulator import CodeGenAccumulator from .codegen_accumulator import CodeGenAccumulator
from .codegen_context import CodeGenContext from .codegen_context import CodeGenContext
from .codegen_utils import collect_forward_decls_and_include_headers
from .codegen_utils import component_export from .codegen_utils import component_export
from .codegen_utils import component_export_header from .codegen_utils import component_export_header
from .codegen_utils import enclose_with_header_guard from .codegen_utils import enclose_with_header_guard
...@@ -30,7 +31,6 @@ from .task_queue import TaskQueue ...@@ -30,7 +31,6 @@ from .task_queue import TaskQueue
# IDL callback interface and IDL callback function share a lot by their nature, # IDL callback interface and IDL callback function share a lot by their nature,
# so this module uses some implementations from IDL callback function. # so this module uses some implementations from IDL callback function.
from .callback_function import collect_forward_decls_and_include_headers
from .callback_function import make_callback_invocation_function from .callback_function import make_callback_invocation_function
from .callback_function import make_invoke_and_report_function from .callback_function import make_invoke_and_report_function
from .callback_function import make_is_runnable_or_throw_exception from .callback_function import make_is_runnable_or_throw_exception
...@@ -289,7 +289,9 @@ def generate_callback_interface(callback_interface_identifier): ...@@ -289,7 +289,9 @@ def generate_callback_interface(callback_interface_identifier):
]) ])
(header_forward_decls, header_include_headers, source_forward_decls, (header_forward_decls, header_include_headers, source_forward_decls,
source_include_headers) = collect_forward_decls_and_include_headers( source_include_headers) = collect_forward_decls_and_include_headers(
callback_interface.operation_groups[0][0]) [callback_interface.operation_groups[0][0].return_type] +
map(lambda argument: argument.idl_type,
callback_interface.operation_groups[0][0].arguments))
header_node.accumulator.add_class_decls(header_forward_decls) header_node.accumulator.add_class_decls(header_forward_decls)
header_node.accumulator.add_include_headers(header_include_headers) header_node.accumulator.add_include_headers(header_include_headers)
source_node.accumulator.add_class_decls(source_forward_decls) source_node.accumulator.add_class_decls(source_forward_decls)
......
...@@ -6,6 +6,7 @@ import web_idl ...@@ -6,6 +6,7 @@ import web_idl
from . import name_style from . import name_style
from . import style_format from . import style_format
from .blink_v8_bridge import blink_class_name
from .blink_v8_bridge import blink_type_info from .blink_v8_bridge import blink_type_info
from .code_node import CodeNode from .code_node import CodeNode
from .code_node import EmptyNode from .code_node import EmptyNode
...@@ -62,6 +63,70 @@ def make_header_include_directives(accumulator): ...@@ -62,6 +63,70 @@ def make_header_include_directives(accumulator):
return LiteralNode(HeaderIncludeDirectives(accumulator)) return LiteralNode(HeaderIncludeDirectives(accumulator))
def collect_forward_decls_and_include_headers(idl_types):
assert isinstance(idl_types, (list, tuple))
assert all(isinstance(idl_type, web_idl.IdlType) for idl_type in idl_types)
header_forward_decls = set()
header_include_headers = set()
source_forward_decls = set()
source_include_headers = set()
def collect(idl_type):
if idl_type.is_any or idl_type.is_object:
header_include_headers.add(
"third_party/blink/renderer/bindings/core/v8/script_value.h")
elif idl_type.is_boolean or idl_type.is_numeric:
pass
elif idl_type.is_buffer_source_type:
header_include_headers.update([
"third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h",
"third_party/blink/renderer/core/typed_arrays/dom_typed_array.h",
])
elif idl_type.is_nullable:
if not blink_type_info(idl_type.inner_type).has_null_value:
header_include_headers.add("base/optional.h")
elif idl_type.is_promise:
header_include_headers.add(
"third_party/blink/renderer/bindings/core/v8/script_promise.h")
elif (idl_type.is_sequence or idl_type.is_record
or idl_type.is_frozen_array or idl_type.is_variadic):
header_include_headers.add(
"third_party/blink/renderer/platform/heap/heap_allocator.h")
elif idl_type.is_string:
header_include_headers.add(
"third_party/blink/renderer/platform/wtf/text/wtf_string.h")
elif idl_type.is_typedef:
pass
elif idl_type.is_void:
pass
elif idl_type.type_definition_object:
type_def_obj = idl_type.type_definition_object
if type_def_obj.is_enumeration:
header_include_headers.add(
PathManager(type_def_obj).api_path(ext="h"))
elif type_def_obj.is_interface:
header_forward_decls.add(blink_class_name(type_def_obj))
source_include_headers.add(
PathManager(type_def_obj).blink_path(ext="h"))
else:
header_forward_decls.add(blink_class_name(type_def_obj))
source_include_headers.add(
PathManager(type_def_obj).api_path(ext="h"))
elif idl_type.union_definition_object:
union_def_obj = idl_type.union_definition_object
header_include_headers.add(
PathManager(union_def_obj).api_path(ext="h"))
else:
assert False, "Unknown type: {}".format(idl_type.syntactic_form)
for idl_type in idl_types:
idl_type.apply_to_all_composing_elements(collect)
return (header_forward_decls, header_include_headers, source_forward_decls,
source_include_headers)
def component_export(component, for_testing): def component_export(component, for_testing):
assert isinstance(component, web_idl.Component) assert isinstance(component, web_idl.Component)
assert isinstance(for_testing, bool) assert isinstance(for_testing, bool)
......
...@@ -27,6 +27,7 @@ from .codegen_accumulator import CodeGenAccumulator ...@@ -27,6 +27,7 @@ from .codegen_accumulator import CodeGenAccumulator
from .codegen_context import CodeGenContext from .codegen_context import CodeGenContext
from .codegen_expr import expr_from_exposure from .codegen_expr import expr_from_exposure
from .codegen_format import format_template as _format from .codegen_format import format_template as _format
from .codegen_utils import collect_forward_decls_and_include_headers
from .codegen_utils import component_export from .codegen_utils import component_export
from .codegen_utils import component_export_header from .codegen_utils import component_export_header
from .codegen_utils import enclose_with_header_guard from .codegen_utils import enclose_with_header_guard
...@@ -118,114 +119,6 @@ def bind_member_iteration_local_vars(code_node): ...@@ -118,114 +119,6 @@ def bind_member_iteration_local_vars(code_node):
code_node.register_code_symbols(local_vars) code_node.register_code_symbols(local_vars)
def _make_include_headers(cg_context):
assert isinstance(cg_context, CodeGenContext)
dictionary = cg_context.dictionary
for_testing = dictionary.code_generator_info.for_testing
header_includes = set()
source_includes = set()
if dictionary.inherited:
header_includes.add(
PathManager(dictionary.inherited).api_path(ext="h"))
else:
header_includes.add(
"third_party/blink/renderer/platform/bindings/dictionary_base.h")
header_includes.update([
component_export_header(dictionary.components[0], for_testing),
"third_party/blink/renderer/bindings/core/v8/generated_code_helper.h",
"third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h",
"v8/include/v8.h",
])
source_includes.update([
"third_party/blink/renderer/platform/bindings/exception_messages.h",
"third_party/blink/renderer/platform/bindings/exception_state.h",
"third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h",
"third_party/blink/renderer/platform/heap/visitor.h",
])
def add_include_headers(idl_type):
if idl_type.is_numeric or idl_type.is_boolean or idl_type.is_typedef:
pass
elif idl_type.is_string:
header_includes.add(
"third_party/blink/renderer/platform/wtf/text/wtf_string.h")
elif idl_type.is_buffer_source_type:
header_includes.update([
"third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h",
"third_party/blink/renderer/core/typed_arrays/dom_typed_array.h",
"third_party/blink/renderer/platform/heap/handle.h",
])
elif idl_type.is_object or idl_type.is_any:
header_includes.add(
"third_party/blink/renderer/bindings/core/v8/script_value.h")
elif idl_type.is_enumeration:
type_def_obj = idl_type.type_definition_object
header_includes.add(PathManager(type_def_obj).api_path(ext="h"))
elif idl_type.is_dictionary:
type_def_obj = idl_type.type_definition_object
header_includes.add(
"third_party/blink/renderer/platform/heap/handle.h")
source_includes.add(PathManager(type_def_obj).api_path(ext="h"))
elif idl_type.type_definition_object:
type_def_obj = idl_type.type_definition_object
header_includes.update([
PathManager(type_def_obj).api_path(ext="h"),
"third_party/blink/renderer/platform/heap/handle.h",
])
elif (idl_type.is_sequence or idl_type.is_frozen_array
or idl_type.is_variadic or idl_type.is_record):
header_includes.update([
"third_party/blink/renderer/platform/wtf/vector.h",
"third_party/blink/renderer/platform/heap/heap_allocator.h",
])
elif idl_type.is_promise:
header_includes.add(
"third_party/blink/renderer/bindings/core/v8/script_promise.h")
elif idl_type.is_union:
union_def_obj = idl_type.union_definition_object
header_includes.add(PathManager(union_def_obj).api_path(ext="h"))
elif idl_type.is_nullable:
if not blink_type_info(idl_type.inner_type).has_null_value:
header_includes.add("base/optional.h")
else:
assert False, "Unknown type: {}".format(idl_type.syntactic_form)
for member in dictionary.own_members:
member.idl_type.apply_to_all_composing_elements(add_include_headers)
return header_includes, source_includes
def _make_forward_declarations(cg_context):
assert isinstance(cg_context, CodeGenContext)
dictionary = cg_context.dictionary
header_class_fwd_decls = set([
"ExceptionState",
"Visitor",
])
header_struct_fwd_decls = set()
source_class_fwd_decls = set()
source_struct_fwd_decls = set()
def add_fwd_decls(idl_type):
if idl_type.is_dictionary:
header_class_fwd_decls.add(
blink_class_name(idl_type.type_definition_object))
for member in dictionary.own_members:
member.idl_type.apply_to_all_composing_elements(add_fwd_decls)
return (header_class_fwd_decls, header_struct_fwd_decls,
source_class_fwd_decls, source_struct_fwd_decls)
def _is_default_ctor_available(dictionary): def _is_default_ctor_available(dictionary):
for member in dictionary.members: for member in dictionary.members:
if member.default_value is None: if member.default_value is None:
...@@ -1005,9 +898,10 @@ def generate_dictionary(dictionary_identifier): ...@@ -1005,9 +898,10 @@ def generate_dictionary(dictionary_identifier):
web_idl_database = package_initializer().web_idl_database() web_idl_database = package_initializer().web_idl_database()
dictionary = web_idl_database.find(dictionary_identifier) dictionary = web_idl_database.find(dictionary_identifier)
assert len(dictionary.components) == 1, ( path_manager = PathManager(dictionary)
assert path_manager.api_component == path_manager.impl_component, (
"We don't support partial dictionaries across components yet.") "We don't support partial dictionaries across components yet.")
component = dictionary.components[0] api_component = path_manager.api_component
for_testing = dictionary.code_generator_info.for_testing for_testing = dictionary.code_generator_info.for_testing
path_manager = PathManager(dictionary) path_manager = PathManager(dictionary)
...@@ -1042,7 +936,7 @@ def generate_dictionary(dictionary_identifier): ...@@ -1042,7 +936,7 @@ def generate_dictionary(dictionary_identifier):
class_def = CxxClassDefNode(cg_context.class_name, class_def = CxxClassDefNode(cg_context.class_name,
base_class_names=[cg_context.base_class_name], base_class_names=[cg_context.base_class_name],
export=component_export( export=component_export(
component, for_testing)) api_component, for_testing))
class_def.set_base_template_vars(cg_context.template_bindings()) class_def.set_base_template_vars(cg_context.template_bindings())
class_def.top_section.append( class_def.top_section.append(
TextNode("using BaseClass = ${base_class_name};")) TextNode("using BaseClass = ${base_class_name};"))
...@@ -1102,17 +996,6 @@ def generate_dictionary(dictionary_identifier): ...@@ -1102,17 +996,6 @@ def generate_dictionary(dictionary_identifier):
member_presense_var_defs.append(presense_var_def) member_presense_var_defs.append(presense_var_def)
# Header part (copyright, include directives, and forward declarations) # Header part (copyright, include directives, and forward declarations)
header_includes, source_includes = _make_include_headers(cg_context)
header_node.accumulator.add_include_headers(header_includes)
source_node.accumulator.add_include_headers(source_includes)
(header_class_fwd_decls, header_struct_fwd_decls, source_class_fwd_decls,
source_struct_fwd_decls) = _make_forward_declarations(cg_context)
header_node.accumulator.add_class_decls(header_class_fwd_decls)
header_node.accumulator.add_struct_decls(header_struct_fwd_decls)
source_node.accumulator.add_class_decls(source_class_fwd_decls)
source_node.accumulator.add_struct_decls(source_struct_fwd_decls)
header_node.extend([ header_node.extend([
make_copyright_header(), make_copyright_header(),
TextNode(""), TextNode(""),
...@@ -1142,6 +1025,29 @@ def generate_dictionary(dictionary_identifier): ...@@ -1142,6 +1025,29 @@ def generate_dictionary(dictionary_identifier):
]) ])
# Assemble the parts. # Assemble the parts.
header_node.accumulator.add_class_decls(["ExceptionState"])
header_node.accumulator.add_include_headers([
(PathManager(dictionary.inherited).api_path(ext="h")
if dictionary.inherited else
"third_party/blink/renderer/platform/bindings/dictionary_base.h"),
component_export_header(api_component, for_testing),
"v8/include/v8.h",
])
source_node.accumulator.add_include_headers([
"third_party/blink/renderer/bindings/core/v8/generated_code_helper.h",
"third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h",
"third_party/blink/renderer/platform/bindings/exception_messages.h",
"third_party/blink/renderer/platform/bindings/exception_state.h",
"third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h",
])
(header_forward_decls, header_include_headers, source_forward_decls,
source_include_headers) = collect_forward_decls_and_include_headers(
map(lambda member: member.idl_type, dictionary.own_members))
header_node.accumulator.add_class_decls(header_forward_decls)
header_node.accumulator.add_include_headers(header_include_headers)
source_node.accumulator.add_class_decls(source_forward_decls)
source_node.accumulator.add_include_headers(source_include_headers)
header_blink_ns.body.append(class_def) header_blink_ns.body.append(class_def)
class_def.public_section.extend([ class_def.public_section.extend([
create_decl, create_decl,
......
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