| 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 18 matching lines...) Expand all Loading... |
| 29 | 29 |
| 30 """Generate template values for an interface. | 30 """Generate template values for an interface. |
| 31 | 31 |
| 32 Design doc: http://www.chromium.org/developers/design-documents/idl-compiler | 32 Design doc: http://www.chromium.org/developers/design-documents/idl-compiler |
| 33 """ | 33 """ |
| 34 | 34 |
| 35 from collections import defaultdict | 35 from collections import defaultdict |
| 36 import itertools | 36 import itertools |
| 37 from operator import itemgetter | 37 from operator import itemgetter |
| 38 | 38 |
| 39 import idl_definitions |
| 40 from idl_definitions import IdlOperation |
| 39 import idl_types | 41 import idl_types |
| 40 from idl_types import IdlType, inherits_interface | 42 from idl_types import IdlType, inherits_interface |
| 41 import v8_attributes | 43 import v8_attributes |
| 42 from v8_globals import includes | 44 from v8_globals import includes |
| 43 import v8_methods | 45 import v8_methods |
| 44 import v8_types | 46 import v8_types |
| 45 from v8_types import cpp_ptr_type, cpp_template_type | 47 from v8_types import cpp_ptr_type, cpp_template_type |
| 46 import v8_utilities | 48 import v8_utilities |
| 47 from v8_utilities import capitalize, conditional_string, cpp_name, gc_type, has_
extended_attribute_value, runtime_enabled_function_name | 49 from v8_utilities import capitalize, conditional_string, cpp_name, gc_type, has_
extended_attribute_value, runtime_enabled_function_name |
| 48 | 50 |
| 49 | 51 |
| 50 INTERFACE_H_INCLUDES = frozenset([ | 52 INTERFACE_H_INCLUDES = frozenset([ |
| 51 'bindings/v8/V8Binding.h', | 53 'bindings/common/ScriptWrappable.h', |
| 52 'bindings/v8/V8DOMWrapper.h', | 54 'bindings/core/v8/V8Binding.h', |
| 53 'bindings/v8/WrapperTypeInfo.h', | 55 'bindings/core/v8/V8DOMWrapper.h', |
| 56 'bindings/core/v8/WrapperTypeInfo.h', |
| 54 'platform/heap/Handle.h', | 57 'platform/heap/Handle.h', |
| 55 ]) | 58 ]) |
| 56 INTERFACE_CPP_INCLUDES = frozenset([ | 59 INTERFACE_CPP_INCLUDES = frozenset([ |
| 57 'bindings/v8/V8ExceptionState.h', | 60 'bindings/core/v8/V8ExceptionState.h', |
| 58 'bindings/v8/V8DOMConfiguration.h', | 61 'bindings/core/v8/V8DOMConfiguration.h', |
| 59 'bindings/v8/V8HiddenValue.h', | 62 'bindings/core/v8/V8HiddenValue.h', |
| 60 'bindings/v8/V8ObjectConstructor.h', | 63 'bindings/core/v8/V8ObjectConstructor.h', |
| 61 'core/dom/ContextFeatures.h', | 64 'core/dom/ContextFeatures.h', |
| 62 'core/dom/Document.h', | 65 'core/dom/Document.h', |
| 63 'platform/RuntimeEnabledFeatures.h', | 66 'platform/RuntimeEnabledFeatures.h', |
| 64 'platform/TraceEvent.h', | 67 'platform/TraceEvent.h', |
| 65 'wtf/GetPtr.h', | 68 'wtf/GetPtr.h', |
| 66 'wtf/RefPtr.h', | 69 'wtf/RefPtr.h', |
| 67 ]) | 70 ]) |
| 68 | 71 |
| 69 | 72 |
| 70 def generate_interface(interface): | 73 def interface_context(interface): |
| 71 includes.clear() | 74 includes.clear() |
| 72 includes.update(INTERFACE_CPP_INCLUDES) | 75 includes.update(INTERFACE_CPP_INCLUDES) |
| 73 header_includes = set(INTERFACE_H_INCLUDES) | 76 header_includes = set(INTERFACE_H_INCLUDES) |
| 74 | 77 |
| 75 parent_interface = interface.parent | 78 parent_interface = interface.parent |
| 76 if parent_interface: | 79 if parent_interface: |
| 77 header_includes.update(v8_types.includes_for_interface(parent_interface)
) | 80 header_includes.update(v8_types.includes_for_interface(parent_interface)
) |
| 78 extended_attributes = interface.extended_attributes | 81 extended_attributes = interface.extended_attributes |
| 79 | 82 |
| 80 is_audio_buffer = inherits_interface(interface.name, 'AudioBuffer') | 83 is_audio_buffer = inherits_interface(interface.name, 'AudioBuffer') |
| 81 if is_audio_buffer: | 84 if is_audio_buffer: |
| 82 includes.add('modules/webaudio/AudioBuffer.h') | 85 includes.add('modules/webaudio/AudioBuffer.h') |
| 83 | 86 |
| 84 is_document = inherits_interface(interface.name, 'Document') | 87 is_document = inherits_interface(interface.name, 'Document') |
| 85 if is_document: | 88 if is_document: |
| 86 includes.update(['bindings/v8/ScriptController.h', | 89 includes.update(['bindings/core/v8/ScriptController.h', |
| 87 'bindings/v8/V8WindowShell.h', | 90 'bindings/core/v8/WindowProxy.h', |
| 88 'core/frame/LocalFrame.h']) | 91 'core/frame/LocalFrame.h']) |
| 89 | 92 |
| 90 # [ActiveDOMObject] | 93 # [ActiveDOMObject] |
| 91 is_active_dom_object = 'ActiveDOMObject' in extended_attributes | 94 is_active_dom_object = 'ActiveDOMObject' in extended_attributes |
| 92 | 95 |
| 93 # [CheckSecurity] | 96 # [CheckSecurity] |
| 94 is_check_security = 'CheckSecurity' in extended_attributes | 97 is_check_security = 'CheckSecurity' in extended_attributes |
| 95 if is_check_security: | 98 if is_check_security: |
| 96 includes.add('bindings/common/BindingSecurity.h') | 99 includes.add('bindings/common/BindingSecurity.h') |
| 97 | 100 |
| 98 # [DependentLifetime] | 101 # [DependentLifetime] |
| 99 is_dependent_lifetime = 'DependentLifetime' in extended_attributes | 102 is_dependent_lifetime = 'DependentLifetime' in extended_attributes |
| 100 | 103 |
| 101 # [MeasureAs] | 104 # [MeasureAs] |
| 102 is_measure_as = 'MeasureAs' in extended_attributes | 105 is_measure_as = 'MeasureAs' in extended_attributes |
| 103 if is_measure_as: | 106 if is_measure_as: |
| 104 includes.add('core/frame/UseCounter.h') | 107 includes.add('core/frame/UseCounter.h') |
| 105 | 108 |
| 106 # [SetWrapperReferenceFrom] | 109 # [SetWrapperReferenceFrom] |
| 107 reachable_node_function = extended_attributes.get('SetWrapperReferenceFrom') | 110 reachable_node_function = extended_attributes.get('SetWrapperReferenceFrom') |
| 108 if reachable_node_function: | 111 if reachable_node_function: |
| 109 includes.update(['bindings/v8/V8GCController.h', | 112 includes.update(['bindings/core/v8/V8GCController.h', |
| 110 'core/dom/Element.h']) | 113 'core/dom/Element.h']) |
| 111 | 114 |
| 112 # [SetWrapperReferenceTo] | 115 # [SetWrapperReferenceTo] |
| 113 set_wrapper_reference_to_list = [{ | 116 set_wrapper_reference_to_list = [{ |
| 114 'name': argument.name, | 117 'name': argument.name, |
| 115 # FIXME: properly should be: | 118 # FIXME: properly should be: |
| 116 # 'cpp_type': argument.idl_type.cpp_type_args(used_as_argument=True), | 119 # 'cpp_type': argument.idl_type.cpp_type_args(raw_type=True), |
| 117 # (if type is non-wrapper type like NodeFilter, normally RefPtr) | 120 # (if type is non-wrapper type like NodeFilter, normally RefPtr) |
| 118 # Raw pointers faster though, and NodeFilter hacky anyway. | 121 # Raw pointers faster though, and NodeFilter hacky anyway. |
| 119 'cpp_type': argument.idl_type.implemented_as + '*', | 122 'cpp_type': argument.idl_type.implemented_as + '*', |
| 120 'idl_type': argument.idl_type, | 123 'idl_type': argument.idl_type, |
| 121 'v8_type': v8_types.v8_type(argument.idl_type.name), | 124 'v8_type': v8_types.v8_type(argument.idl_type.name), |
| 122 } for argument in extended_attributes.get('SetWrapperReferenceTo', [])] | 125 } for argument in extended_attributes.get('SetWrapperReferenceTo', [])] |
| 123 for set_wrapper_reference_to in set_wrapper_reference_to_list: | 126 for set_wrapper_reference_to in set_wrapper_reference_to_list: |
| 124 set_wrapper_reference_to['idl_type'].add_includes_for_type() | 127 set_wrapper_reference_to['idl_type'].add_includes_for_type() |
| 125 | 128 |
| 126 # [SpecialWrapFor] | 129 # [SpecialWrapFor] |
| 127 if 'SpecialWrapFor' in extended_attributes: | 130 if 'SpecialWrapFor' in extended_attributes: |
| 128 special_wrap_for = extended_attributes['SpecialWrapFor'].split('|') | 131 special_wrap_for = extended_attributes['SpecialWrapFor'].split('|') |
| 129 else: | 132 else: |
| 130 special_wrap_for = [] | 133 special_wrap_for = [] |
| 131 for special_wrap_interface in special_wrap_for: | 134 for special_wrap_interface in special_wrap_for: |
| 132 v8_types.add_includes_for_interface(special_wrap_interface) | 135 v8_types.add_includes_for_interface(special_wrap_interface) |
| 133 | 136 |
| 134 # [Custom=Wrap], [SetWrapperReferenceFrom] | 137 # [Custom=Wrap], [SetWrapperReferenceFrom] |
| 135 has_visit_dom_wrapper = ( | 138 has_visit_dom_wrapper = ( |
| 136 has_extended_attribute_value(interface, 'Custom', 'VisitDOMWrapper') or | 139 has_extended_attribute_value(interface, 'Custom', 'VisitDOMWrapper') or |
| 137 reachable_node_function or | 140 reachable_node_function or |
| 138 set_wrapper_reference_to_list) | 141 set_wrapper_reference_to_list) |
| 139 | 142 |
| 140 this_gc_type = gc_type(interface) | 143 this_gc_type = gc_type(interface) |
| 141 | 144 |
| 142 template_contents = { | 145 context = { |
| 143 'conditional_string': conditional_string(interface), # [Conditional] | 146 'conditional_string': conditional_string(interface), # [Conditional] |
| 144 'cpp_class': cpp_name(interface), | 147 'cpp_class': cpp_name(interface), |
| 145 'gc_type': this_gc_type, | 148 'gc_type': this_gc_type, |
| 146 'has_custom_legacy_call_as_function': has_extended_attribute_value(inter
face, 'Custom', 'LegacyCallAsFunction'), # [Custom=LegacyCallAsFunction] | 149 'has_custom_legacy_call_as_function': has_extended_attribute_value(inter
face, 'Custom', 'LegacyCallAsFunction'), # [Custom=LegacyCallAsFunction] |
| 147 'has_custom_to_v8': has_extended_attribute_value(interface, 'Custom', 'T
oV8'), # [Custom=ToV8] | 150 'has_custom_to_v8': has_extended_attribute_value(interface, 'Custom', 'T
oV8'), # [Custom=ToV8] |
| 148 'has_custom_wrap': has_extended_attribute_value(interface, 'Custom', 'Wr
ap'), # [Custom=Wrap] | 151 'has_custom_wrap': has_extended_attribute_value(interface, 'Custom', 'Wr
ap'), # [Custom=Wrap] |
| 149 'has_visit_dom_wrapper': has_visit_dom_wrapper, | 152 'has_visit_dom_wrapper': has_visit_dom_wrapper, |
| 150 'header_includes': header_includes, | 153 'header_includes': header_includes, |
| 151 'interface_name': interface.name, | 154 'interface_name': interface.name, |
| 152 'is_active_dom_object': is_active_dom_object, | 155 'is_active_dom_object': is_active_dom_object, |
| (...skipping 15 matching lines...) Expand all Loading... |
| 168 'special_wrap_for': special_wrap_for, | 171 'special_wrap_for': special_wrap_for, |
| 169 'v8_class': v8_utilities.v8_class_name(interface), | 172 'v8_class': v8_utilities.v8_class_name(interface), |
| 170 'wrapper_configuration': 'WrapperConfiguration::Dependent' | 173 'wrapper_configuration': 'WrapperConfiguration::Dependent' |
| 171 if (has_visit_dom_wrapper or | 174 if (has_visit_dom_wrapper or |
| 172 is_active_dom_object or | 175 is_active_dom_object or |
| 173 is_dependent_lifetime) | 176 is_dependent_lifetime) |
| 174 else 'WrapperConfiguration::Independent', | 177 else 'WrapperConfiguration::Independent', |
| 175 } | 178 } |
| 176 | 179 |
| 177 # Constructors | 180 # Constructors |
| 178 constructors = [generate_constructor(interface, constructor) | 181 constructors = [constructor_context(interface, constructor) |
| 179 for constructor in interface.constructors | 182 for constructor in interface.constructors |
| 180 # FIXME: shouldn't put named constructors with constructors | 183 # FIXME: shouldn't put named constructors with constructors |
| 181 # (currently needed for Perl compatibility) | 184 # (currently needed for Perl compatibility) |
| 182 # Handle named constructors separately | 185 # Handle named constructors separately |
| 183 if constructor.name == 'Constructor'] | 186 if constructor.name == 'Constructor'] |
| 184 if len(constructors) > 1: | 187 if len(constructors) > 1: |
| 185 template_contents['constructor_overloads'] = generate_overloads(construc
tors) | 188 context['constructor_overloads'] = overloads_context(constructors) |
| 186 | 189 |
| 187 # [CustomConstructor] | 190 # [CustomConstructor] |
| 188 custom_constructors = [{ # Only needed for computing interface length | 191 custom_constructors = [{ # Only needed for computing interface length |
| 189 'number_of_required_arguments': | 192 'number_of_required_arguments': |
| 190 number_of_required_arguments(constructor), | 193 number_of_required_arguments(constructor), |
| 191 } for constructor in interface.custom_constructors] | 194 } for constructor in interface.custom_constructors] |
| 192 | 195 |
| 193 # [EventConstructor] | 196 # [EventConstructor] |
| 194 has_event_constructor = 'EventConstructor' in extended_attributes | 197 has_event_constructor = 'EventConstructor' in extended_attributes |
| 195 any_type_attributes = [attribute for attribute in interface.attributes | 198 any_type_attributes = [attribute for attribute in interface.attributes |
| 196 if attribute.idl_type.name == 'Any'] | 199 if attribute.idl_type.name == 'Any'] |
| 197 if has_event_constructor: | 200 if has_event_constructor: |
| 198 includes.add('bindings/common/Dictionary.h') | 201 includes.add('bindings/core/v8/Dictionary.h') |
| 199 if any_type_attributes: | 202 if any_type_attributes: |
| 200 includes.add('bindings/v8/SerializedScriptValue.h') | 203 includes.add('bindings/core/v8/SerializedScriptValue.h') |
| 201 | 204 |
| 202 # [NamedConstructor] | 205 # [NamedConstructor] |
| 203 named_constructor = generate_named_constructor(interface) | 206 named_constructor = named_constructor_context(interface) |
| 204 | 207 |
| 205 if (constructors or custom_constructors or has_event_constructor or | 208 if (constructors or custom_constructors or has_event_constructor or |
| 206 named_constructor): | 209 named_constructor): |
| 207 includes.add('bindings/v8/V8ObjectConstructor.h') | 210 includes.add('bindings/core/v8/V8ObjectConstructor.h') |
| 208 includes.add('core/frame/LocalDOMWindow.h') | 211 includes.add('core/frame/LocalDOMWindow.h') |
| 209 | 212 |
| 210 template_contents.update({ | 213 context.update({ |
| 211 'any_type_attributes': any_type_attributes, | 214 'any_type_attributes': any_type_attributes, |
| 212 'constructors': constructors, | 215 'constructors': constructors, |
| 213 'has_custom_constructor': bool(custom_constructors), | 216 'has_custom_constructor': bool(custom_constructors), |
| 214 'has_event_constructor': has_event_constructor, | 217 'has_event_constructor': has_event_constructor, |
| 215 'interface_length': | 218 'interface_length': |
| 216 interface_length(interface, constructors + custom_constructors), | 219 interface_length(interface, constructors + custom_constructors), |
| 217 'is_constructor_call_with_document': has_extended_attribute_value( | |
| 218 interface, 'ConstructorCallWith', 'Document'), # [ConstructorCallWi
th=Document] | |
| 219 'is_constructor_call_with_execution_context': has_extended_attribute_val
ue( | |
| 220 interface, 'ConstructorCallWith', 'ExecutionContext'), # [Construct
orCallWith=ExeuctionContext] | |
| 221 'is_constructor_raises_exception': extended_attributes.get('RaisesExcept
ion') == 'Constructor', # [RaisesException=Constructor] | 220 'is_constructor_raises_exception': extended_attributes.get('RaisesExcept
ion') == 'Constructor', # [RaisesException=Constructor] |
| 222 'named_constructor': named_constructor, | 221 'named_constructor': named_constructor, |
| 223 }) | 222 }) |
| 224 | 223 |
| 225 # Constants | 224 # Constants |
| 226 template_contents.update({ | 225 context.update({ |
| 227 'constants': [generate_constant(constant) for constant in interface.cons
tants], | 226 'constants': [constant_context(constant) |
| 227 for constant in interface.constants], |
| 228 'do_not_check_constants': 'DoNotCheckConstants' in extended_attributes, | 228 'do_not_check_constants': 'DoNotCheckConstants' in extended_attributes, |
| 229 }) | 229 }) |
| 230 | 230 |
| 231 # Attributes | 231 # Attributes |
| 232 attributes = [v8_attributes.generate_attribute(interface, attribute) | 232 attributes = [v8_attributes.attribute_context(interface, attribute) |
| 233 for attribute in interface.attributes | 233 for attribute in interface.attributes |
| 234 if not v8_utilities.dart_custom_method(attribute.extended_attr
ibutes)] | 234 if not v8_utilities.dart_custom_method(attribute.extended_attr
ibutes)] |
| 235 template_contents.update({ | 235 context.update({ |
| 236 'attributes': attributes, | 236 'attributes': attributes, |
| 237 'has_accessors': any(attribute['is_expose_js_accessors'] for attribute i
n attributes), | 237 'has_accessors': any(attribute['is_expose_js_accessors'] and attribute['
should_be_exposed_to_script'] for attribute in attributes), |
| 238 'has_attribute_configuration': any( | 238 'has_attribute_configuration': any( |
| 239 not (attribute['is_expose_js_accessors'] or | 239 not (attribute['is_expose_js_accessors'] or |
| 240 attribute['is_static'] or | 240 attribute['is_static'] or |
| 241 attribute['runtime_enabled_function'] or | 241 attribute['runtime_enabled_function'] or |
| 242 attribute['per_context_enabled_function']) | 242 attribute['per_context_enabled_function']) |
| 243 and attribute['should_be_exposed_to_script'] |
| 243 for attribute in attributes), | 244 for attribute in attributes), |
| 245 'has_conditional_attributes': any(attribute['per_context_enabled_functio
n'] or attribute['exposed_test'] for attribute in attributes), |
| 244 'has_constructor_attributes': any(attribute['constructor_type'] for attr
ibute in attributes), | 246 'has_constructor_attributes': any(attribute['constructor_type'] for attr
ibute in attributes), |
| 245 'has_per_context_enabled_attributes': any(attribute['per_context_enabled
_function'] for attribute in attributes), | |
| 246 'has_replaceable_attributes': any(attribute['is_replaceable'] for attrib
ute in attributes), | 247 'has_replaceable_attributes': any(attribute['is_replaceable'] for attrib
ute in attributes), |
| 247 }) | 248 }) |
| 248 | 249 |
| 249 # Methods | 250 # Methods |
| 250 methods = [v8_methods.generate_method(interface, method) | 251 methods = [v8_methods.method_context(interface, method) |
| 251 for method in interface.operations | 252 for method in interface.operations |
| 252 if (method.name and # Skip anonymous special operations (methods
) | 253 if (method.name and # Skip anonymous special operations (methods
) |
| 253 not v8_utilities.dart_custom_method(method.extended_attribute
s))] | 254 not v8_utilities.dart_custom_method(method.extended_attribute
s))] |
| 254 generate_method_overloads(methods) | 255 compute_method_overloads_context(methods) |
| 255 | 256 |
| 256 per_context_enabled_methods = [] | 257 # Stringifier |
| 258 if interface.stringifier: |
| 259 stringifier = interface.stringifier |
| 260 method = IdlOperation(interface.idl_name) |
| 261 method.name = 'toString' |
| 262 method.idl_type = IdlType('DOMString') |
| 263 method.extended_attributes.update(stringifier.extended_attributes) |
| 264 if stringifier.attribute: |
| 265 method.extended_attributes['ImplementedAs'] = stringifier.attribute.
name |
| 266 elif stringifier.operation: |
| 267 method.extended_attributes['ImplementedAs'] = stringifier.operation.
name |
| 268 methods.append(v8_methods.method_context(interface, method)) |
| 269 |
| 270 conditionally_enabled_methods = [] |
| 257 custom_registration_methods = [] | 271 custom_registration_methods = [] |
| 258 method_configuration_methods = [] | 272 method_configuration_methods = [] |
| 259 | 273 |
| 260 for method in methods: | 274 for method in methods: |
| 261 # Skip all but one method in each set of overloaded methods. | 275 # Skip all but one method in each set of overloaded methods. |
| 262 if 'overload_index' in method and 'overloads' not in method: | 276 if 'overload_index' in method and 'overloads' not in method: |
| 263 continue | 277 continue |
| 264 | 278 |
| 265 if 'overloads' in method: | 279 if 'overloads' in method: |
| 266 overloads = method['overloads'] | 280 overloads = method['overloads'] |
| 267 per_context_enabled_function = overloads['per_context_enabled_functi
on_all'] | 281 per_context_enabled_function = overloads['per_context_enabled_functi
on_all'] |
| 282 conditionally_exposed_function = overloads['exposed_test_all'] |
| 268 runtime_enabled_function = overloads['runtime_enabled_function_all'] | 283 runtime_enabled_function = overloads['runtime_enabled_function_all'] |
| 269 has_custom_registration = overloads['has_custom_registration_all'] | 284 has_custom_registration = overloads['has_custom_registration_all'] |
| 270 else: | 285 else: |
| 271 per_context_enabled_function = method['per_context_enabled_function'
] | 286 per_context_enabled_function = method['per_context_enabled_function'
] |
| 287 conditionally_exposed_function = method['exposed_test'] |
| 272 runtime_enabled_function = method['runtime_enabled_function'] | 288 runtime_enabled_function = method['runtime_enabled_function'] |
| 273 has_custom_registration = method['has_custom_registration'] | 289 has_custom_registration = method['has_custom_registration'] |
| 274 | 290 |
| 275 if per_context_enabled_function: | 291 if per_context_enabled_function or conditionally_exposed_function: |
| 276 per_context_enabled_methods.append(method) | 292 conditionally_enabled_methods.append(method) |
| 277 continue | 293 continue |
| 278 if runtime_enabled_function or has_custom_registration: | 294 if runtime_enabled_function or has_custom_registration: |
| 279 custom_registration_methods.append(method) | 295 custom_registration_methods.append(method) |
| 280 continue | 296 continue |
| 281 method_configuration_methods.append(method) | 297 if method['should_be_exposed_to_script']: |
| 298 method_configuration_methods.append(method) |
| 282 | 299 |
| 283 for method in methods: | 300 for method in methods: |
| 284 # The value of the Function object’s “length” property is a Number | 301 # The value of the Function object’s “length” property is a Number |
| 285 # determined as follows: | 302 # determined as follows: |
| 286 # 1. Let S be the effective overload set for regular operations (if the | 303 # 1. Let S be the effective overload set for regular operations (if the |
| 287 # operation is a regular operation) or for static operations (if the | 304 # operation is a regular operation) or for static operations (if the |
| 288 # operation is a static operation) with identifier id on interface I and | 305 # operation is a static operation) with identifier id on interface I and |
| 289 # with argument count 0. | 306 # with argument count 0. |
| 290 # 2. Return the length of the shortest argument list of the entries in S
. | 307 # 2. Return the length of the shortest argument list of the entries in S
. |
| 291 # FIXME: This calculation doesn't take into account whether runtime | 308 # FIXME: This calculation doesn't take into account whether runtime |
| 292 # enabled overloads are actually enabled, so length may be incorrect. | 309 # enabled overloads are actually enabled, so length may be incorrect. |
| 293 # E.g., [RuntimeEnabled=Foo] void f(); void f(long x); | 310 # E.g., [RuntimeEnabled=Foo] void f(); void f(long x); |
| 294 # should have length 1 if Foo is not enabled, but length 0 if it is. | 311 # should have length 1 if Foo is not enabled, but length 0 if it is. |
| 295 method['length'] = (method['overloads']['minarg'] if 'overloads' in meth
od else | 312 method['length'] = (method['overloads']['minarg'] if 'overloads' in meth
od else |
| 296 method['number_of_required_arguments']) | 313 method['number_of_required_arguments']) |
| 297 | 314 |
| 298 template_contents.update({ | 315 context.update({ |
| 316 'conditionally_enabled_methods': conditionally_enabled_methods, |
| 299 'custom_registration_methods': custom_registration_methods, | 317 'custom_registration_methods': custom_registration_methods, |
| 300 'has_origin_safe_method_setter': any( | 318 'has_origin_safe_method_setter': any( |
| 301 method['is_check_security_for_frame'] and not method['is_read_only'] | 319 method['is_check_security_for_frame'] and not method['is_read_only'] |
| 302 for method in methods), | 320 for method in methods), |
| 321 'has_private_script': any(attribute['is_implemented_in_private_script']
for attribute in attributes) or |
| 322 any(method['is_implemented_in_private_script'] for method in methods
), |
| 303 'method_configuration_methods': method_configuration_methods, | 323 'method_configuration_methods': method_configuration_methods, |
| 304 'per_context_enabled_methods': per_context_enabled_methods, | |
| 305 'methods': methods, | 324 'methods': methods, |
| 306 }) | 325 }) |
| 307 | 326 |
| 308 template_contents.update({ | 327 context.update({ |
| 309 'indexed_property_getter': indexed_property_getter(interface), | 328 'indexed_property_getter': indexed_property_getter(interface), |
| 310 'indexed_property_setter': indexed_property_setter(interface), | 329 'indexed_property_setter': indexed_property_setter(interface), |
| 311 'indexed_property_deleter': indexed_property_deleter(interface), | 330 'indexed_property_deleter': indexed_property_deleter(interface), |
| 312 'is_override_builtins': 'OverrideBuiltins' in extended_attributes, | 331 'is_override_builtins': 'OverrideBuiltins' in extended_attributes, |
| 313 'named_property_getter': named_property_getter(interface), | 332 'named_property_getter': named_property_getter(interface), |
| 314 'named_property_setter': named_property_setter(interface), | 333 'named_property_setter': named_property_setter(interface), |
| 315 'named_property_deleter': named_property_deleter(interface), | 334 'named_property_deleter': named_property_deleter(interface), |
| 316 }) | 335 }) |
| 317 | 336 |
| 318 return template_contents | 337 return context |
| 319 | 338 |
| 320 | 339 |
| 321 # [DeprecateAs], [Reflect], [RuntimeEnabled] | 340 # [DeprecateAs], [Reflect], [RuntimeEnabled] |
| 322 def generate_constant(constant): | 341 def constant_context(constant): |
| 323 # (Blink-only) string literals are unquoted in tokenizer, must be re-quoted | 342 # (Blink-only) string literals are unquoted in tokenizer, must be re-quoted |
| 324 # in C++. | 343 # in C++. |
| 325 if constant.idl_type.name == 'String': | 344 if constant.idl_type.name == 'String': |
| 326 value = '"%s"' % constant.value | 345 value = '"%s"' % constant.value |
| 327 else: | 346 else: |
| 328 value = constant.value | 347 value = constant.value |
| 329 | 348 |
| 330 extended_attributes = constant.extended_attributes | 349 extended_attributes = constant.extended_attributes |
| 331 return { | 350 return { |
| 332 'cpp_class': extended_attributes.get('PartialInterfaceImplementedAs'), | 351 'cpp_class': extended_attributes.get('PartialInterfaceImplementedAs'), |
| 352 'idl_type': constant.idl_type.name, |
| 333 'name': constant.name, | 353 'name': constant.name, |
| 334 # FIXME: use 'reflected_name' as correct 'name' | 354 # FIXME: use 'reflected_name' as correct 'name' |
| 335 'reflected_name': extended_attributes.get('Reflect', constant.name), | 355 'reflected_name': extended_attributes.get('Reflect', constant.name), |
| 336 'runtime_enabled_function': runtime_enabled_function_name(constant), | 356 'runtime_enabled_function': runtime_enabled_function_name(constant), |
| 337 'value': value, | 357 'value': value, |
| 338 } | 358 } |
| 339 | 359 |
| 340 | 360 |
| 341 ################################################################################ | 361 ################################################################################ |
| 342 # Overloads | 362 # Overloads |
| 343 ################################################################################ | 363 ################################################################################ |
| 344 | 364 |
| 345 def generate_method_overloads(methods): | 365 def compute_method_overloads_context(methods): |
| 346 # Regular methods | 366 # Regular methods |
| 347 generate_overloads_by_type([method for method in methods | 367 compute_method_overloads_context_by_type([method for method in methods |
| 348 if not method['is_static']]) | 368 if not method['is_static']]) |
| 349 # Static methods | 369 # Static methods |
| 350 generate_overloads_by_type([method for method in methods | 370 compute_method_overloads_context_by_type([method for method in methods |
| 351 if method['is_static']]) | 371 if method['is_static']]) |
| 352 | 372 |
| 353 | 373 |
| 354 def generate_overloads_by_type(methods): | 374 def compute_method_overloads_context_by_type(methods): |
| 355 """Generates |method.overload*| template values. | 375 """Computes |method.overload*| template values. |
| 356 | 376 |
| 357 Called separately for static and non-static (regular) methods, | 377 Called separately for static and non-static (regular) methods, |
| 358 as these are overloaded separately. | 378 as these are overloaded separately. |
| 359 Modifies |method| in place for |method| in |methods|. | 379 Modifies |method| in place for |method| in |methods|. |
| 360 Doesn't change the |methods| list itself (only the values, i.e. individual | 380 Doesn't change the |methods| list itself (only the values, i.e. individual |
| 361 methods), so ok to treat these separately. | 381 methods), so ok to treat these separately. |
| 362 """ | 382 """ |
| 363 # Add overload information only to overloaded methods, so template code can | 383 # Add overload information only to overloaded methods, so template code can |
| 364 # easily verify if a function is overloaded | 384 # easily verify if a function is overloaded |
| 365 for name, overloads in method_overloads_by_name(methods): | 385 for name, overloads in method_overloads_by_name(methods): |
| 366 # Resolution function is generated after last overloaded function; | 386 # Resolution function is generated after last overloaded function; |
| 367 # package necessary information into |method.overloads| for that method. | 387 # package necessary information into |method.overloads| for that method. |
| 368 overloads[-1]['overloads'] = generate_overloads(overloads) | 388 overloads[-1]['overloads'] = overloads_context(overloads) |
| 369 overloads[-1]['overloads']['name'] = name | 389 overloads[-1]['overloads']['name'] = name |
| 370 | 390 |
| 371 | 391 |
| 372 def method_overloads_by_name(methods): | 392 def method_overloads_by_name(methods): |
| 373 """Returns generator of overloaded methods by name: [name, [method]]""" | 393 """Returns generator of overloaded methods by name: [name, [method]]""" |
| 374 # Filter to only methods that are actually overloaded | 394 # Filter to only methods that are actually overloaded |
| 375 method_counts = Counter(method['name'] for method in methods) | 395 method_counts = Counter(method['name'] for method in methods) |
| 376 overloaded_method_names = set(name | 396 overloaded_method_names = set(name |
| 377 for name, count in method_counts.iteritems() | 397 for name, count in method_counts.iteritems() |
| 378 if count > 1) | 398 if count > 1) |
| 379 overloaded_methods = [method for method in methods | 399 overloaded_methods = [method for method in methods |
| 380 if method['name'] in overloaded_method_names] | 400 if method['name'] in overloaded_method_names] |
| 381 | 401 |
| 382 # Group by name (generally will be defined together, but not necessarily) | 402 # Group by name (generally will be defined together, but not necessarily) |
| 383 return sort_and_groupby(overloaded_methods, itemgetter('name')) | 403 return sort_and_groupby(overloaded_methods, itemgetter('name')) |
| 384 | 404 |
| 385 | 405 |
| 386 def generate_overloads(overloads): | 406 def overloads_context(overloads): |
| 387 """Returns |overloads| template values for a single name. | 407 """Returns |overloads| template values for a single name. |
| 388 | 408 |
| 389 Sets |method.overload_index| in place for |method| in |overloads| | 409 Sets |method.overload_index| in place for |method| in |overloads| |
| 390 and returns dict of overall overload template values. | 410 and returns dict of overall overload template values. |
| 391 """ | 411 """ |
| 392 assert len(overloads) > 1 # only apply to overloaded names | 412 assert len(overloads) > 1 # only apply to overloaded names |
| 393 for index, method in enumerate(overloads, 1): | 413 for index, method in enumerate(overloads, 1): |
| 394 method['overload_index'] = index | 414 method['overload_index'] = index |
| 395 | 415 |
| 396 effective_overloads_by_length = effective_overload_set_by_length(overloads) | 416 effective_overloads_by_length = effective_overload_set_by_length(overloads) |
| (...skipping 20 matching lines...) Expand all Loading... |
| 417 overload_extended_attributes = [ | 437 overload_extended_attributes = [ |
| 418 method['custom_registration_extended_attributes'] | 438 method['custom_registration_extended_attributes'] |
| 419 for method in overloads] | 439 for method in overloads] |
| 420 for extended_attribute in v8_methods.CUSTOM_REGISTRATION_EXTENDED_ATTRIB
UTES: | 440 for extended_attribute in v8_methods.CUSTOM_REGISTRATION_EXTENDED_ATTRIB
UTES: |
| 421 if common_key(overload_extended_attributes, extended_attribute) is N
one: | 441 if common_key(overload_extended_attributes, extended_attribute) is N
one: |
| 422 raise ValueError('Overloads of %s have conflicting extended attr
ibute %s' | 442 raise ValueError('Overloads of %s have conflicting extended attr
ibute %s' |
| 423 % (name, extended_attribute)) | 443 % (name, extended_attribute)) |
| 424 | 444 |
| 425 return { | 445 return { |
| 426 'deprecate_all_as': common_value(overloads, 'deprecate_as'), # [Depreca
teAs] | 446 'deprecate_all_as': common_value(overloads, 'deprecate_as'), # [Depreca
teAs] |
| 447 'exposed_test_all': common_value(overloads, 'exposed_test'), # [Exposed
] |
| 448 'has_custom_registration_all': common_value(overloads, 'has_custom_regis
tration'), |
| 427 'length_tests_methods': length_tests_methods(effective_overloads_by_leng
th), | 449 'length_tests_methods': length_tests_methods(effective_overloads_by_leng
th), |
| 428 'minarg': lengths[0], | |
| 429 # 1. Let maxarg be the length of the longest type list of the | 450 # 1. Let maxarg be the length of the longest type list of the |
| 430 # entries in S. | 451 # entries in S. |
| 431 'maxarg': lengths[-1], | 452 'maxarg': lengths[-1], |
| 432 'measure_all_as': common_value(overloads, 'measure_as'), # [MeasureAs] | 453 'measure_all_as': common_value(overloads, 'measure_as'), # [MeasureAs] |
| 433 'has_custom_registration_all': common_value(overloads, 'has_custom_regis
tration'), | 454 'minarg': lengths[0], |
| 434 'per_context_enabled_function_all': common_value(overloads, 'per_context
_enabled_function'), # [PerContextEnabled] | 455 'per_context_enabled_function_all': common_value(overloads, 'per_context
_enabled_function'), # [PerContextEnabled] |
| 435 'runtime_enabled_function_all': common_value(overloads, 'runtime_enabled
_function'), # [RuntimeEnabled] | 456 'runtime_enabled_function_all': common_value(overloads, 'runtime_enabled
_function'), # [RuntimeEnabled] |
| 436 'valid_arities': lengths | 457 'valid_arities': lengths |
| 437 # Only need to report valid arities if there is a gap in the | 458 # Only need to report valid arities if there is a gap in the |
| 438 # sequence of possible lengths, otherwise invalid length means | 459 # sequence of possible lengths, otherwise invalid length means |
| 439 # "not enough arguments". | 460 # "not enough arguments". |
| 440 if lengths[-1] - lengths[0] != len(lengths) - 1 else None, | 461 if lengths[-1] - lengths[0] != len(lengths) - 1 else None, |
| 441 } | 462 } |
| 442 | 463 |
| 443 | 464 |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 698 # 4. Otherwise: if V is a platform object – but not a platform array | 719 # 4. Otherwise: if V is a platform object – but not a platform array |
| 699 # object – and there is an entry in S that has one of the following | 720 # object – and there is an entry in S that has one of the following |
| 700 # types at position i of its type list, | 721 # types at position i of its type list, |
| 701 # • an interface type that V implements | 722 # • an interface type that V implements |
| 702 # (Unlike most of these tests, this can return multiple methods, since we | 723 # (Unlike most of these tests, this can return multiple methods, since we |
| 703 # test if it implements an interface. Thus we need a for loop, not a next.) | 724 # test if it implements an interface. Thus we need a for loop, not a next.) |
| 704 # (We distinguish wrapper types from built-in interface types.) | 725 # (We distinguish wrapper types from built-in interface types.) |
| 705 for idl_type, method in ((idl_type, method) | 726 for idl_type, method in ((idl_type, method) |
| 706 for idl_type, method in idl_types_methods | 727 for idl_type, method in idl_types_methods |
| 707 if idl_type.is_wrapper_type): | 728 if idl_type.is_wrapper_type): |
| 708 test = 'V8{idl_type}::hasInstance({cpp_value}, isolate)'.format(idl_type
=idl_type.base_type, cpp_value=cpp_value) | 729 test = 'V8{idl_type}::hasInstance({cpp_value}, info.GetIsolate())'.forma
t(idl_type=idl_type.base_type, cpp_value=cpp_value) |
| 709 yield test, method | 730 yield test, method |
| 710 | 731 |
| 711 # 8. Otherwise: if V is any kind of object except for a native Date object, | 732 # 8. Otherwise: if V is any kind of object except for a native Date object, |
| 712 # a native RegExp object, and there is an entry in S that has one of the | 733 # a native RegExp object, and there is an entry in S that has one of the |
| 713 # following types at position i of its type list, | 734 # following types at position i of its type list, |
| 714 # • an array type | 735 # • an array type |
| 715 # • a sequence type | 736 # • a sequence type |
| 716 # ... | 737 # ... |
| 717 # • a dictionary | 738 # • a dictionary |
| 718 try: | 739 try: |
| 719 # FIXME: IDL dictionary not implemented, so use Blink Dictionary | 740 # FIXME: IDL dictionary not implemented, so use Blink Dictionary |
| 720 # http://crbug.com/321462 | 741 # http://crbug.com/321462 |
| 721 idl_type, method = next((idl_type, method) | 742 idl_type, method = next((idl_type, method) |
| 722 for idl_type, method in idl_types_methods | 743 for idl_type, method in idl_types_methods |
| 723 if (idl_type.array_or_sequence_type or | 744 if (idl_type.native_array_element_type or |
| 724 idl_type.name == 'Dictionary')) | 745 idl_type.name == 'Dictionary')) |
| 725 if idl_type.array_or_sequence_type: | 746 if idl_type.native_array_element_type: |
| 726 # (We test for Array instead of generic Object to type-check.) | 747 # (We test for Array instead of generic Object to type-check.) |
| 727 # FIXME: test for Object during resolution, then have type check for | 748 # FIXME: test for Object during resolution, then have type check for |
| 728 # Array in overloaded method: http://crbug.com/262383 | 749 # Array in overloaded method: http://crbug.com/262383 |
| 729 test = '%s->IsArray()' % cpp_value | 750 test = '%s->IsArray()' % cpp_value |
| 730 else: | 751 else: |
| 731 # FIXME: should be '{1}->IsObject() && !{1}->IsDate() && !{1}->IsReg
Exp()'.format(cpp_value) | 752 # FIXME: should be '{1}->IsObject() && !{1}->IsDate() && !{1}->IsReg
Exp()'.format(cpp_value) |
| 732 # FIXME: the IsDate and IsRegExp checks can be skipped if we've | 753 # FIXME: the IsDate and IsRegExp checks can be skipped if we've |
| 733 # already generated tests for them. | 754 # already generated tests for them. |
| 734 test = '%s->IsObject()' % cpp_value | 755 test = '%s->IsObject()' % cpp_value |
| 735 yield test, method | 756 yield test, method |
| 736 except StopIteration: | 757 except StopIteration: |
| 737 pass | 758 pass |
| 738 | 759 |
| 739 # (Check for exact type matches before performing automatic type conversion; | 760 # (Check for exact type matches before performing automatic type conversion; |
| 740 # only needed if distinguishing between primitive types.) | 761 # only needed if distinguishing between primitive types.) |
| 741 if len([idl_type.is_primitive_type for idl_type in idl_types]) > 1: | 762 if len([idl_type.is_primitive_type for idl_type in idl_types]) > 1: |
| 742 # (Only needed if match in step 11, otherwise redundant.) | 763 # (Only needed if match in step 11, otherwise redundant.) |
| 743 if any(idl_type.name == 'String' or idl_type.is_enum | 764 if any(idl_type.is_string_type or idl_type.is_enum |
| 744 for idl_type in idl_types): | 765 for idl_type in idl_types): |
| 745 # 10. Otherwise: if V is a Number value, and there is an entry in S | 766 # 10. Otherwise: if V is a Number value, and there is an entry in S |
| 746 # that has one of the following types at position i of its type | 767 # that has one of the following types at position i of its type |
| 747 # list, | 768 # list, |
| 748 # • a numeric type | 769 # • a numeric type |
| 749 try: | 770 try: |
| 750 method = next(method for idl_type, method in idl_types_methods | 771 method = next(method for idl_type, method in idl_types_methods |
| 751 if idl_type.is_numeric_type) | 772 if idl_type.is_numeric_type) |
| 752 test = '%s->IsNumber()' % cpp_value | 773 test = '%s->IsNumber()' % cpp_value |
| 753 yield test, method | 774 yield test, method |
| 754 except StopIteration: | 775 except StopIteration: |
| 755 pass | 776 pass |
| 756 | 777 |
| 757 # (Perform automatic type conversion, in order. If any of these match, | 778 # (Perform automatic type conversion, in order. If any of these match, |
| 758 # that’s the end, and no other tests are needed.) To keep this code simple, | 779 # that’s the end, and no other tests are needed.) To keep this code simple, |
| 759 # we rely on the C++ compiler's dead code elimination to deal with the | 780 # we rely on the C++ compiler's dead code elimination to deal with the |
| 760 # redundancy if both cases below trigger. | 781 # redundancy if both cases below trigger. |
| 761 | 782 |
| 762 # 11. Otherwise: if there is an entry in S that has one of the following | 783 # 11. Otherwise: if there is an entry in S that has one of the following |
| 763 # types at position i of its type list, | 784 # types at position i of its type list, |
| 764 # • DOMString | 785 # • DOMString |
| 786 # • ByteString |
| 787 # • ScalarValueString [a DOMString typedef, per definition.] |
| 765 # • an enumeration type | 788 # • an enumeration type |
| 766 # * ByteString | |
| 767 # Blink: ScalarValueString is a pending Web IDL addition | |
| 768 try: | 789 try: |
| 769 method = next(method for idl_type, method in idl_types_methods | 790 method = next(method for idl_type, method in idl_types_methods |
| 770 if idl_type.name in ('String', | 791 if idl_type.is_string_type or idl_type.is_enum) |
| 771 'ByteString', | |
| 772 'ScalarValueString') or | |
| 773 idl_type.is_enum) | |
| 774 yield 'true', method | 792 yield 'true', method |
| 775 except StopIteration: | 793 except StopIteration: |
| 776 pass | 794 pass |
| 777 | 795 |
| 778 # 12. Otherwise: if there is an entry in S that has one of the following | 796 # 12. Otherwise: if there is an entry in S that has one of the following |
| 779 # types at position i of its type list, | 797 # types at position i of its type list, |
| 780 # • a numeric type | 798 # • a numeric type |
| 781 try: | 799 try: |
| 782 method = next(method for idl_type, method in idl_types_methods | 800 method = next(method for idl_type, method in idl_types_methods |
| 783 if idl_type.is_numeric_type) | 801 if idl_type.is_numeric_type) |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 832 """Returns a generator of (key, list), sorting and grouping list by key.""" | 850 """Returns a generator of (key, list), sorting and grouping list by key.""" |
| 833 l.sort(key=key) | 851 l.sort(key=key) |
| 834 return ((k, list(g)) for k, g in itertools.groupby(l, key)) | 852 return ((k, list(g)) for k, g in itertools.groupby(l, key)) |
| 835 | 853 |
| 836 | 854 |
| 837 ################################################################################ | 855 ################################################################################ |
| 838 # Constructors | 856 # Constructors |
| 839 ################################################################################ | 857 ################################################################################ |
| 840 | 858 |
| 841 # [Constructor] | 859 # [Constructor] |
| 842 def generate_constructor(interface, constructor): | 860 def constructor_context(interface, constructor): |
| 843 arguments_need_try_catch = any(v8_methods.argument_needs_try_catch(argument) | 861 arguments_need_try_catch = any(v8_methods.argument_needs_try_catch(argument,
return_promise=False) |
| 844 for argument in constructor.arguments) | 862 for argument in constructor.arguments) |
| 845 | 863 |
| 864 # [RaisesException=Constructor] |
| 865 is_constructor_raises_exception = \ |
| 866 interface.extended_attributes.get('RaisesException') == 'Constructor' |
| 867 |
| 846 return { | 868 return { |
| 847 'arguments': [v8_methods.generate_argument(interface, constructor, argum
ent, index) | 869 'arguments': [v8_methods.argument_context(interface, constructor, argume
nt, index) |
| 848 for index, argument in enumerate(constructor.arguments)], | 870 for index, argument in enumerate(constructor.arguments)], |
| 849 'arguments_need_try_catch': arguments_need_try_catch, | 871 'arguments_need_try_catch': arguments_need_try_catch, |
| 850 'cpp_type': cpp_template_type( | 872 'cpp_type': cpp_template_type( |
| 851 cpp_ptr_type('RefPtr', 'RawPtr', gc_type(interface)), | 873 cpp_ptr_type('RefPtr', 'RawPtr', gc_type(interface)), |
| 852 cpp_name(interface)), | 874 cpp_name(interface)), |
| 853 'cpp_value': v8_methods.cpp_value( | 875 'cpp_value': v8_methods.cpp_value( |
| 854 interface, constructor, len(constructor.arguments)), | 876 interface, constructor, len(constructor.arguments)), |
| 855 'has_exception_state': | 877 'has_exception_state': |
| 856 # [RaisesException=Constructor] | 878 is_constructor_raises_exception or |
| 857 interface.extended_attributes.get('RaisesException') == 'Constructor
' or | |
| 858 any(argument for argument in constructor.arguments | 879 any(argument for argument in constructor.arguments |
| 859 if argument.idl_type.name == 'SerializedScriptValue' or | 880 if argument.idl_type.name == 'SerializedScriptValue' or |
| 860 argument.idl_type.is_integer_type), | 881 argument.idl_type.may_raise_exception_on_conversion), |
| 882 'is_call_with_document': |
| 883 # [ConstructorCallWith=Document] |
| 884 has_extended_attribute_value(interface, |
| 885 'ConstructorCallWith', 'Document'), |
| 886 'is_call_with_execution_context': |
| 887 # [ConstructorCallWith=ExecutionContext] |
| 888 has_extended_attribute_value(interface, |
| 889 'ConstructorCallWith', 'ExecutionContext'), |
| 861 'is_constructor': True, | 890 'is_constructor': True, |
| 862 'is_named_constructor': False, | 891 'is_named_constructor': False, |
| 892 'is_raises_exception': is_constructor_raises_exception, |
| 863 'number_of_required_arguments': | 893 'number_of_required_arguments': |
| 864 number_of_required_arguments(constructor), | 894 number_of_required_arguments(constructor), |
| 865 } | 895 } |
| 866 | 896 |
| 867 | 897 |
| 868 # [NamedConstructor] | 898 # [NamedConstructor] |
| 869 def generate_named_constructor(interface): | 899 def named_constructor_context(interface): |
| 870 extended_attributes = interface.extended_attributes | 900 extended_attributes = interface.extended_attributes |
| 871 if 'NamedConstructor' not in extended_attributes: | 901 if 'NamedConstructor' not in extended_attributes: |
| 872 return None | 902 return None |
| 873 # FIXME: parser should return named constructor separately; | 903 # FIXME: parser should return named constructor separately; |
| 874 # included in constructors (and only name stored in extended attribute) | 904 # included in constructors (and only name stored in extended attribute) |
| 875 # for Perl compatibility | 905 # for Perl compatibility |
| 876 idl_constructor = interface.constructors[-1] | 906 idl_constructor = interface.constructors[-1] |
| 877 assert idl_constructor.name == 'NamedConstructor' | 907 assert idl_constructor.name == 'NamedConstructor' |
| 878 constructor = generate_constructor(interface, idl_constructor) | 908 context = constructor_context(interface, idl_constructor) |
| 879 constructor.update({ | 909 context.update({ |
| 880 'name': extended_attributes['NamedConstructor'], | 910 'name': extended_attributes['NamedConstructor'], |
| 881 'is_named_constructor': True, | 911 'is_named_constructor': True, |
| 882 }) | 912 }) |
| 883 return constructor | 913 return context |
| 884 | 914 |
| 885 | 915 |
| 886 def number_of_required_arguments(constructor): | 916 def number_of_required_arguments(constructor): |
| 887 return len([argument for argument in constructor.arguments | 917 return len([argument for argument in constructor.arguments |
| 888 if not argument.is_optional]) | 918 if not argument.is_optional]) |
| 889 | 919 |
| 890 | 920 |
| 891 def interface_length(interface, constructors): | 921 def interface_length(interface, constructors): |
| 892 # Docs: http://heycam.github.io/webidl/#es-interface-call | 922 # Docs: http://heycam.github.io/webidl/#es-interface-call |
| 893 if 'EventConstructor' in interface.extended_attributes: | 923 if 'EventConstructor' in interface.extended_attributes: |
| 894 return 1 | 924 return 1 |
| 895 if not constructors: | 925 if not constructors: |
| 896 return 0 | 926 return 0 |
| 897 return min(constructor['number_of_required_arguments'] | 927 return min(constructor['number_of_required_arguments'] |
| 898 for constructor in constructors) | 928 for constructor in constructors) |
| 899 | 929 |
| 900 | 930 |
| 901 ################################################################################ | 931 ################################################################################ |
| 902 # Special operations (methods) | 932 # Special operations (methods) |
| 903 # http://heycam.github.io/webidl/#idl-special-operations | 933 # http://heycam.github.io/webidl/#idl-special-operations |
| 904 ################################################################################ | 934 ################################################################################ |
| 905 | 935 |
| 906 def property_getter(getter, cpp_arguments): | 936 def property_getter(getter, cpp_arguments): |
| 907 def is_null_expression(idl_type): | 937 def is_null_expression(idl_type): |
| 908 if idl_type.is_union_type: | 938 if idl_type.is_union_type: |
| 909 return ' && '.join('!result%sEnabled' % i | 939 notnull = ' || '.join([ |
| 910 for i, _ in enumerate(idl_type.member_types)) | 940 member_argument['null_check_value'] |
| 941 for member_argument in idl_type.union_arguments]) |
| 942 return '!(%s)' % notnull |
| 911 if idl_type.name == 'String': | 943 if idl_type.name == 'String': |
| 912 return 'result.isNull()' | 944 return 'result.isNull()' |
| 913 if idl_type.is_interface_type: | 945 if idl_type.is_interface_type: |
| 914 return '!result' | 946 return '!result' |
| 915 return '' | 947 return '' |
| 916 | 948 |
| 917 idl_type = getter.idl_type | 949 idl_type = getter.idl_type |
| 918 extended_attributes = getter.extended_attributes | 950 extended_attributes = getter.extended_attributes |
| 919 is_raises_exception = 'RaisesException' in extended_attributes | 951 is_raises_exception = 'RaisesException' in extended_attributes |
| 920 | 952 |
| 921 # FIXME: make more generic, so can use v8_methods.cpp_value | 953 # FIXME: make more generic, so can use v8_methods.cpp_value |
| 922 cpp_method_name = 'impl->%s' % cpp_name(getter) | 954 cpp_method_name = 'impl->%s' % cpp_name(getter) |
| 923 | 955 |
| 924 if is_raises_exception: | 956 if is_raises_exception: |
| 925 cpp_arguments.append('exceptionState') | 957 cpp_arguments.append('exceptionState') |
| 926 union_arguments = idl_type.union_arguments | 958 union_arguments = idl_type.union_arguments |
| 927 if union_arguments: | 959 if union_arguments: |
| 928 cpp_arguments.extend(union_arguments) | 960 cpp_arguments.extend([member_argument['cpp_value'] |
| 961 for member_argument in union_arguments]) |
| 929 | 962 |
| 930 cpp_value = '%s(%s)' % (cpp_method_name, ', '.join(cpp_arguments)) | 963 cpp_value = '%s(%s)' % (cpp_method_name, ', '.join(cpp_arguments)) |
| 931 | 964 |
| 932 return { | 965 return { |
| 933 'cpp_type': idl_type.cpp_type, | 966 'cpp_type': idl_type.cpp_type, |
| 934 'cpp_value': cpp_value, | 967 'cpp_value': cpp_value, |
| 935 'is_custom': | 968 'is_custom': |
| 936 'Custom' in extended_attributes and | 969 'Custom' in extended_attributes and |
| 937 (not extended_attributes['Custom'] or | 970 (not extended_attributes['Custom'] or |
| 938 has_extended_attribute_value(getter, 'Custom', 'PropertyGetter')), | 971 has_extended_attribute_value(getter, 'Custom', 'PropertyGetter')), |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1080 deleter = next( | 1113 deleter = next( |
| 1081 method | 1114 method |
| 1082 for method in interface.operations | 1115 for method in interface.operations |
| 1083 if ('deleter' in method.specials and | 1116 if ('deleter' in method.specials and |
| 1084 len(method.arguments) == 1 and | 1117 len(method.arguments) == 1 and |
| 1085 str(method.arguments[0].idl_type) == 'DOMString')) | 1118 str(method.arguments[0].idl_type) == 'DOMString')) |
| 1086 except StopIteration: | 1119 except StopIteration: |
| 1087 return None | 1120 return None |
| 1088 | 1121 |
| 1089 return property_deleter(deleter) | 1122 return property_deleter(deleter) |
| OLD | NEW |