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

Side by Side Diff: Source/bindings/scripts/v8_interface.py

Issue 618373003: [bindings] partial interfaces should not violate componentization (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Fixed http/tests/serviceworker/fetch\* regression Created 6 years, 2 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 | Annotate | Revision Log
OLDNEW
1 # Copyright (C) 2013 Google Inc. All rights reserved. 1 # Copyright (C) 2013 Google Inc. All rights reserved.
2 # coding=utf-8 2 # coding=utf-8
3 # 3 #
4 # Redistribution and use in source and binary forms, with or without 4 # Redistribution and use in source and binary forms, with or without
5 # modification, are permitted provided that the following conditions are 5 # modification, are permitted provided that the following conditions are
6 # met: 6 # met:
7 # 7 #
8 # * Redistributions of source code must retain the above copyright 8 # * Redistributions of source code must retain the above copyright
9 # notice, this list of conditions and the following disclaimer. 9 # notice, this list of conditions and the following disclaimer.
10 # * Redistributions in binary form must reproduce the above 10 # * Redistributions in binary form must reproduce the above
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 'wtf/GetPtr.h', 70 'wtf/GetPtr.h',
71 'wtf/RefPtr.h', 71 'wtf/RefPtr.h',
72 ]) 72 ])
73 73
74 74
75 def interface_context(interface): 75 def interface_context(interface):
76 includes.clear() 76 includes.clear()
77 includes.update(INTERFACE_CPP_INCLUDES) 77 includes.update(INTERFACE_CPP_INCLUDES)
78 header_includes = set(INTERFACE_H_INCLUDES) 78 header_includes = set(INTERFACE_H_INCLUDES)
79 79
80 parent_interface = interface.parent 80 if not interface.is_partial:
haraken 2014/10/09 04:24:00 Avoid 'if not ... else ...'. Use 'if ... else ...'
tasak 2014/10/10 07:52:22 Done.
81 if parent_interface: 81 parent_interface = interface.parent
82 header_includes.update(v8_types.includes_for_interface(parent_interface) ) 82 if parent_interface:
83 header_includes.update(v8_types.includes_for_interface(parent_interf ace))
84
85 is_document = inherits_interface(interface.name, 'Document')
86 is_event_target = inherits_interface(interface.name, 'EventTarget')
87 else:
88 # A partial interface definition cannot specify that the interface inher its
89 # from another interface. Inheritance must be specified on the original interface
90 # definition.
91 parent_interface = None
92 is_audio_buffer = False
93 is_document = False
94 is_event_target = False
95
96 # partial interface needs the definition of its original interface.
97 includes.add('bindings/core/v8/V8%s.h' % interface.name)
98
83 extended_attributes = interface.extended_attributes 99 extended_attributes = interface.extended_attributes
84 100
85 # [ActiveDOMObject] 101 # [ActiveDOMObject]
86 is_active_dom_object = 'ActiveDOMObject' in extended_attributes 102 is_active_dom_object = 'ActiveDOMObject' in extended_attributes
87 103
88 # [CheckSecurity] 104 # [CheckSecurity]
89 is_check_security = 'CheckSecurity' in extended_attributes 105 is_check_security = 'CheckSecurity' in extended_attributes
90 if is_check_security: 106 if is_check_security:
91 includes.add('bindings/core/v8/BindingSecurity.h') 107 includes.add('bindings/core/v8/BindingSecurity.h')
92 108
93 # [DependentLifetime] 109 # [DependentLifetime]
94 is_dependent_lifetime = 'DependentLifetime' in extended_attributes 110 is_dependent_lifetime = 'DependentLifetime' in extended_attributes
95 111
96 # [Iterable] 112 # [Iterable]
97 iterator_method = None 113 iterator_method = None
98 if 'Iterable' in extended_attributes: 114 if 'Iterable' in extended_attributes and not interface.is_partial:
haraken 2014/10/09 04:24:00 Add a FIXME to support Iterable in partial interfa
tasak 2014/10/10 07:52:22 Done.
99 iterator_operation = IdlOperation(interface.idl_name) 115 iterator_operation = IdlOperation(interface.idl_name)
100 iterator_operation.name = 'iterator' 116 iterator_operation.name = 'iterator'
101 iterator_operation.idl_type = IdlType('Iterator') 117 iterator_operation.idl_type = IdlType('Iterator')
102 iterator_operation.extended_attributes['RaisesException'] = None 118 iterator_operation.extended_attributes['RaisesException'] = None
103 iterator_operation.extended_attributes['CallWith'] = 'ScriptState' 119 iterator_operation.extended_attributes['CallWith'] = 'ScriptState'
104 iterator_method = v8_methods.method_context(interface, 120 iterator_method = v8_methods.method_context(interface,
105 iterator_operation) 121 iterator_operation)
106 122
107 # [MeasureAs] 123 # [MeasureAs]
108 is_measure_as = 'MeasureAs' in extended_attributes 124 is_measure_as = 'MeasureAs' in extended_attributes
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 interface.name != 'EventTarget'), 168 interface.name != 'EventTarget'),
153 'has_custom_legacy_call_as_function': has_extended_attribute_value(inter face, 'Custom', 'LegacyCallAsFunction'), # [Custom=LegacyCallAsFunction] 169 'has_custom_legacy_call_as_function': has_extended_attribute_value(inter face, 'Custom', 'LegacyCallAsFunction'), # [Custom=LegacyCallAsFunction]
154 'has_custom_to_v8': has_extended_attribute_value(interface, 'Custom', 'T oV8'), # [Custom=ToV8] 170 'has_custom_to_v8': has_extended_attribute_value(interface, 'Custom', 'T oV8'), # [Custom=ToV8]
155 'has_custom_wrap': has_extended_attribute_value(interface, 'Custom', 'Wr ap'), # [Custom=Wrap] 171 'has_custom_wrap': has_extended_attribute_value(interface, 'Custom', 'Wr ap'), # [Custom=Wrap]
156 'has_visit_dom_wrapper': has_visit_dom_wrapper, 172 'has_visit_dom_wrapper': has_visit_dom_wrapper,
157 'header_includes': header_includes, 173 'header_includes': header_includes,
158 'interface_name': interface.name, 174 'interface_name': interface.name,
159 'is_active_dom_object': is_active_dom_object, 175 'is_active_dom_object': is_active_dom_object,
160 'is_check_security': is_check_security, 176 'is_check_security': is_check_security,
161 'is_dependent_lifetime': is_dependent_lifetime, 177 'is_dependent_lifetime': is_dependent_lifetime,
162 'is_event_target': inherits_interface(interface.name, 'EventTarget'), 178 'is_document': is_document,
179 'is_event_target': is_event_target,
163 'is_exception': interface.is_exception, 180 'is_exception': interface.is_exception,
164 'is_node': inherits_interface(interface.name, 'Node'), 181 'is_node': inherits_interface(interface.name, 'Node'),
165 'is_script_wrappable': is_script_wrappable, 182 'is_script_wrappable': is_script_wrappable,
166 'iterator_method': iterator_method, 183 'iterator_method': iterator_method,
167 'lifetime': 'Dependent' 184 'lifetime': 'Dependent'
168 if (has_visit_dom_wrapper or 185 if (has_visit_dom_wrapper or
169 is_active_dom_object or 186 is_active_dom_object or
170 is_dependent_lifetime) 187 is_dependent_lifetime)
171 else 'Independent', 188 else 'Independent',
189 'is_partial': interface.is_partial,
190 'has_partial_interface': len(interface.partial_interfaces) > 0,
172 'measure_as': v8_utilities.measure_as(interface), # [MeasureAs] 191 'measure_as': v8_utilities.measure_as(interface), # [MeasureAs]
173 'parent_interface': parent_interface, 192 'parent_interface': parent_interface,
174 'pass_cpp_type': cpp_template_type( 193 'pass_cpp_type': cpp_template_type(
175 cpp_ptr_type('PassRefPtr', 'RawPtr', this_gc_type), 194 cpp_ptr_type('PassRefPtr', 'RawPtr', this_gc_type),
176 cpp_name(interface)), 195 cpp_name(interface)),
177 'reachable_node_function': reachable_node_function, 196 'reachable_node_function': reachable_node_function,
178 'runtime_enabled_function': runtime_enabled_function_name(interface), # [RuntimeEnabled] 197 'runtime_enabled_function': runtime_enabled_function_name(interface), # [RuntimeEnabled]
179 'set_wrapper_reference_to_list': set_wrapper_reference_to_list, 198 'set_wrapper_reference_to_list': set_wrapper_reference_to_list,
180 'v8_class': v8_utilities.v8_class_name(interface), 199 'v8_class': v8_utilities.v8_class_name(interface),
181 'wrapper_class_id': wrapper_class_id, 200 'wrapper_class_id': wrapper_class_id,
182 } 201 }
183 202
184 # Constructors 203 # Constructors
185 constructors = [constructor_context(interface, constructor) 204 if not interface.is_partial:
haraken 2014/10/09 04:24:00 Use if ... else ....
tasak 2014/10/10 07:52:22 Done.
186 for constructor in interface.constructors 205 update_interface_constructor_context(interface, context)
187 # FIXME: shouldn't put named constructors with constructors 206 else:
188 # (currently needed for Perl compatibility) 207 update_partial_interface_constructor_context(interface, context)
189 # Handle named constructors separately
190 if constructor.name == 'Constructor']
191 if len(constructors) > 1:
192 context['constructor_overloads'] = overloads_context(constructors)
193
194 # [CustomConstructor]
195 custom_constructors = [{ # Only needed for computing interface length
196 'number_of_required_arguments':
197 number_of_required_arguments(constructor),
198 } for constructor in interface.custom_constructors]
199
200 # [EventConstructor]
201 has_event_constructor = 'EventConstructor' in extended_attributes
202 any_type_attributes = [attribute for attribute in interface.attributes
203 if attribute.idl_type.name == 'Any']
204 if has_event_constructor:
205 includes.add('bindings/core/v8/Dictionary.h')
206 if any_type_attributes:
207 includes.add('bindings/core/v8/SerializedScriptValue.h')
208
209 # [NamedConstructor]
210 named_constructor = named_constructor_context(interface)
211
212 if (constructors or custom_constructors or has_event_constructor or
213 named_constructor):
214 includes.add('bindings/core/v8/V8ObjectConstructor.h')
215 includes.add('core/frame/LocalDOMWindow.h')
216
217 context.update({
218 'any_type_attributes': any_type_attributes,
219 'constructors': constructors,
220 'has_custom_constructor': bool(custom_constructors),
221 'has_event_constructor': has_event_constructor,
222 'interface_length':
223 interface_length(interface, constructors + custom_constructors),
224 'is_constructor_raises_exception': extended_attributes.get('RaisesExcept ion') == 'Constructor', # [RaisesException=Constructor]
225 'named_constructor': named_constructor,
226 })
227 208
228 constants = [constant_context(constant) for constant in interface.constants] 209 constants = [constant_context(constant) for constant in interface.constants]
229 210
230 special_getter_constants = [] 211 special_getter_constants = []
231 runtime_enabled_constants = [] 212 runtime_enabled_constants = []
232 constant_configuration_constants = [] 213 constant_configuration_constants = []
233 214
234 for constant in constants: 215 for constant in constants:
235 if constant['measure_as'] or constant['deprecate_as']: 216 if constant['measure_as'] or constant['deprecate_as']:
236 special_getter_constants.append(constant) 217 special_getter_constants.append(constant)
(...skipping 27 matching lines...) Expand all
264 attribute['runtime_enabled_function'] or 245 attribute['runtime_enabled_function'] or
265 attribute['per_context_enabled_function']) 246 attribute['per_context_enabled_function'])
266 and attribute['should_be_exposed_to_script'] 247 and attribute['should_be_exposed_to_script']
267 for attribute in attributes), 248 for attribute in attributes),
268 'has_conditional_attributes': any(attribute['per_context_enabled_functio n'] or attribute['exposed_test'] for attribute in attributes), 249 'has_conditional_attributes': any(attribute['per_context_enabled_functio n'] or attribute['exposed_test'] for attribute in attributes),
269 'has_constructor_attributes': any(attribute['constructor_type'] for attr ibute in attributes), 250 'has_constructor_attributes': any(attribute['constructor_type'] for attr ibute in attributes),
270 'has_replaceable_attributes': any(attribute['is_replaceable'] for attrib ute in attributes), 251 'has_replaceable_attributes': any(attribute['is_replaceable'] for attrib ute in attributes),
271 }) 252 })
272 253
273 # Methods 254 # Methods
274 methods = [v8_methods.method_context(interface, method) 255 methods = []
275 for method in interface.operations 256 if interface.original_interface:
276 if method.name] # Skip anonymous special operations (methods) 257 for operation in interface.original_interface.operations:
277 compute_method_overloads_context(methods) 258 if not operation.name:
259 continue
260 method = v8_methods.method_context(interface, operation)
261 method['visible'] = False
262 methods.append(method)
263 methods.extend([v8_methods.method_context(interface, method)
264 for method in interface.operations
265 if method.name]) # Skip anonymous special operations (metho ds)
266 if interface.partial_interfaces:
267 assert len(interface.partial_interfaces) == len(set(interface.partial_in terfaces))
268 for partial_interface in interface.partial_interfaces:
269 for operation in partial_interface.operations:
270 if not operation.name:
271 continue
272 partial_method = v8_methods.method_context(interface, operation)
273 partial_method['visible'] = False
274 methods.append(partial_method)
275 compute_method_overloads_context(interface, methods)
278 276
279 # Stringifier 277 # Stringifier
280 if interface.stringifier: 278 if interface.stringifier:
281 stringifier = interface.stringifier 279 stringifier = interface.stringifier
282 method = IdlOperation(interface.idl_name) 280 method = IdlOperation(interface.idl_name)
283 method.name = 'toString' 281 method.name = 'toString'
284 method.idl_type = IdlType('DOMString') 282 method.idl_type = IdlType('DOMString')
285 method.extended_attributes.update(stringifier.extended_attributes) 283 method.extended_attributes.update(stringifier.extended_attributes)
286 if stringifier.attribute: 284 if stringifier.attribute:
287 method.extended_attributes['ImplementedAs'] = stringifier.attribute. name 285 method.extended_attributes['ImplementedAs'] = stringifier.attribute. name
288 elif stringifier.operation: 286 elif stringifier.operation:
289 method.extended_attributes['ImplementedAs'] = stringifier.operation. name 287 method.extended_attributes['ImplementedAs'] = stringifier.operation. name
290 methods.append(v8_methods.method_context(interface, method)) 288 methods.append(v8_methods.method_context(interface, method))
291 289
292 conditionally_enabled_methods = [] 290 conditionally_enabled_methods = []
293 custom_registration_methods = [] 291 custom_registration_methods = []
294 method_configuration_methods = [] 292 method_configuration_methods = []
295 293
296 for method in methods: 294 for method in methods:
297 # Skip all but one method in each set of overloaded methods. 295 # Skip all but one method in each set of overloaded methods.
298 if 'overload_index' in method and 'overloads' not in method: 296 if 'overload_index' in method and 'overloads' not in method:
299 continue 297 continue
300 298
301 if 'overloads' in method: 299 if 'overloads' in method:
302 overloads = method['overloads'] 300 overloads = method['overloads']
301 if not overloads['visible']:
302 continue
303 # original interface will register instead of partial interface.
304 if overloads['partial_overloads'] and interface.is_partial:
305 continue
303 per_context_enabled_function = overloads['per_context_enabled_functi on_all'] 306 per_context_enabled_function = overloads['per_context_enabled_functi on_all']
304 conditionally_exposed_function = overloads['exposed_test_all'] 307 conditionally_exposed_function = overloads['exposed_test_all']
305 runtime_enabled_function = overloads['runtime_enabled_function_all'] 308 runtime_enabled_function = overloads['runtime_enabled_function_all']
306 has_custom_registration = overloads['has_custom_registration_all'] 309 has_custom_registration = overloads['has_custom_registration_all']
307 else: 310 else:
311 if not method['visible']:
312 continue
308 per_context_enabled_function = method['per_context_enabled_function' ] 313 per_context_enabled_function = method['per_context_enabled_function' ]
309 conditionally_exposed_function = method['exposed_test'] 314 conditionally_exposed_function = method['exposed_test']
310 runtime_enabled_function = method['runtime_enabled_function'] 315 runtime_enabled_function = method['runtime_enabled_function']
311 has_custom_registration = method['has_custom_registration'] 316 has_custom_registration = method['has_custom_registration']
312 317
313 if per_context_enabled_function or conditionally_exposed_function: 318 if per_context_enabled_function or conditionally_exposed_function:
314 conditionally_enabled_methods.append(method) 319 conditionally_enabled_methods.append(method)
315 continue 320 continue
316 if runtime_enabled_function or has_custom_registration: 321 if runtime_enabled_function or has_custom_registration:
317 custom_registration_methods.append(method) 322 custom_registration_methods.append(method)
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
352 'indexed_property_deleter': indexed_property_deleter(interface), 357 'indexed_property_deleter': indexed_property_deleter(interface),
353 'is_override_builtins': 'OverrideBuiltins' in extended_attributes, 358 'is_override_builtins': 'OverrideBuiltins' in extended_attributes,
354 'named_property_getter': named_property_getter(interface), 359 'named_property_getter': named_property_getter(interface),
355 'named_property_setter': named_property_setter(interface), 360 'named_property_setter': named_property_setter(interface),
356 'named_property_deleter': named_property_deleter(interface), 361 'named_property_deleter': named_property_deleter(interface),
357 }) 362 })
358 363
359 return context 364 return context
360 365
361 366
367 def update_interface_constructor_context(interface, context):
368 constructors = [constructor_context(interface, constructor)
369 for constructor in interface.constructors
370 # FIXME: shouldn't put named constructors with constructors
371 # (currently needed for Perl compatibility)
372 # Handle named constructors separately
373 if constructor.name == 'Constructor']
374 if len(constructors) > 1:
375 context['constructor_overloads'] = overloads_context(interface, construc tors)
376
377 # [CustomConstructor]
378 custom_constructors = [{ # Only needed for computing interface length
379 'number_of_required_arguments':
380 number_of_required_arguments(constructor),
381 } for constructor in interface.custom_constructors]
382
383 # [EventConstructor]
384 has_event_constructor = 'EventConstructor' in interface.extended_attributes
385 any_type_attributes = [attribute for attribute in interface.attributes
386 if attribute.idl_type.name == 'Any']
387 if has_event_constructor:
388 includes.add('bindings/core/v8/Dictionary.h')
389 if any_type_attributes:
390 includes.add('bindings/core/v8/SerializedScriptValue.h')
391
392 # [NamedConstructor]
393 named_constructor = named_constructor_context(interface)
394
395 if constructors or custom_constructors or has_event_constructor or named_con structor:
396 includes.add('bindings/core/v8/V8ObjectConstructor.h')
397 includes.add('core/frame/LocalDOMWindow.h')
398
399 context.update({
400 'any_type_attributes': any_type_attributes,
401 'constructors': constructors,
402 'has_custom_constructor': bool(custom_constructors),
403 'has_event_constructor': has_event_constructor,
404 'interface_length':
405 interface_length(interface, constructors + custom_constructors),
406 'is_constructor_raises_exception':
407 interface.extended_attributes.get('RaisesException') == 'Constructor ', # [RaisesException=Constructor]
408 'named_constructor': named_constructor,
409 })
410
411
412 def update_partial_interface_constructor_context(interface, context):
haraken 2014/10/09 04:24:00 Why can we share the code with update_interface_co
tasak 2014/10/10 07:52:22 Done.
413 # [Constructor], [NamedConstructor] must not be specified on partial interfa ce
haraken 2014/10/09 04:24:00 Can we raise an exception if this happens?
tasak 2014/10/10 07:52:22 Done.
414 # definitions.
415 any_type_attributes = [attribute for attribute in interface.attributes
416 if attribute.idl_type.name == 'Any']
417 context.update({
418 'any_type_attributes': any_type_attributes,
419 'constructors': [],
420 'has_custom_constructor': False,
421 'has_event_constructor': False,
422 'interface_length': 0,
423 'is_constructor_raises_exception': False,
424 'named_constructor': [],
425 })
426
427
362 # [DeprecateAs], [Reflect], [RuntimeEnabled] 428 # [DeprecateAs], [Reflect], [RuntimeEnabled]
363 def constant_context(constant): 429 def constant_context(constant):
364 extended_attributes = constant.extended_attributes 430 extended_attributes = constant.extended_attributes
365 return { 431 return {
366 'cpp_class': extended_attributes.get('PartialInterfaceImplementedAs'), 432 'cpp_class': extended_attributes.get('PartialInterfaceImplementedAs'),
367 'deprecate_as': v8_utilities.deprecate_as(constant), # [DeprecateAs] 433 'deprecate_as': v8_utilities.deprecate_as(constant), # [DeprecateAs]
368 'idl_type': constant.idl_type.name, 434 'idl_type': constant.idl_type.name,
369 'measure_as': v8_utilities.measure_as(constant), # [MeasureAs] 435 'measure_as': v8_utilities.measure_as(constant), # [MeasureAs]
370 'name': constant.name, 436 'name': constant.name,
371 # FIXME: use 'reflected_name' as correct 'name' 437 # FIXME: use 'reflected_name' as correct 'name'
372 'reflected_name': extended_attributes.get('Reflect', constant.name), 438 'reflected_name': extended_attributes.get('Reflect', constant.name),
373 'runtime_enabled_function': runtime_enabled_function_name(constant), 439 'runtime_enabled_function': runtime_enabled_function_name(constant),
374 'value': constant.value, 440 'value': constant.value,
375 } 441 }
376 442
377 443
378 ################################################################################ 444 ################################################################################
379 # Overloads 445 # Overloads
380 ################################################################################ 446 ################################################################################
381 447
382 def compute_method_overloads_context(methods): 448 def compute_method_overloads_context(interface, methods):
383 # Regular methods 449 # Regular methods
384 compute_method_overloads_context_by_type([method for method in methods 450 compute_method_overloads_context_by_type(
385 if not method['is_static']]) 451 interface, [method for method in methods if not method['is_static']])
386 # Static methods 452 # Static methods
387 compute_method_overloads_context_by_type([method for method in methods 453 compute_method_overloads_context_by_type(
388 if method['is_static']]) 454 interface, [method for method in methods if method['is_static']])
389 455
390 456
391 def compute_method_overloads_context_by_type(methods): 457 def compute_method_overloads_context_by_type(interface, methods):
392 """Computes |method.overload*| template values. 458 """Computes |method.overload*| template values.
393 459
394 Called separately for static and non-static (regular) methods, 460 Called separately for static and non-static (regular) methods,
395 as these are overloaded separately. 461 as these are overloaded separately.
396 Modifies |method| in place for |method| in |methods|. 462 Modifies |method| in place for |method| in |methods|.
397 Doesn't change the |methods| list itself (only the values, i.e. individual 463 Doesn't change the |methods| list itself (only the values, i.e. individual
398 methods), so ok to treat these separately. 464 methods), so ok to treat these separately.
399 """ 465 """
400 # Add overload information only to overloaded methods, so template code can 466 # Add overload information only to overloaded methods, so template code can
401 # easily verify if a function is overloaded 467 # easily verify if a function is overloaded
402 for name, overloads in method_overloads_by_name(methods): 468 for name, overloads in method_overloads_by_name(methods):
403 # Resolution function is generated after last overloaded function; 469 # Resolution function is generated after last overloaded function;
404 # package necessary information into |method.overloads| for that method. 470 # package necessary information into |method.overloads| for that method.
405 overloads[-1]['overloads'] = overloads_context(overloads) 471 overloads[-1]['overloads'] = overloads_context(interface, overloads)
406 overloads[-1]['overloads']['name'] = name 472 overloads[-1]['overloads']['name'] = name
407 473
408 474
409 def method_overloads_by_name(methods): 475 def method_overloads_by_name(methods):
410 """Returns generator of overloaded methods by name: [name, [method]]""" 476 """Returns generator of overloaded methods by name: [name, [method]]"""
411 # Filter to only methods that are actually overloaded 477 # Filter to only methods that are actually overloaded
412 method_counts = Counter(method['name'] for method in methods) 478 method_counts = Counter(method['name'] for method in methods)
413 overloaded_method_names = set(name 479 overloaded_method_names = set(name
414 for name, count in method_counts.iteritems() 480 for name, count in method_counts.iteritems()
415 if count > 1) 481 if count > 1)
416 overloaded_methods = [method for method in methods 482 overloaded_methods = [method for method in methods
417 if method['name'] in overloaded_method_names] 483 if method['name'] in overloaded_method_names]
418 484
419 # Group by name (generally will be defined together, but not necessarily) 485 # Group by name (generally will be defined together, but not necessarily)
420 return sort_and_groupby(overloaded_methods, itemgetter('name')) 486 return sort_and_groupby(overloaded_methods, itemgetter('name'))
421 487
422 488
423 def overloads_context(overloads): 489 def overloads_context(interface, overloads):
424 """Returns |overloads| template values for a single name. 490 """Returns |overloads| template values for a single name.
425 491
426 Sets |method.overload_index| in place for |method| in |overloads| 492 Sets |method.overload_index| in place for |method| in |overloads|
427 and returns dict of overall overload template values. 493 and returns dict of overall overload template values.
428 """ 494 """
495 # partial overloads breaks this assumption.
429 assert len(overloads) > 1 # only apply to overloaded names 496 assert len(overloads) > 1 # only apply to overloaded names
430 for index, method in enumerate(overloads, 1): 497 for index, method in enumerate(overloads, 1):
431 method['overload_index'] = index 498 method['overload_index'] = index
432 499
433 effective_overloads_by_length = effective_overload_set_by_length(overloads) 500 effective_overloads_by_length = effective_overload_set_by_length(overloads)
434 lengths = [length for length, _ in effective_overloads_by_length] 501 lengths = [length for length, _ in effective_overloads_by_length]
435 name = overloads[0].get('name', '<constructor>') 502 name = overloads[0].get('name', '<constructor>')
436 503
437 # Check and fail if all overloads with the shortest acceptable arguments 504 # Check and fail if all overloads with the shortest acceptable arguments
438 # list are runtime enabled, since we would otherwise set 'length' on the 505 # list are runtime enabled, since we would otherwise set 'length' on the
(...skipping 20 matching lines...) Expand all
459 raise ValueError('Overloads of %s have conflicting extended attr ibute %s' 526 raise ValueError('Overloads of %s have conflicting extended attr ibute %s'
460 % (name, extended_attribute)) 527 % (name, extended_attribute))
461 528
462 # Check and fail if overloads disagree about whether the return type 529 # Check and fail if overloads disagree about whether the return type
463 # is a Promise or not. 530 # is a Promise or not.
464 promise_overload_count = sum(1 for method in overloads if method.get('idl_ty pe') == 'Promise') 531 promise_overload_count = sum(1 for method in overloads if method.get('idl_ty pe') == 'Promise')
465 if promise_overload_count not in (0, len(overloads)): 532 if promise_overload_count not in (0, len(overloads)):
466 raise ValueError('Overloads of %s have conflicting Promise/non-Promise t ypes' 533 raise ValueError('Overloads of %s have conflicting Promise/non-Promise t ypes'
467 % (name)) 534 % (name))
468 535
536 overloads_visibles = set([method.get('visible', True) for method in overload s])
537 if len(overloads_visibles) > 1:
538 overloads_visible = True
539 partial_overloads = True
540 else:
541 overloads_visible = overloads_visibles.pop()
542 partial_overloads = False
543
469 return { 544 return {
470 'deprecate_all_as': common_value(overloads, 'deprecate_as'), # [Depreca teAs] 545 'deprecate_all_as': common_value(overloads, 'deprecate_as'), # [Depreca teAs]
471 'exposed_test_all': common_value(overloads, 'exposed_test'), # [Exposed ] 546 'exposed_test_all': common_value(overloads, 'exposed_test'), # [Exposed ]
472 'has_custom_registration_all': common_value(overloads, 'has_custom_regis tration'), 547 'has_custom_registration_all': common_value(overloads, 'has_custom_regis tration'),
473 'length_tests_methods': length_tests_methods(effective_overloads_by_leng th), 548 'length_tests_methods': length_tests_methods(effective_overloads_by_leng th),
474 # 1. Let maxarg be the length of the longest type list of the 549 # 1. Let maxarg be the length of the longest type list of the
475 # entries in S. 550 # entries in S.
476 'maxarg': lengths[-1], 551 'maxarg': lengths[-1],
477 'measure_all_as': common_value(overloads, 'measure_as'), # [MeasureAs] 552 'measure_all_as': common_value(overloads, 'measure_as'), # [MeasureAs]
478 'minarg': lengths[0], 553 'minarg': lengths[0],
479 'per_context_enabled_function_all': common_value(overloads, 'per_context _enabled_function'), # [PerContextEnabled] 554 'per_context_enabled_function_all': common_value(overloads, 'per_context _enabled_function'), # [PerContextEnabled]
480 'runtime_enabled_function_all': common_value(overloads, 'runtime_enabled _function'), # [RuntimeEnabled] 555 'runtime_enabled_function_all': common_value(overloads, 'runtime_enabled _function'), # [RuntimeEnabled]
481 'valid_arities': lengths 556 'valid_arities': lengths
482 # Only need to report valid arities if there is a gap in the 557 # Only need to report valid arities if there is a gap in the
483 # sequence of possible lengths, otherwise invalid length means 558 # sequence of possible lengths, otherwise invalid length means
484 # "not enough arguments". 559 # "not enough arguments".
485 if lengths[-1] - lengths[0] != len(lengths) - 1 else None, 560 if lengths[-1] - lengths[0] != len(lengths) - 1 else None,
561 'visible': overloads_visible,
562 'partial_overloads': partial_overloads,
486 } 563 }
487 564
488 565
489 def effective_overload_set(F): 566 def effective_overload_set(F):
490 """Returns the effective overload set of an overloaded function. 567 """Returns the effective overload set of an overloaded function.
491 568
492 An effective overload set is the set of overloaded functions + signatures 569 An effective overload set is the set of overloaded functions + signatures
493 (type list of arguments, with optional and variadic arguments included or 570 (type list of arguments, with optional and variadic arguments included or
494 not), and is used in the overload resolution algorithm. 571 not), and is used in the overload resolution algorithm.
495 572
(...skipping 637 matching lines...) Expand 10 before | Expand all | Expand 10 after
1133 deleter = next( 1210 deleter = next(
1134 method 1211 method
1135 for method in interface.operations 1212 for method in interface.operations
1136 if ('deleter' in method.specials and 1213 if ('deleter' in method.specials and
1137 len(method.arguments) == 1 and 1214 len(method.arguments) == 1 and
1138 str(method.arguments[0].idl_type) == 'DOMString')) 1215 str(method.arguments[0].idl_type) == 'DOMString'))
1139 except StopIteration: 1216 except StopIteration:
1140 return None 1217 return None
1141 1218
1142 return property_deleter(deleter) 1219 return property_deleter(deleter)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698