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): |