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