Index: Source/bindings/scripts/code_generator_v8.py |
diff --git a/Source/bindings/scripts/code_generator_v8.py b/Source/bindings/scripts/code_generator_v8.py |
index 42fb98cfffb7dc58d5df3f95c3ba9be00664eb7a..dfb8bf0606ffa0bf521e4de82b6cab92a8f1f74e 100644 |
--- a/Source/bindings/scripts/code_generator_v8.py |
+++ b/Source/bindings/scripts/code_generator_v8.py |
@@ -323,40 +323,103 @@ class CodeGeneratorUnionType(object): |
self.target_component = target_component |
set_global_type_info(info_provider) |
- def generate_code(self): |
- union_types = self.info_provider.union_types |
- if not union_types: |
- return () |
- header_template = self.jinja_env.get_template('union.h') |
- cpp_template = self.jinja_env.get_template('union.cpp') |
- template_context = v8_union.union_context( |
- union_types, self.info_provider.interfaces_info) |
+ def _collect_unique_unions(self, union_types): |
+ """This method iterates over |union_types| to remove duplicated entries |
+ in |union_types| and to collect additional information (e.g. whether we |
+ need to generate *OrNull class). Returns a dict which contains the |
+ information. |
+ """ |
+ unique_unions = {} |
+ for union_type in union_types: |
+ cpp_type = union_type.cpp_type |
+ if cpp_type not in unique_unions.keys(): |
+ unique_unions[cpp_type] = { |
+ 'union_type': union_type, |
+ } |
+ if union_type.includes_nullable_type: |
+ unique_unions[cpp_type]['needs_ornull_converter'] = True |
+ return unique_unions |
+ |
+ def _generate_container_code(self, name, union_type_dict): |
+ """Generates a union type container into separate .h/.cpp files. |
+ Returns the path and its contents as a tuple. |
+ """ |
+ header_template = self.jinja_env.get_template('union_container.h') |
+ cpp_template = self.jinja_env.get_template('union_container.cpp') |
+ template_context = v8_union.container_context( |
+ union_type_dict['union_type'], self.info_provider.interfaces_info) |
template_context['code_generator'] = module_pyname |
- capitalized_component = self.target_component.capitalize() |
- template_context['header_filename'] = 'bindings/%s/v8/UnionTypes%s.h' % ( |
- self.target_component, capitalized_component) |
- template_context['macro_guard'] = 'UnionType%s_h' % capitalized_component |
+ template_context['needs_ornull_converter'] = ( |
+ union_type_dict.get('needs_ornull_converter')) |
+ |
+ header_text = header_template.render(template_context) |
+ cpp_text = cpp_template.render(template_context) |
+ header_path = posixpath.join(self.output_dir, '%s.h' % name) |
+ cpp_path = posixpath.join(self.output_dir, '%s.cpp' % name) |
+ return ( |
+ (header_path, header_text), |
+ (cpp_path, cpp_text), |
+ ) |
+ def _generate_aggregate_header(self, names): |
+ """Generates a header file which contains all union type container |
+ headers. |
+ FIXME: We might want to remove the aggregated header once we directly |
+ include necessary header files in Blink side. |
+ """ |
+ capitalized_component = self.target_component.capitalize() |
+ context = { |
+ 'code_generator': module_pyname, |
+ 'header_includes': sorted([ |
+ 'bindings/%s/v8/%s.h' % (self.target_component, name) |
+ for name in names]), |
+ 'macro_guard': 'UnionType%s_h' % capitalized_component, |
+ } |
# Add UnionTypesCore.h as a dependency when we generate modules union types |
# because we only generate union type containers which are used by both |
# core and modules in UnionTypesCore.h. |
# FIXME: This is an ad hoc workaround and we need a general way to |
# handle core <-> modules dependency. |
if self.target_component == 'modules': |
- template_context['header_includes'] = sorted( |
- template_context['header_includes'] + |
+ context['header_includes'] = sorted( |
+ context['header_includes'] + |
['bindings/core/v8/UnionTypesCore.h']) |
- |
- header_text = header_template.render(template_context) |
- cpp_text = cpp_template.render(template_context) |
+ template = self.jinja_env.get_template('union.h') |
+ header_text = template.render(context) |
header_path = posixpath.join(self.output_dir, |
'UnionTypes%s.h' % capitalized_component) |
+ return (header_path, header_text) |
+ |
+ def _generate_aggregate_cpp(self, names): |
+ """Generates a cpp file which contains all union type container |
+ implementations. We need this aggregated cpp file as the output of |
+ a GYP/GN rule. |
+ """ |
+ capitalized_component = self.target_component.capitalize() |
+ context = { |
+ 'code_generator': module_pyname, |
+ 'cpp_files': sorted([ |
+ 'bindings/%s/v8/%s.cpp' % (self.target_component, name) |
+ for name in names]), |
+ } |
+ template = self.jinja_env.get_template('union.cpp') |
+ cpp_text = template.render(context) |
cpp_path = posixpath.join(self.output_dir, |
'UnionTypes%s.cpp' % capitalized_component) |
- return ( |
- (header_path, header_text), |
- (cpp_path, cpp_text), |
- ) |
+ return (cpp_path, cpp_text) |
+ |
+ def generate_code(self): |
+ unique_unions = self._collect_unique_unions( |
+ self.info_provider.union_types) |
+ if not unique_unions: |
+ return () |
+ outputs = set() |
+ for name, union_type_dict in unique_unions.iteritems(): |
+ outputs.update(self._generate_container_code(name, union_type_dict)) |
+ |
+ outputs.add(self._generate_aggregate_header(unique_unions.keys())) |
+ outputs.add(self._generate_aggregate_cpp(unique_unions.keys())) |
+ return outputs |
def initialize_jinja_env(cache_dir): |