OLD | NEW |
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 28 matching lines...) Expand all Loading... |
39 import idl_definitions | 39 import idl_definitions |
40 from idl_definitions import IdlOperation | 40 from idl_definitions import IdlOperation |
41 import idl_types | 41 import idl_types |
42 from idl_types import IdlType, inherits_interface | 42 from idl_types import IdlType, inherits_interface |
43 import v8_attributes | 43 import v8_attributes |
44 from v8_globals import includes | 44 from v8_globals import includes |
45 import v8_methods | 45 import v8_methods |
46 import v8_types | 46 import v8_types |
47 from v8_types import cpp_ptr_type, cpp_template_type | 47 from v8_types import cpp_ptr_type, cpp_template_type |
48 import v8_utilities | 48 import v8_utilities |
49 from v8_utilities import (capitalize, conditional_string, cpp_name, gc_type, | 49 from v8_utilities import (cpp_name_or_partial, capitalize, conditional_string, c
pp_name, gc_type, |
50 has_extended_attribute_value, runtime_enabled_function
_name, | 50 has_extended_attribute_value, runtime_enabled_function
_name, |
51 extended_attribute_value_as_list) | 51 extended_attribute_value_as_list) |
52 | 52 |
53 | 53 |
54 INTERFACE_H_INCLUDES = frozenset([ | 54 INTERFACE_H_INCLUDES = frozenset([ |
55 'bindings/core/v8/ScriptWrappable.h', | 55 'bindings/core/v8/ScriptWrappable.h', |
56 'bindings/core/v8/V8Binding.h', | 56 'bindings/core/v8/V8Binding.h', |
57 'bindings/core/v8/V8DOMWrapper.h', | 57 'bindings/core/v8/V8DOMWrapper.h', |
58 'bindings/core/v8/WrapperTypeInfo.h', | 58 'bindings/core/v8/WrapperTypeInfo.h', |
59 'platform/heap/Handle.h', | 59 'platform/heap/Handle.h', |
(...skipping 10 matching lines...) Expand all Loading... |
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 interface.is_partial: |
81 if parent_interface: | 81 # A partial interface definition cannot specify that the interface |
82 header_includes.update(v8_types.includes_for_interface(parent_interface)
) | 82 # inherits from another interface. Inheritance must be specified on |
| 83 # the original interface definition. |
| 84 parent_interface = None |
| 85 is_event_target = False |
| 86 # partial interface needs the definition of its original interface. |
| 87 includes.add('bindings/core/v8/V8%s.h' % interface.name) |
| 88 else: |
| 89 parent_interface = interface.parent |
| 90 if parent_interface: |
| 91 header_includes.update(v8_types.includes_for_interface(parent_interf
ace)) |
| 92 is_event_target = inherits_interface(interface.name, 'EventTarget') |
| 93 |
83 extended_attributes = interface.extended_attributes | 94 extended_attributes = interface.extended_attributes |
84 | 95 |
85 is_array_buffer_or_view = interface.idl_type.is_array_buffer_or_view | 96 is_array_buffer_or_view = interface.idl_type.is_array_buffer_or_view |
86 is_typed_array_type = interface.idl_type.is_typed_array | 97 is_typed_array_type = interface.idl_type.is_typed_array |
87 if is_array_buffer_or_view: | 98 if is_array_buffer_or_view: |
88 includes.add('bindings/core/v8/V8ArrayBuffer.h') | 99 includes.add('bindings/core/v8/V8ArrayBuffer.h') |
89 if interface.name == 'ArrayBuffer': | 100 if interface.name == 'ArrayBuffer': |
90 includes.add('core/dom/DOMArrayBufferDeallocationObserver.h') | 101 includes.add('core/dom/DOMArrayBufferDeallocationObserver.h') |
91 if interface.name == 'ArrayBufferView': | 102 if interface.name == 'ArrayBufferView': |
92 includes.update(( | 103 includes.update(( |
(...skipping 14 matching lines...) Expand all Loading... |
107 # [CheckSecurity] | 118 # [CheckSecurity] |
108 is_check_security = 'CheckSecurity' in extended_attributes | 119 is_check_security = 'CheckSecurity' in extended_attributes |
109 if is_check_security: | 120 if is_check_security: |
110 includes.add('bindings/core/v8/BindingSecurity.h') | 121 includes.add('bindings/core/v8/BindingSecurity.h') |
111 | 122 |
112 # [DependentLifetime] | 123 # [DependentLifetime] |
113 is_dependent_lifetime = 'DependentLifetime' in extended_attributes | 124 is_dependent_lifetime = 'DependentLifetime' in extended_attributes |
114 | 125 |
115 # [Iterable] | 126 # [Iterable] |
116 iterator_method = None | 127 iterator_method = None |
117 if 'Iterable' in extended_attributes: | 128 # FIXME: support Iterable in partial interfaces. However, we don't |
| 129 # need to support iterator overloads between interface and |
| 130 # partial interface definitions. |
| 131 # http://heycam.github.io/webidl/#idl-overloading |
| 132 if 'Iterable' in extended_attributes and not interface.is_partial: |
118 iterator_operation = IdlOperation(interface.idl_name) | 133 iterator_operation = IdlOperation(interface.idl_name) |
119 iterator_operation.name = 'iterator' | 134 iterator_operation.name = 'iterator' |
120 iterator_operation.idl_type = IdlType('Iterator') | 135 iterator_operation.idl_type = IdlType('Iterator') |
121 iterator_operation.extended_attributes['RaisesException'] = None | 136 iterator_operation.extended_attributes['RaisesException'] = None |
122 iterator_operation.extended_attributes['CallWith'] = 'ScriptState' | 137 iterator_operation.extended_attributes['CallWith'] = 'ScriptState' |
123 iterator_method = v8_methods.method_context(interface, | 138 iterator_method = v8_methods.method_context(interface, |
124 iterator_operation) | 139 iterator_operation) |
125 | 140 |
126 # [MeasureAs] | 141 # [MeasureAs] |
127 is_measure_as = 'MeasureAs' in extended_attributes | 142 is_measure_as = 'MeasureAs' in extended_attributes |
(...skipping 26 matching lines...) Expand all Loading... |
154 # [Custom=Wrap], [SetWrapperReferenceFrom] | 169 # [Custom=Wrap], [SetWrapperReferenceFrom] |
155 has_visit_dom_wrapper = ( | 170 has_visit_dom_wrapper = ( |
156 has_extended_attribute_value(interface, 'Custom', 'VisitDOMWrapper') or | 171 has_extended_attribute_value(interface, 'Custom', 'VisitDOMWrapper') or |
157 reachable_node_function or | 172 reachable_node_function or |
158 set_wrapper_reference_to_list) | 173 set_wrapper_reference_to_list) |
159 | 174 |
160 this_gc_type = gc_type(interface) | 175 this_gc_type = gc_type(interface) |
161 | 176 |
162 wrapper_class_id = ('NodeClassId' if inherits_interface(interface.name, 'Nod
e') else 'ObjectClassId') | 177 wrapper_class_id = ('NodeClassId' if inherits_interface(interface.name, 'Nod
e') else 'ObjectClassId') |
163 | 178 |
| 179 v8_class_name = v8_utilities.v8_class_name(interface) |
| 180 cpp_class_name = cpp_name(interface) |
| 181 cpp_class_name_or_partial = cpp_name_or_partial(interface) |
| 182 v8_class_name_or_partial = v8_utilities.v8_class_name_or_partial(interface) |
| 183 |
164 context = { | 184 context = { |
165 'conditional_string': conditional_string(interface), # [Conditional] | 185 'conditional_string': conditional_string(interface), # [Conditional] |
166 'cpp_class': cpp_name(interface), | 186 'cpp_class': cpp_class_name, |
| 187 'cpp_class_or_partial': cpp_class_name_or_partial, |
167 'gc_type': this_gc_type, | 188 'gc_type': this_gc_type, |
168 # FIXME: Remove 'EventTarget' special handling, http://crbug.com/383699 | 189 # FIXME: Remove 'EventTarget' special handling, http://crbug.com/383699 |
169 'has_access_check_callbacks': (is_check_security and | 190 'has_access_check_callbacks': (is_check_security and |
170 interface.name != 'Window' and | 191 interface.name != 'Window' and |
171 interface.name != 'EventTarget'), | 192 interface.name != 'EventTarget'), |
172 'has_custom_legacy_call_as_function': has_extended_attribute_value(inter
face, 'Custom', 'LegacyCallAsFunction'), # [Custom=LegacyCallAsFunction] | 193 'has_custom_legacy_call_as_function': has_extended_attribute_value(inter
face, 'Custom', 'LegacyCallAsFunction'), # [Custom=LegacyCallAsFunction] |
173 'has_custom_to_v8': has_extended_attribute_value(interface, 'Custom', 'T
oV8'), # [Custom=ToV8] | 194 'has_custom_to_v8': has_extended_attribute_value(interface, 'Custom', 'T
oV8'), # [Custom=ToV8] |
174 'has_custom_wrap': has_extended_attribute_value(interface, 'Custom', 'Wr
ap'), # [Custom=Wrap] | 195 'has_custom_wrap': has_extended_attribute_value(interface, 'Custom', 'Wr
ap'), # [Custom=Wrap] |
| 196 'has_partial_interface': len(interface.partial_interfaces) > 0, |
175 'has_visit_dom_wrapper': has_visit_dom_wrapper, | 197 'has_visit_dom_wrapper': has_visit_dom_wrapper, |
176 'header_includes': header_includes, | 198 'header_includes': header_includes, |
177 'interface_name': interface.name, | 199 'interface_name': interface.name, |
178 'is_active_dom_object': is_active_dom_object, | 200 'is_active_dom_object': is_active_dom_object, |
179 'is_array_buffer_or_view': is_array_buffer_or_view, | 201 'is_array_buffer_or_view': is_array_buffer_or_view, |
180 'is_check_security': is_check_security, | 202 'is_check_security': is_check_security, |
181 'is_dependent_lifetime': is_dependent_lifetime, | 203 'is_dependent_lifetime': is_dependent_lifetime, |
182 'is_event_target': inherits_interface(interface.name, 'EventTarget'), | 204 'is_event_target': is_event_target, |
183 'is_exception': interface.is_exception, | 205 'is_exception': interface.is_exception, |
184 'is_node': inherits_interface(interface.name, 'Node'), | 206 'is_node': inherits_interface(interface.name, 'Node'), |
| 207 'is_partial': interface.is_partial, |
185 'is_script_wrappable': is_script_wrappable, | 208 'is_script_wrappable': is_script_wrappable, |
186 'is_typed_array_type': is_typed_array_type, | 209 'is_typed_array_type': is_typed_array_type, |
187 'iterator_method': iterator_method, | 210 'iterator_method': iterator_method, |
188 'lifetime': 'Dependent' | 211 'lifetime': 'Dependent' |
189 if (has_visit_dom_wrapper or | 212 if (has_visit_dom_wrapper or |
190 is_active_dom_object or | 213 is_active_dom_object or |
191 is_dependent_lifetime) | 214 is_dependent_lifetime) |
192 else 'Independent', | 215 else 'Independent', |
193 'measure_as': v8_utilities.measure_as(interface), # [MeasureAs] | 216 'measure_as': v8_utilities.measure_as(interface), # [MeasureAs] |
194 'parent_interface': parent_interface, | 217 'parent_interface': parent_interface, |
195 'pass_cpp_type': cpp_template_type( | 218 'pass_cpp_type': cpp_template_type( |
196 cpp_ptr_type('PassRefPtr', 'RawPtr', this_gc_type), | 219 cpp_ptr_type('PassRefPtr', 'RawPtr', this_gc_type), |
197 cpp_name(interface)), | 220 cpp_name(interface)), |
198 'reachable_node_function': reachable_node_function, | 221 'reachable_node_function': reachable_node_function, |
199 'runtime_enabled_function': runtime_enabled_function_name(interface), #
[RuntimeEnabled] | 222 'runtime_enabled_function': runtime_enabled_function_name(interface), #
[RuntimeEnabled] |
200 'set_wrapper_reference_to_list': set_wrapper_reference_to_list, | 223 'set_wrapper_reference_to_list': set_wrapper_reference_to_list, |
201 'v8_class': v8_utilities.v8_class_name(interface), | 224 'v8_class': v8_class_name, |
| 225 'v8_class_or_partial': v8_class_name_or_partial, |
202 'wrapper_class_id': wrapper_class_id, | 226 'wrapper_class_id': wrapper_class_id, |
203 } | 227 } |
204 | 228 |
205 # Constructors | 229 # Constructors |
206 constructors = [constructor_context(interface, constructor) | 230 constructors = [constructor_context(interface, constructor) |
207 for constructor in interface.constructors | 231 for constructor in interface.constructors |
208 # FIXME: shouldn't put named constructors with constructors | 232 # FIXME: shouldn't put named constructors with constructors |
209 # (currently needed for Perl compatibility) | 233 # (currently needed for Perl compatibility) |
210 # Handle named constructors separately | 234 # Handle named constructors separately |
211 if constructor.name == 'Constructor'] | 235 if constructor.name == 'Constructor'] |
212 if len(constructors) > 1: | 236 if len(constructors) > 1: |
213 context['constructor_overloads'] = overloads_context(constructors) | 237 context['constructor_overloads'] = overloads_context(interface, construc
tors) |
214 | 238 |
215 # [CustomConstructor] | 239 # [CustomConstructor] |
216 custom_constructors = [{ # Only needed for computing interface length | 240 custom_constructors = [{ # Only needed for computing interface length |
217 'number_of_required_arguments': | 241 'number_of_required_arguments': |
218 number_of_required_arguments(constructor), | 242 number_of_required_arguments(constructor), |
219 } for constructor in interface.custom_constructors] | 243 } for constructor in interface.custom_constructors] |
220 | 244 |
221 # [EventConstructor] | 245 # [EventConstructor] |
222 has_event_constructor = 'EventConstructor' in extended_attributes | 246 has_event_constructor = 'EventConstructor' in extended_attributes |
223 any_type_attributes = [attribute for attribute in interface.attributes | 247 any_type_attributes = [attribute for attribute in interface.attributes |
224 if attribute.idl_type.name == 'Any'] | 248 if attribute.idl_type.name == 'Any'] |
225 if has_event_constructor: | 249 if has_event_constructor: |
226 includes.add('bindings/core/v8/Dictionary.h') | 250 includes.add('bindings/core/v8/Dictionary.h') |
227 if any_type_attributes: | 251 if any_type_attributes: |
228 includes.add('bindings/core/v8/SerializedScriptValue.h') | 252 includes.add('bindings/core/v8/SerializedScriptValue.h') |
229 | 253 |
230 # [NamedConstructor] | 254 # [NamedConstructor] |
231 named_constructor = named_constructor_context(interface) | 255 named_constructor = named_constructor_context(interface) |
232 | 256 |
233 if (constructors or custom_constructors or has_event_constructor or | 257 if constructors or custom_constructors or has_event_constructor or named_con
structor: |
234 named_constructor): | 258 if interface.is_partial: |
| 259 raise Exception('[Constructor] and [NamedConstructor] MUST NOT be' |
| 260 ' specified on partial interface definitions:' |
| 261 '%s' % interface.name) |
| 262 |
235 includes.add('bindings/core/v8/V8ObjectConstructor.h') | 263 includes.add('bindings/core/v8/V8ObjectConstructor.h') |
236 includes.add('core/frame/LocalDOMWindow.h') | 264 includes.add('core/frame/LocalDOMWindow.h') |
237 | 265 |
238 context.update({ | 266 context.update({ |
239 'any_type_attributes': any_type_attributes, | 267 'any_type_attributes': any_type_attributes, |
240 'constructors': constructors, | 268 'constructors': constructors, |
241 'has_custom_constructor': bool(custom_constructors), | 269 'has_custom_constructor': bool(custom_constructors), |
242 'has_event_constructor': has_event_constructor, | 270 'has_event_constructor': has_event_constructor, |
243 'interface_length': | 271 'interface_length': |
244 interface_length(interface, constructors + custom_constructors), | 272 interface_length(interface, constructors + custom_constructors), |
(...skipping 24 matching lines...) Expand all Loading... |
269 'has_constant_configuration': any( | 297 'has_constant_configuration': any( |
270 not constant['runtime_enabled_function'] | 298 not constant['runtime_enabled_function'] |
271 for constant in constants), | 299 for constant in constants), |
272 'runtime_enabled_constants': runtime_enabled_constants, | 300 'runtime_enabled_constants': runtime_enabled_constants, |
273 'special_getter_constants': special_getter_constants, | 301 'special_getter_constants': special_getter_constants, |
274 }) | 302 }) |
275 | 303 |
276 # Attributes | 304 # Attributes |
277 attributes = [v8_attributes.attribute_context(interface, attribute) | 305 attributes = [v8_attributes.attribute_context(interface, attribute) |
278 for attribute in interface.attributes] | 306 for attribute in interface.attributes] |
| 307 |
| 308 has_conditional_attributes = any(attribute['per_context_enabled_function'] o
r attribute['exposed_test'] for attribute in attributes) |
| 309 if has_conditional_attributes and interface.is_partial: |
| 310 raise Exception('Conditional attributes between partial interfaces in mo
dules and the original interfaces(%s) in core are not allowed.' % interface.name
) |
| 311 |
279 context.update({ | 312 context.update({ |
280 'attributes': attributes, | 313 'attributes': attributes, |
281 'has_accessors': any(attribute['is_expose_js_accessors'] and attribute['
should_be_exposed_to_script'] for attribute in attributes), | 314 'has_accessors': any(attribute['is_expose_js_accessors'] and attribute['
should_be_exposed_to_script'] for attribute in attributes), |
282 'has_attribute_configuration': any( | 315 'has_attribute_configuration': any( |
283 not (attribute['is_expose_js_accessors'] or | 316 not (attribute['is_expose_js_accessors'] or |
284 attribute['is_static'] or | 317 attribute['is_static'] or |
285 attribute['runtime_enabled_function'] or | 318 attribute['runtime_enabled_function'] or |
286 attribute['per_context_enabled_function']) | 319 attribute['per_context_enabled_function']) |
287 and attribute['should_be_exposed_to_script'] | 320 and attribute['should_be_exposed_to_script'] |
288 for attribute in attributes), | 321 for attribute in attributes), |
289 'has_conditional_attributes': any(attribute['per_context_enabled_functio
n'] or attribute['exposed_test'] for attribute in attributes), | 322 'has_conditional_attributes': has_conditional_attributes, |
290 'has_constructor_attributes': any(attribute['constructor_type'] for attr
ibute in attributes), | 323 'has_constructor_attributes': any(attribute['constructor_type'] for attr
ibute in attributes), |
291 'has_replaceable_attributes': any(attribute['is_replaceable'] for attrib
ute in attributes), | 324 'has_replaceable_attributes': any(attribute['is_replaceable'] for attrib
ute in attributes), |
292 }) | 325 }) |
293 | 326 |
294 # Methods | 327 # Methods |
295 methods = [v8_methods.method_context(interface, method) | 328 methods = [] |
296 for method in interface.operations | 329 if interface.original_interface: |
297 if method.name] # Skip anonymous special operations (methods) | 330 methods.extend([v8_methods.method_context(interface, operation, is_visib
le=False) |
298 compute_method_overloads_context(methods) | 331 for operation in interface.original_interface.operations |
| 332 if operation.name]) |
| 333 methods.extend([v8_methods.method_context(interface, method) |
| 334 for method in interface.operations |
| 335 if method.name]) # Skip anonymous special operations (metho
ds) |
| 336 if interface.partial_interfaces: |
| 337 assert len(interface.partial_interfaces) == len(set(interface.partial_in
terfaces)) |
| 338 for partial_interface in interface.partial_interfaces: |
| 339 methods.extend([v8_methods.method_context(interface, operation, is_v
isible=False) |
| 340 for operation in partial_interface.operations |
| 341 if operation.name]) |
| 342 compute_method_overloads_context(interface, methods) |
299 | 343 |
300 # Stringifier | 344 # Stringifier |
301 if interface.stringifier: | 345 if interface.stringifier: |
302 stringifier = interface.stringifier | 346 stringifier = interface.stringifier |
303 method = IdlOperation(interface.idl_name) | 347 method = IdlOperation(interface.idl_name) |
304 method.name = 'toString' | 348 method.name = 'toString' |
305 method.idl_type = IdlType('DOMString') | 349 method.idl_type = IdlType('DOMString') |
306 method.extended_attributes.update(stringifier.extended_attributes) | 350 method.extended_attributes.update(stringifier.extended_attributes) |
307 if stringifier.attribute: | 351 if stringifier.attribute: |
308 method.extended_attributes['ImplementedAs'] = stringifier.attribute.
name | 352 method.extended_attributes['ImplementedAs'] = stringifier.attribute.
name |
309 elif stringifier.operation: | 353 elif stringifier.operation: |
310 method.extended_attributes['ImplementedAs'] = stringifier.operation.
name | 354 method.extended_attributes['ImplementedAs'] = stringifier.operation.
name |
311 methods.append(v8_methods.method_context(interface, method)) | 355 methods.append(v8_methods.method_context(interface, method)) |
312 | 356 |
313 conditionally_enabled_methods = [] | 357 conditionally_enabled_methods = [] |
314 custom_registration_methods = [] | 358 custom_registration_methods = [] |
315 method_configuration_methods = [] | 359 method_configuration_methods = [] |
316 | 360 |
317 for method in methods: | 361 for method in methods: |
318 # Skip all but one method in each set of overloaded methods. | 362 # Skip all but one method in each set of overloaded methods. |
319 if 'overload_index' in method and 'overloads' not in method: | 363 if 'overload_index' in method and 'overloads' not in method: |
320 continue | 364 continue |
321 | 365 |
322 if 'overloads' in method: | 366 if 'overloads' in method: |
323 overloads = method['overloads'] | 367 overloads = method['overloads'] |
| 368 if not overloads['visible']: |
| 369 continue |
| 370 # original interface will register instead of partial interface. |
| 371 if overloads['has_partial_overloads'] and interface.is_partial: |
| 372 continue |
324 per_context_enabled_function = overloads['per_context_enabled_functi
on_all'] | 373 per_context_enabled_function = overloads['per_context_enabled_functi
on_all'] |
325 conditionally_exposed_function = overloads['exposed_test_all'] | 374 conditionally_exposed_function = overloads['exposed_test_all'] |
326 runtime_enabled_function = overloads['runtime_enabled_function_all'] | 375 runtime_enabled_function = overloads['runtime_enabled_function_all'] |
327 has_custom_registration = overloads['has_custom_registration_all'] | 376 has_custom_registration = overloads['has_custom_registration_all'] |
328 else: | 377 else: |
| 378 if not method['visible']: |
| 379 continue |
329 per_context_enabled_function = method['per_context_enabled_function'
] | 380 per_context_enabled_function = method['per_context_enabled_function'
] |
330 conditionally_exposed_function = method['exposed_test'] | 381 conditionally_exposed_function = method['exposed_test'] |
331 runtime_enabled_function = method['runtime_enabled_function'] | 382 runtime_enabled_function = method['runtime_enabled_function'] |
332 has_custom_registration = method['has_custom_registration'] | 383 has_custom_registration = method['has_custom_registration'] |
333 | 384 |
334 if per_context_enabled_function or conditionally_exposed_function: | 385 if per_context_enabled_function or conditionally_exposed_function: |
335 conditionally_enabled_methods.append(method) | 386 conditionally_enabled_methods.append(method) |
336 continue | 387 continue |
337 if runtime_enabled_function or has_custom_registration: | 388 if runtime_enabled_function or has_custom_registration: |
338 custom_registration_methods.append(method) | 389 custom_registration_methods.append(method) |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
393 'reflected_name': extended_attributes.get('Reflect', constant.name), | 444 'reflected_name': extended_attributes.get('Reflect', constant.name), |
394 'runtime_enabled_function': runtime_enabled_function_name(constant), | 445 'runtime_enabled_function': runtime_enabled_function_name(constant), |
395 'value': constant.value, | 446 'value': constant.value, |
396 } | 447 } |
397 | 448 |
398 | 449 |
399 ################################################################################ | 450 ################################################################################ |
400 # Overloads | 451 # Overloads |
401 ################################################################################ | 452 ################################################################################ |
402 | 453 |
403 def compute_method_overloads_context(methods): | 454 def compute_method_overloads_context(interface, methods): |
404 # Regular methods | 455 # Regular methods |
405 compute_method_overloads_context_by_type([method for method in methods | 456 compute_method_overloads_context_by_type( |
406 if not method['is_static']]) | 457 interface, [method for method in methods if not method['is_static']]) |
407 # Static methods | 458 # Static methods |
408 compute_method_overloads_context_by_type([method for method in methods | 459 compute_method_overloads_context_by_type( |
409 if method['is_static']]) | 460 interface, [method for method in methods if method['is_static']]) |
410 | 461 |
411 | 462 |
412 def compute_method_overloads_context_by_type(methods): | 463 def compute_method_overloads_context_by_type(interface, methods): |
413 """Computes |method.overload*| template values. | 464 """Computes |method.overload*| template values. |
414 | 465 |
415 Called separately for static and non-static (regular) methods, | 466 Called separately for static and non-static (regular) methods, |
416 as these are overloaded separately. | 467 as these are overloaded separately. |
417 Modifies |method| in place for |method| in |methods|. | 468 Modifies |method| in place for |method| in |methods|. |
418 Doesn't change the |methods| list itself (only the values, i.e. individual | 469 Doesn't change the |methods| list itself (only the values, i.e. individual |
419 methods), so ok to treat these separately. | 470 methods), so ok to treat these separately. |
420 """ | 471 """ |
421 # Add overload information only to overloaded methods, so template code can | 472 # Add overload information only to overloaded methods, so template code can |
422 # easily verify if a function is overloaded | 473 # easily verify if a function is overloaded |
423 for name, overloads in method_overloads_by_name(methods): | 474 for name, overloads in method_overloads_by_name(methods): |
424 # Resolution function is generated after last overloaded function; | 475 # Resolution function is generated after last overloaded function; |
425 # package necessary information into |method.overloads| for that method. | 476 # package necessary information into |method.overloads| for that method. |
426 overloads[-1]['overloads'] = overloads_context(overloads) | 477 overloads[-1]['overloads'] = overloads_context(interface, overloads) |
427 overloads[-1]['overloads']['name'] = name | 478 overloads[-1]['overloads']['name'] = name |
428 | 479 |
429 | 480 |
430 def method_overloads_by_name(methods): | 481 def method_overloads_by_name(methods): |
431 """Returns generator of overloaded methods by name: [name, [method]]""" | 482 """Returns generator of overloaded methods by name: [name, [method]]""" |
432 # Filter to only methods that are actually overloaded | 483 # Filter to only methods that are actually overloaded |
433 method_counts = Counter(method['name'] for method in methods) | 484 method_counts = Counter(method['name'] for method in methods) |
434 overloaded_method_names = set(name | 485 overloaded_method_names = set(name |
435 for name, count in method_counts.iteritems() | 486 for name, count in method_counts.iteritems() |
436 if count > 1) | 487 if count > 1) |
437 overloaded_methods = [method for method in methods | 488 overloaded_methods = [method for method in methods |
438 if method['name'] in overloaded_method_names] | 489 if method['name'] in overloaded_method_names] |
439 | 490 |
440 # Group by name (generally will be defined together, but not necessarily) | 491 # Group by name (generally will be defined together, but not necessarily) |
441 return sort_and_groupby(overloaded_methods, itemgetter('name')) | 492 return sort_and_groupby(overloaded_methods, itemgetter('name')) |
442 | 493 |
443 | 494 |
444 def overloads_context(overloads): | 495 def overloads_context(interface, overloads): |
445 """Returns |overloads| template values for a single name. | 496 """Returns |overloads| template values for a single name. |
446 | 497 |
447 Sets |method.overload_index| in place for |method| in |overloads| | 498 Sets |method.overload_index| in place for |method| in |overloads| |
448 and returns dict of overall overload template values. | 499 and returns dict of overall overload template values. |
449 """ | 500 """ |
450 assert len(overloads) > 1 # only apply to overloaded names | 501 assert len(overloads) > 1 # only apply to overloaded names |
451 for index, method in enumerate(overloads, 1): | 502 for index, method in enumerate(overloads, 1): |
452 method['overload_index'] = index | 503 method['overload_index'] = index |
453 | 504 |
454 effective_overloads_by_length = effective_overload_set_by_length(overloads) | 505 effective_overloads_by_length = effective_overload_set_by_length(overloads) |
(...skipping 25 matching lines...) Expand all Loading... |
480 raise ValueError('Overloads of %s have conflicting extended attr
ibute %s' | 531 raise ValueError('Overloads of %s have conflicting extended attr
ibute %s' |
481 % (name, extended_attribute)) | 532 % (name, extended_attribute)) |
482 | 533 |
483 # Check and fail if overloads disagree about whether the return type | 534 # Check and fail if overloads disagree about whether the return type |
484 # is a Promise or not. | 535 # is a Promise or not. |
485 promise_overload_count = sum(1 for method in overloads if method.get('idl_ty
pe') == 'Promise') | 536 promise_overload_count = sum(1 for method in overloads if method.get('idl_ty
pe') == 'Promise') |
486 if promise_overload_count not in (0, len(overloads)): | 537 if promise_overload_count not in (0, len(overloads)): |
487 raise ValueError('Overloads of %s have conflicting Promise/non-Promise t
ypes' | 538 raise ValueError('Overloads of %s have conflicting Promise/non-Promise t
ypes' |
488 % (name)) | 539 % (name)) |
489 | 540 |
| 541 has_overload_visible = False |
| 542 has_overload_not_visible = False |
| 543 for overload in overloads: |
| 544 if overload.get('visible', True): |
| 545 # If there exists an overload which is visible, need to generate |
| 546 # overload_resolution, i.e. overlods_visible should be True. |
| 547 has_overload_visible = True |
| 548 else: |
| 549 has_overload_not_visible = True |
| 550 |
| 551 # If some overloads are not visible and others are visible, |
| 552 # the method is overloaded between core and modules. |
| 553 has_partial_overloads = has_overload_visible and has_overload_not_visible |
| 554 |
490 return { | 555 return { |
491 'deprecate_all_as': common_value(overloads, 'deprecate_as'), # [Depreca
teAs] | 556 'deprecate_all_as': common_value(overloads, 'deprecate_as'), # [Depreca
teAs] |
492 'exposed_test_all': common_value(overloads, 'exposed_test'), # [Exposed
] | 557 'exposed_test_all': common_value(overloads, 'exposed_test'), # [Exposed
] |
493 'has_custom_registration_all': common_value(overloads, 'has_custom_regis
tration'), | 558 'has_custom_registration_all': common_value(overloads, 'has_custom_regis
tration'), |
494 'length_tests_methods': length_tests_methods(effective_overloads_by_leng
th), | 559 'length_tests_methods': length_tests_methods(effective_overloads_by_leng
th), |
495 # 1. Let maxarg be the length of the longest type list of the | 560 # 1. Let maxarg be the length of the longest type list of the |
496 # entries in S. | 561 # entries in S. |
497 'maxarg': lengths[-1], | 562 'maxarg': lengths[-1], |
498 'measure_all_as': common_value(overloads, 'measure_as'), # [MeasureAs] | 563 'measure_all_as': common_value(overloads, 'measure_as'), # [MeasureAs] |
499 'minarg': lengths[0], | 564 'minarg': lengths[0], |
500 'per_context_enabled_function_all': common_value(overloads, 'per_context
_enabled_function'), # [PerContextEnabled] | 565 'per_context_enabled_function_all': common_value(overloads, 'per_context
_enabled_function'), # [PerContextEnabled] |
501 'runtime_enabled_function_all': common_value(overloads, 'runtime_enabled
_function'), # [RuntimeEnabled] | 566 'runtime_enabled_function_all': common_value(overloads, 'runtime_enabled
_function'), # [RuntimeEnabled] |
502 'valid_arities': lengths | 567 'valid_arities': lengths |
503 # Only need to report valid arities if there is a gap in the | 568 # Only need to report valid arities if there is a gap in the |
504 # sequence of possible lengths, otherwise invalid length means | 569 # sequence of possible lengths, otherwise invalid length means |
505 # "not enough arguments". | 570 # "not enough arguments". |
506 if lengths[-1] - lengths[0] != len(lengths) - 1 else None, | 571 if lengths[-1] - lengths[0] != len(lengths) - 1 else None, |
| 572 'visible': has_overload_visible, |
| 573 'has_partial_overloads': has_partial_overloads, |
507 } | 574 } |
508 | 575 |
509 | 576 |
510 def effective_overload_set(F): | 577 def effective_overload_set(F): |
511 """Returns the effective overload set of an overloaded function. | 578 """Returns the effective overload set of an overloaded function. |
512 | 579 |
513 An effective overload set is the set of overloaded functions + signatures | 580 An effective overload set is the set of overloaded functions + signatures |
514 (type list of arguments, with optional and variadic arguments included or | 581 (type list of arguments, with optional and variadic arguments included or |
515 not), and is used in the overload resolution algorithm. | 582 not), and is used in the overload resolution algorithm. |
516 | 583 |
(...skipping 637 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1154 deleter = next( | 1221 deleter = next( |
1155 method | 1222 method |
1156 for method in interface.operations | 1223 for method in interface.operations |
1157 if ('deleter' in method.specials and | 1224 if ('deleter' in method.specials and |
1158 len(method.arguments) == 1 and | 1225 len(method.arguments) == 1 and |
1159 str(method.arguments[0].idl_type) == 'DOMString')) | 1226 str(method.arguments[0].idl_type) == 'DOMString')) |
1160 except StopIteration: | 1227 except StopIteration: |
1161 return None | 1228 return None |
1162 | 1229 |
1163 return property_deleter(deleter) | 1230 return property_deleter(deleter) |
OLD | NEW |