Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(153)

Side by Side Diff: third_party/WebKit/Source/bindings/scripts/code_generator_web_agent_api.py

Issue 2703653004: [WebAgentsAPI]: Start adding support for method arguments. (Closed)
Patch Set: Comments addressed. Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | third_party/WebKit/Source/bindings/scripts/code_generator_web_agent_api_test.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright 2016 The Chromium Authors. All rights reserved. 1 # Copyright 2016 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 # pylint: disable=import-error,print-statement,relative-import 5 # pylint: disable=import-error,print-statement,relative-import
6 6
7 """Generates Web Agent API bindings. 7 """Generates Web Agent API bindings.
8 8
9 The Web Agent API bindings provide a stable, IDL-generated interface for the 9 The Web Agent API bindings provide a stable, IDL-generated interface for the
10 Web Agents. 10 Web Agents.
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 76
77 def type_from_definition(self, idl_definition): 77 def type_from_definition(self, idl_definition):
78 # TODO(dglazkov): The output of this method must be a reasonable C++ 78 # TODO(dglazkov): The output of this method must be a reasonable C++
79 # type that can be used directly in the jinja2 template. 79 # type that can be used directly in the jinja2 template.
80 return idl_definition.idl_type.base_type 80 return idl_definition.idl_type.base_type
81 81
82 def base_class_includes(self): 82 def base_class_includes(self):
83 return set(['platform/heap/Handle.h']) 83 return set(['platform/heap/Handle.h'])
84 84
85 85
86 class MethodOverloadSplitter(object):
87 """Because of union and optional types being used as arguments, some
88 operations may result in more than one generated method. This class
89 contains the logic for spliting an operation into multiple C++ overloads.
90 """
91
92 def __init__(self, idl_operation):
93 self.idl_operation = idl_operation
94
95 def _update_argument_lists(self, argument_lists, idl_types):
96 """Given a list of IdlTypes and an existing list of argument lists (yes,
97 this is a list of lists), produces a next generation of the list of
98 lists. This is where the actual splitting into overloads happens.
99 """
100 result = []
101 for argument_list in argument_lists:
102 for idl_type in idl_types:
103 new_argument_list = list(argument_list)
104 if idl_type is not None:
105 new_argument_list.append(idl_type)
106 result.append(new_argument_list)
107 return result
108
109 def _enumerate_argument_types(self, idl_argument):
110 """Given an IdlArgument, returns a list of types that are included
111 in this argument. If optional, the list will include a 'None'."""
112 argument_type = idl_argument.idl_type
113 # TODO(dglazkov): What should we do with primitive nullable args?
114 if (argument_type.is_nullable and
115 argument_type.inner_type.is_primitive_type):
116 raise ValueError('Primitive nullable types are not supported.')
117
118 idl_types = []
119 if idl_argument.is_optional:
120 idl_types.append(None) # None is used to convey optionality.
121 if argument_type.is_union_type:
122 idl_types = idl_types + argument_type.member_types
123 else:
124 idl_types.append(argument_type)
125 return idl_types
126
127 def split_into_overloads(self):
128 """Splits an operation into one or more overloads that correctly reflect
129 the WebIDL semantics of the operation arguments. For example,
130 running this method on an IdlOperation that represents this WebIDL
131 definition:
132
133 void addEventListener(
134 DOMString type,
135 EventListener? listener,
136 optional (AddEventListenerOptions or boolean) options)
137
138 will produce a list of 3 argument lists:
139
140 1) [DOMString, EventListener], since the third argument is optional,
141 2) [DOMString, EventListener, AddEventListenerOptions], since the
142 third argument is a union type with AddEventListenerOptions as
143 one of its member types, and
144 3) [DOMString, EventListener, boolean], since the other union member
145 type of the third argument is boolean.
146
147 This example is also captured as test in
148 MethodOverloadSplitterTest.test_split_add_event_listener.
149 """
150
151 argument_lists = [[]]
152 for idl_argument in self.idl_operation.arguments:
153 idl_types = self._enumerate_argument_types(idl_argument)
154 argument_lists = self._update_argument_lists(argument_lists,
155 idl_types)
156 return argument_lists
157
158
86 class InterfaceContextBuilder(object): 159 class InterfaceContextBuilder(object):
87 def __init__(self, code_generator, type_resolver): 160 def __init__(self, code_generator, type_resolver):
88 self.result = {'code_generator': code_generator} 161 self.result = {'code_generator': code_generator}
89 self.type_resolver = type_resolver 162 self.type_resolver = type_resolver
90 163
91 def set_class_name(self, class_name): 164 def set_class_name(self, class_name):
92 converter = NameStyleConverter(class_name) 165 converter = NameStyleConverter(class_name)
93 self.result['class_name'] = converter.to_all_cases() 166 self.result['class_name'] = converter.to_all_cases()
94 self._ensure_set('cpp_includes').update( 167 self._ensure_set('cpp_includes').update(
95 self.type_resolver.includes_from_interface(class_name)) 168 self.type_resolver.includes_from_interface(class_name))
(...skipping 15 matching lines...) Expand all
111 184
112 def add_attribute(self, idl_attribute): 185 def add_attribute(self, idl_attribute):
113 self._ensure_list('attributes').append( 186 self._ensure_list('attributes').append(
114 self.create_attribute(idl_attribute)) 187 self.create_attribute(idl_attribute))
115 self._ensure_set('cpp_includes').update( 188 self._ensure_set('cpp_includes').update(
116 self.type_resolver.includes_from_definition(idl_attribute)) 189 self.type_resolver.includes_from_definition(idl_attribute))
117 190
118 def add_operation(self, idl_operation): 191 def add_operation(self, idl_operation):
119 if not idl_operation.name: 192 if not idl_operation.name:
120 return 193 return
121 self._ensure_list('methods').append( 194 overload_splitter = MethodOverloadSplitter(idl_operation)
122 self.create_method(idl_operation)) 195 overloads = overload_splitter.split_into_overloads()
123 self._ensure_set('cpp_includes').update( 196 argument_names = [argument.name for argument
124 self.type_resolver.includes_from_definition(idl_operation)) 197 in idl_operation.arguments]
198 for argument_types in overloads:
199 arguments = []
200 for position, argument_type in enumerate(argument_types):
201 arguments.append(
202 self.create_argument(argument_names[position],
203 argument_type))
204 self._ensure_list('methods').append(
205 self.create_method(idl_operation, arguments))
206 self._ensure_set('cpp_includes').update(
207 self.type_resolver.includes_from_definition(idl_operation))
125 208
126 def create_method(self, idl_operation): 209 def create_argument(self, argument_name, argument_type):
127 name = idl_operation.name 210 name_converter = NameStyleConverter(argument_name)
211 return {
212 'name': name_converter.to_snake_case(),
213 'type': argument_type.base_type,
214 }
215
216 def create_method(self, idl_operation, arguments):
217 name_converter = NameStyleConverter(idl_operation.name)
128 return_type = self.type_resolver.type_from_definition(idl_operation) 218 return_type = self.type_resolver.type_from_definition(idl_operation)
129 return { 219 return {
130 'name': name, 220 'name': name_converter.to_upper_camel_case(),
131 'return_type': return_type 221 'type': return_type,
222 'arguments': arguments
132 } 223 }
133 224
134 def create_attribute(self, idl_attribute): 225 def create_attribute(self, idl_attribute):
135 name = idl_attribute.name 226 name = idl_attribute.name
136 return_type = self.type_resolver.type_from_definition(idl_attribute) 227 return_type = self.type_resolver.type_from_definition(idl_attribute)
137 return { 228 return {
138 'name': name, 229 'name': name,
139 'return_type': return_type 230 'type': return_type
140 } 231 }
141 232
142 def build(self): 233 def build(self):
143 return self.result 234 return self.result
144 235
145 236
146 class CodeGeneratorWebAgentAPI(CodeGeneratorBase): 237 class CodeGeneratorWebAgentAPI(CodeGeneratorBase):
147 def __init__(self, info_provider, cache_dir, output_dir): 238 def __init__(self, info_provider, cache_dir, output_dir):
148 CodeGeneratorBase.__init__(self, MODULE_PYNAME, info_provider, 239 CodeGeneratorBase.__init__(self, MODULE_PYNAME, info_provider,
149 cache_dir, output_dir) 240 cache_dir, output_dir)
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
181 272
182 # TODO(dglazkov): Implement dictionaries 273 # TODO(dglazkov): Implement dictionaries
183 if definition_name not in definitions.interfaces: 274 if definition_name not in definitions.interfaces:
184 return None 275 return None
185 276
186 interface = definitions.interfaces[definition_name] 277 interface = definitions.interfaces[definition_name]
187 if WEB_AGENT_API_IDL_ATTRIBUTE not in interface.extended_attributes: 278 if WEB_AGENT_API_IDL_ATTRIBUTE not in interface.extended_attributes:
188 return None 279 return None
189 280
190 return self.generate_interface_code(interface) 281 return self.generate_interface_code(interface)
OLDNEW
« no previous file with comments | « no previous file | third_party/WebKit/Source/bindings/scripts/code_generator_web_agent_api_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698