Chromium Code Reviews| Index: third_party/WebKit/Source/bindings/scripts/code_generator_web_agent_api.py |
| diff --git a/third_party/WebKit/Source/bindings/scripts/code_generator_web_agent_api.py b/third_party/WebKit/Source/bindings/scripts/code_generator_web_agent_api.py |
| index 89fa5e2ab6775daa0e37292c017a60aad66bb10c..7644b37b006ef1d389d043f90a0d8737c32f1075 100644 |
| --- a/third_party/WebKit/Source/bindings/scripts/code_generator_web_agent_api.py |
| +++ b/third_party/WebKit/Source/bindings/scripts/code_generator_web_agent_api.py |
| @@ -83,6 +83,56 @@ class TypeResolver(object): |
| return set(['platform/heap/Handle.h']) |
| +class MethodOverloadSplitter(object): |
| + """Because of union and optional types being used as arguments, some |
| + operations may result in more than one generated method. This class |
| + contains the logic for spliting an operation into multiple C++ overloads. |
| + """ |
| + |
| + def __init__(self, idl_operation): |
| + self.idl_operation = idl_operation |
| + |
| + def _update_argument_lists(self, argument_lists, idl_types): |
| + """Given a list of IdlTypes and an existing list of argument lists (yes, |
| + this is a list of lists), produces a next generation of the list of |
| + lists. This is the where the actual splitting into overloads happens. |
|
haraken
2017/03/18 16:30:17
the place where
dglazkov
2017/03/20 03:25:33
Fixed. Thanks! :)
|
| + """ |
| + result = [] |
| + for argument_list in argument_lists: |
| + for idl_type in idl_types: |
| + new_argument_list = list(argument_list) |
| + if idl_type is not None: |
| + new_argument_list.append(idl_type) |
| + result.append(new_argument_list) |
| + return result |
| + |
| + def _enumerate_argument_types(self, idl_argument): |
| + """Given an IdlArgument, returns a list of types that are included |
| + in this argument. If optional, the list will include a 'None'.""" |
| + argument_type = idl_argument.idl_type |
| + # TODO(dglazkov): What should we do with primitive nullable args? |
| + if (argument_type.is_nullable and |
| + argument_type.inner_type.is_primitive_type): |
| + raise ValueError('Primitive nullable types are not supported.') |
| + |
| + idl_types = [] |
| + if idl_argument.is_optional: |
| + idl_types.append(None) # None is used to convey optionality. |
| + if argument_type.is_union_type: |
| + idl_types = idl_types + argument_type.member_types |
| + else: |
| + idl_types.append(argument_type) |
| + return idl_types |
| + |
| + def split_into_overloads(self): |
|
haraken
2017/03/18 16:30:17
It would be helpful to describe a concrete example
dglazkov
2017/03/20 03:25:33
Sure thing! I added an explanation with an example
|
| + argument_lists = [[]] |
| + for idl_argument in self.idl_operation.arguments: |
| + idl_types = self._enumerate_argument_types(idl_argument) |
| + argument_lists = self._update_argument_lists(argument_lists, |
| + idl_types) |
| + return argument_lists |
| + |
| + |
| class InterfaceContextBuilder(object): |
| def __init__(self, code_generator, type_resolver): |
| self.result = {'code_generator': code_generator} |
| @@ -118,17 +168,35 @@ class InterfaceContextBuilder(object): |
| def add_operation(self, idl_operation): |
| if not idl_operation.name: |
| return |
| - self._ensure_list('methods').append( |
| - self.create_method(idl_operation)) |
| - self._ensure_set('cpp_includes').update( |
| - self.type_resolver.includes_from_definition(idl_operation)) |
| + overload_splitter = MethodOverloadSplitter(idl_operation) |
| + overloads = overload_splitter.split_into_overloads() |
| + argument_names = [argument.name for argument |
| + in idl_operation.arguments] |
| + for argument_types in overloads: |
| + arguments = [] |
| + for position, argument_type in enumerate(argument_types): |
| + arguments.append( |
| + self.create_argument(argument_names[position], |
| + argument_type)) |
| + self._ensure_list('methods').append( |
| + self.create_method(idl_operation, arguments)) |
| + self._ensure_set('cpp_includes').update( |
| + self.type_resolver.includes_from_definition(idl_operation)) |
| + |
| + def create_argument(self, argument_name, argument_type): |
| + name_converter = NameStyleConverter(argument_name) |
| + return { |
| + 'name': name_converter.to_snake_case(), |
| + 'type': argument_type.base_type, |
| + } |
| - def create_method(self, idl_operation): |
| - name = idl_operation.name |
| + def create_method(self, idl_operation, arguments): |
| + name_converter = NameStyleConverter(idl_operation.name) |
| return_type = self.type_resolver.type_from_definition(idl_operation) |
| return { |
| - 'name': name, |
| - 'return_type': return_type |
| + 'name': name_converter.to_upper_camel_case(), |
| + 'type': return_type, |
| + 'arguments': arguments |
| } |
| def create_attribute(self, idl_attribute): |
| @@ -136,7 +204,7 @@ class InterfaceContextBuilder(object): |
| return_type = self.type_resolver.type_from_definition(idl_attribute) |
| return { |
| 'name': name, |
| - 'return_type': return_type |
| + 'type': return_type |
| } |
| def build(self): |