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 |