OLD | NEW |
1 # Copyright (C) 2013 Google Inc. All rights reserved. | 1 # Copyright (C) 2013 Google Inc. All rights reserved. |
2 # | 2 # |
3 # Redistribution and use in source and binary forms, with or without | 3 # Redistribution and use in source and binary forms, with or without |
4 # modification, are permitted provided that the following conditions are | 4 # modification, are permitted provided that the following conditions are |
5 # met: | 5 # met: |
6 # | 6 # |
7 # * Redistributions of source code must retain the above copyright | 7 # * Redistributions of source code must retain the above copyright |
8 # notice, this list of conditions and the following disclaimer. | 8 # notice, this list of conditions and the following disclaimer. |
9 # * Redistributions in binary form must reproduce the above | 9 # * Redistributions in binary form must reproduce the above |
10 # copyright notice, this list of conditions and the following disclaimer | 10 # copyright notice, this list of conditions and the following disclaimer |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
48 # V8-specific handling of IDL types | 48 # V8-specific handling of IDL types |
49 ################################################################################ | 49 ################################################################################ |
50 | 50 |
51 NON_WRAPPER_TYPES = frozenset([ | 51 NON_WRAPPER_TYPES = frozenset([ |
52 'Dictionary', | 52 'Dictionary', |
53 'EventHandler', | 53 'EventHandler', |
54 'EventListener', | 54 'EventListener', |
55 'NodeFilter', | 55 'NodeFilter', |
56 'SerializedScriptValue', | 56 'SerializedScriptValue', |
57 ]) | 57 ]) |
58 TYPED_ARRAYS = { | 58 TYPED_ARRAY_TYPES = frozenset([ |
59 # (cpp_type, v8_type), used by constructor templates | 59 'Float32Array', |
60 'ArrayBuffer': None, | 60 'Float64Array', |
61 'ArrayBufferView': None, | 61 'Int8Array', |
62 'Float32Array': ('float', 'v8::kExternalFloatArray'), | 62 'Int16Array', |
63 'Float64Array': ('double', 'v8::kExternalDoubleArray'), | 63 'Int32Array', |
64 'Int8Array': ('signed char', 'v8::kExternalByteArray'), | 64 'Uint8Array', |
65 'Int16Array': ('short', 'v8::kExternalShortArray'), | 65 'Uint8ClampedArray', |
66 'Int32Array': ('int', 'v8::kExternalIntArray'), | 66 'Uint16Array', |
67 'Uint8Array': ('unsigned char', 'v8::kExternalUnsignedByteArray'), | 67 'Uint32Array', |
68 'Uint8ClampedArray': ('unsigned char', 'v8::kExternalPixelArray'), | 68 ]) |
69 'Uint16Array': ('unsigned short', 'v8::kExternalUnsignedShortArray'), | 69 ARRAY_BUFFER_AND_VIEW_TYPES = TYPED_ARRAY_TYPES.union(frozenset([ |
70 'Uint32Array': ('unsigned int', 'v8::kExternalUnsignedIntArray'), | 70 'ArrayBuffer', |
71 } | 71 'ArrayBufferView', |
| 72 'DataView', |
| 73 ])) |
72 | 74 |
73 IdlType.is_typed_array_element_type = property( | 75 IdlType.is_array_buffer_or_view = property( |
74 lambda self: self.base_type in TYPED_ARRAYS) | 76 lambda self: self.base_type in ARRAY_BUFFER_AND_VIEW_TYPES) |
| 77 |
| 78 IdlType.is_typed_array = property( |
| 79 lambda self: self.base_type in TYPED_ARRAY_TYPES) |
75 | 80 |
76 IdlType.is_wrapper_type = property( | 81 IdlType.is_wrapper_type = property( |
77 lambda self: (self.is_interface_type and | 82 lambda self: (self.is_interface_type and |
| 83 not self.is_callback_interface and |
78 self.base_type not in NON_WRAPPER_TYPES)) | 84 self.base_type not in NON_WRAPPER_TYPES)) |
79 | 85 |
80 | 86 |
81 ################################################################################ | 87 ################################################################################ |
82 # C++ types | 88 # C++ types |
83 ################################################################################ | 89 ################################################################################ |
84 | 90 |
85 CPP_TYPE_SAME_AS_IDL_TYPE = set([ | 91 CPP_TYPE_SAME_AS_IDL_TYPE = set([ |
86 'double', | 92 'double', |
87 'float', | 93 'float', |
(...skipping 12 matching lines...) Expand all Loading... |
100 'unsigned short', | 106 'unsigned short', |
101 ]) | 107 ]) |
102 CPP_SPECIAL_CONVERSION_RULES = { | 108 CPP_SPECIAL_CONVERSION_RULES = { |
103 'Date': 'double', | 109 'Date': 'double', |
104 'Dictionary': 'Dictionary', | 110 'Dictionary': 'Dictionary', |
105 'EventHandler': 'EventListener*', | 111 'EventHandler': 'EventListener*', |
106 'NodeFilter': 'RefPtrWillBeRawPtr<NodeFilter>', | 112 'NodeFilter': 'RefPtrWillBeRawPtr<NodeFilter>', |
107 'Promise': 'ScriptPromise', | 113 'Promise': 'ScriptPromise', |
108 'ScriptValue': 'ScriptValue', | 114 'ScriptValue': 'ScriptValue', |
109 # FIXME: Eliminate custom bindings for XPathNSResolver http://crbug.com/345
529 | 115 # FIXME: Eliminate custom bindings for XPathNSResolver http://crbug.com/345
529 |
110 'XPathNSResolver': 'RefPtrWillBeRawPtr<XPathNSResolver>', | 116 'XPathNSResolver': 'RawPtr<XPathNSResolver>', |
111 'boolean': 'bool', | 117 'boolean': 'bool', |
112 'unrestricted double': 'double', | 118 'unrestricted double': 'double', |
113 'unrestricted float': 'float', | 119 'unrestricted float': 'float', |
114 } | 120 } |
115 | 121 |
116 | 122 |
117 def cpp_type(idl_type, extended_attributes=None, raw_type=False, used_as_rvalue_
type=False, used_as_variadic_argument=False, used_in_cpp_sequence=False): | 123 def cpp_type(idl_type, extended_attributes=None, raw_type=False, used_as_rvalue_
type=False, used_as_variadic_argument=False, used_in_cpp_sequence=False): |
118 """Returns C++ type corresponding to IDL type. | 124 """Returns C++ type corresponding to IDL type. |
119 | 125 |
120 |idl_type| argument is of type IdlType, while return value is a string | 126 |idl_type| argument is of type IdlType, while return value is a string |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 if base_idl_type in CPP_SPECIAL_CONVERSION_RULES: | 175 if base_idl_type in CPP_SPECIAL_CONVERSION_RULES: |
170 return CPP_SPECIAL_CONVERSION_RULES[base_idl_type] | 176 return CPP_SPECIAL_CONVERSION_RULES[base_idl_type] |
171 | 177 |
172 if base_idl_type in NON_WRAPPER_TYPES: | 178 if base_idl_type in NON_WRAPPER_TYPES: |
173 return ('PassRefPtr<%s>' if used_as_rvalue_type else 'RefPtr<%s>') % bas
e_idl_type | 179 return ('PassRefPtr<%s>' if used_as_rvalue_type else 'RefPtr<%s>') % bas
e_idl_type |
174 if idl_type.is_string_type: | 180 if idl_type.is_string_type: |
175 if not raw_type: | 181 if not raw_type: |
176 return 'String' | 182 return 'String' |
177 return 'V8StringResource<%s>' % string_mode() | 183 return 'V8StringResource<%s>' % string_mode() |
178 | 184 |
179 if idl_type.is_typed_array_element_type and raw_type: | 185 if idl_type.is_array_buffer_or_view and raw_type: |
180 return base_idl_type + '*' | 186 return idl_type.implemented_as + '*' |
181 if idl_type.is_interface_type: | 187 if idl_type.is_interface_type: |
182 implemented_as_class = idl_type.implemented_as | 188 implemented_as_class = idl_type.implemented_as |
183 if raw_type: | 189 if raw_type or (used_as_rvalue_type and idl_type.is_garbage_collected): |
184 return implemented_as_class + '*' | 190 return implemented_as_class + '*' |
185 new_type = 'Member' if used_in_cpp_sequence else 'RawPtr' | 191 new_type = 'Member' if used_in_cpp_sequence else 'RawPtr' |
186 ptr_type = cpp_ptr_type(('PassRefPtr' if used_as_rvalue_type else 'RefPt
r'), new_type, idl_type.gc_type) | 192 ptr_type = cpp_ptr_type(('PassRefPtr' if used_as_rvalue_type else 'RefPt
r'), new_type, idl_type.gc_type) |
187 return cpp_template_type(ptr_type, implemented_as_class) | 193 return cpp_template_type(ptr_type, implemented_as_class) |
| 194 if idl_type.is_dictionary: |
| 195 return base_idl_type |
| 196 if idl_type.is_union_type: |
| 197 # Avoid "AOrNullOrB" for cpp type of (A? or B) because we generate |
| 198 # V8AOrBOrNull to handle nulle for (A? or B), (A or B?) and (A or B)? |
| 199 def member_cpp_name(idl_type): |
| 200 if idl_type.is_nullable: |
| 201 return idl_type.inner_type.name |
| 202 return idl_type.name |
| 203 idl_type_name = "Or".join(member_cpp_name(member) |
| 204 for member in idl_type.member_types) |
| 205 return 'const %s&' % idl_type_name if used_as_rvalue_type else idl_type_
name |
| 206 |
188 # Default, assume native type is a pointer with same type name as idl type | 207 # Default, assume native type is a pointer with same type name as idl type |
189 return base_idl_type + '*' | 208 return base_idl_type + '*' |
190 | 209 |
191 | 210 |
192 def cpp_type_initializer(idl_type): | 211 def cpp_type_initializer(idl_type): |
193 """Returns a string containing a C++ initialization statement for the | 212 """Returns a string containing a C++ initialization statement for the |
194 corresponding type. | 213 corresponding type. |
195 | 214 |
196 |idl_type| argument is of type IdlType. | 215 |idl_type| argument is of type IdlType. |
197 """ | 216 """ |
198 | 217 |
199 base_idl_type = idl_type.base_type | 218 base_idl_type = idl_type.base_type |
200 | 219 |
201 if idl_type.native_array_element_type: | 220 if idl_type.native_array_element_type: |
202 return '' | 221 return '' |
203 if idl_type.is_numeric_type: | 222 if idl_type.is_numeric_type: |
204 return ' = 0' | 223 return ' = 0' |
205 if base_idl_type == 'boolean': | 224 if base_idl_type == 'boolean': |
206 return ' = false' | 225 return ' = false' |
207 if idl_type.base_type == 'Promise': | |
208 return '(nullptr)' | |
209 | |
210 if (base_idl_type in NON_WRAPPER_TYPES or | 226 if (base_idl_type in NON_WRAPPER_TYPES or |
211 base_idl_type in CPP_SPECIAL_CONVERSION_RULES or | 227 base_idl_type in CPP_SPECIAL_CONVERSION_RULES or |
212 base_idl_type == 'any' or | 228 base_idl_type == 'any' or |
213 idl_type.is_string_type or | 229 idl_type.is_string_type or |
214 idl_type.is_enum): | 230 idl_type.is_enum): |
215 return '' | 231 return '' |
216 return ' = nullptr' | 232 return ' = nullptr' |
217 | 233 |
218 | 234 |
219 def cpp_type_union(idl_type, extended_attributes=None, raw_type=False): | |
220 # FIXME: Need to revisit the design of union support. | |
221 # http://crbug.com/240176 | |
222 return None | |
223 | |
224 | |
225 def cpp_type_initializer_union(idl_type): | |
226 return (member_type.cpp_type_initializer for member_type in idl_type.member_
types) | |
227 | |
228 | |
229 # Allow access as idl_type.cpp_type if no arguments | 235 # Allow access as idl_type.cpp_type if no arguments |
230 IdlTypeBase.cpp_type = property(cpp_type) | 236 IdlTypeBase.cpp_type = property(cpp_type) |
231 IdlTypeBase.cpp_type_initializer = property(cpp_type_initializer) | 237 IdlTypeBase.cpp_type_initializer = property(cpp_type_initializer) |
232 IdlTypeBase.cpp_type_args = cpp_type | 238 IdlTypeBase.cpp_type_args = cpp_type |
233 IdlUnionType.cpp_type = property(cpp_type_union) | 239 IdlUnionType.cpp_type_initializer = '' |
234 IdlUnionType.cpp_type_initializer = property(cpp_type_initializer_union) | |
235 IdlUnionType.cpp_type_args = cpp_type_union | |
236 | 240 |
237 | 241 |
238 IdlArrayOrSequenceType.native_array_element_type = property( | 242 IdlArrayOrSequenceType.native_array_element_type = property( |
239 lambda self: self.element_type) | 243 lambda self: self.element_type) |
240 | 244 |
241 | 245 |
242 def cpp_template_type(template, inner_type): | 246 def cpp_template_type(template, inner_type): |
243 """Returns C++ template specialized to type, with space added if needed.""" | 247 """Returns C++ template specialized to type.""" |
244 if inner_type.endswith('>'): | 248 format_string = '{template}<{inner_type}>' |
245 format_string = '{template}<{inner_type} >' | |
246 else: | |
247 format_string = '{template}<{inner_type}>' | |
248 return format_string.format(template=template, inner_type=inner_type) | 249 return format_string.format(template=template, inner_type=inner_type) |
249 | 250 |
250 | 251 |
251 def cpp_ptr_type(old_type, new_type, gc_type): | 252 def cpp_ptr_type(old_type, new_type, gc_type): |
252 if gc_type == 'GarbageCollectedObject': | 253 if gc_type == 'GarbageCollectedObject': |
253 return new_type | 254 return new_type |
254 if gc_type == 'WillBeGarbageCollectedObject': | 255 if gc_type == 'WillBeGarbageCollectedObject': |
255 if old_type == 'Vector': | 256 if old_type == 'Vector': |
256 return 'WillBe' + new_type | 257 return 'WillBe' + new_type |
257 return old_type + 'WillBe' + new_type | 258 return old_type + 'WillBe' + new_type |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
303 | 304 |
304 IdlType.is_will_be_garbage_collected = property( | 305 IdlType.is_will_be_garbage_collected = property( |
305 lambda self: self.base_type in IdlType.will_be_garbage_collected_types) | 306 lambda self: self.base_type in IdlType.will_be_garbage_collected_types) |
306 | 307 |
307 IdlType.set_will_be_garbage_collected_types = classmethod( | 308 IdlType.set_will_be_garbage_collected_types = classmethod( |
308 lambda cls, new_will_be_garbage_collected_types: | 309 lambda cls, new_will_be_garbage_collected_types: |
309 cls.will_be_garbage_collected_types.update(new_will_be_garbage_collected
_types)) | 310 cls.will_be_garbage_collected_types.update(new_will_be_garbage_collected
_types)) |
310 | 311 |
311 | 312 |
312 def gc_type(idl_type): | 313 def gc_type(idl_type): |
313 if idl_type.is_garbage_collected: | 314 if idl_type.is_garbage_collected or idl_type.is_dictionary or idl_type.is_un
ion_type: |
314 return 'GarbageCollectedObject' | 315 return 'GarbageCollectedObject' |
315 if idl_type.is_will_be_garbage_collected: | 316 if idl_type.is_will_be_garbage_collected: |
316 return 'WillBeGarbageCollectedObject' | 317 return 'WillBeGarbageCollectedObject' |
317 return 'RefCountedObject' | 318 return 'RefCountedObject' |
318 | 319 |
319 IdlTypeBase.gc_type = property(gc_type) | 320 IdlTypeBase.gc_type = property(gc_type) |
320 | 321 |
321 | 322 |
| 323 def is_traceable(idl_type): |
| 324 return (idl_type.is_garbage_collected |
| 325 or idl_type.is_will_be_garbage_collected |
| 326 or idl_type.is_dictionary) |
| 327 |
| 328 IdlTypeBase.is_traceable = property(is_traceable) |
| 329 IdlUnionType.is_traceable = property(lambda self: True) |
| 330 IdlArrayOrSequenceType.is_traceable = property( |
| 331 lambda self: self.element_type.is_traceable) |
| 332 |
| 333 |
322 ################################################################################ | 334 ################################################################################ |
323 # Includes | 335 # Includes |
324 ################################################################################ | 336 ################################################################################ |
325 | 337 |
326 def includes_for_cpp_class(class_name, relative_dir_posix): | 338 def includes_for_cpp_class(class_name, relative_dir_posix): |
327 return set([posixpath.join('bindings', relative_dir_posix, class_name + '.h'
)]) | 339 return set([posixpath.join('bindings', relative_dir_posix, class_name + '.h'
)]) |
328 | 340 |
329 | 341 |
330 INCLUDES_FOR_TYPE = { | 342 INCLUDES_FOR_TYPE = { |
331 'object': set(), | 343 'object': set(), |
332 'Dictionary': set(['bindings/core/v8/Dictionary.h']), | 344 'Dictionary': set(['bindings/core/v8/Dictionary.h']), |
333 'EventHandler': set(['bindings/core/v8/V8AbstractEventListener.h', | 345 'EventHandler': set(['bindings/core/v8/V8AbstractEventListener.h', |
334 'bindings/core/v8/V8EventListenerList.h']), | 346 'bindings/core/v8/V8EventListenerList.h']), |
335 'EventListener': set(['bindings/common/BindingSecurity.h', | 347 'EventListener': set(['bindings/core/v8/BindingSecurity.h', |
336 'bindings/core/v8/V8EventListenerList.h', | 348 'bindings/core/v8/V8EventListenerList.h', |
337 'core/frame/LocalDOMWindow.h']), | 349 'core/frame/LocalDOMWindow.h']), |
338 'HTMLCollection': set(['bindings/core/v8/V8HTMLCollection.h', | 350 'HTMLCollection': set(['bindings/core/v8/V8HTMLCollection.h', |
339 'core/dom/ClassCollection.h', | 351 'core/dom/ClassCollection.h', |
340 'core/dom/TagCollection.h', | 352 'core/dom/TagCollection.h', |
341 'core/html/HTMLCollection.h', | 353 'core/html/HTMLCollection.h', |
342 'core/html/HTMLDataListOptionsCollection.h', | 354 'core/html/HTMLDataListOptionsCollection.h', |
343 'core/html/HTMLFormControlsCollection.h', | 355 'core/html/HTMLFormControlsCollection.h', |
344 'core/html/HTMLTableRowsCollection.h']), | 356 'core/html/HTMLTableRowsCollection.h']), |
345 'NodeList': set(['bindings/core/v8/V8NodeList.h', | 357 'NodeList': set(['bindings/core/v8/V8NodeList.h', |
346 'core/dom/NameNodeList.h', | 358 'core/dom/NameNodeList.h', |
347 'core/dom/NodeList.h', | 359 'core/dom/NodeList.h', |
348 'core/dom/StaticNodeList.h', | 360 'core/dom/StaticNodeList.h', |
349 'core/html/LabelsNodeList.h']), | 361 'core/html/LabelsNodeList.h']), |
350 'Promise': set(['bindings/core/v8/V8ScriptPromise.h']), | 362 'Promise': set(['bindings/core/v8/ScriptPromise.h']), |
351 'SerializedScriptValue': set(['bindings/core/v8/SerializedScriptValue.h']), | 363 'SerializedScriptValue': set(['bindings/core/v8/SerializedScriptValue.h', |
352 'ScriptValue': set(['bindings/common/ScriptValue.h']), | 364 'bindings/core/v8/SerializedScriptValueFactory
.h']), |
| 365 'ScriptValue': set(['bindings/core/v8/ScriptValue.h']), |
353 } | 366 } |
354 | 367 |
355 | 368 |
356 def includes_for_type(idl_type): | 369 def includes_for_type(idl_type, extended_attributes=None): |
357 idl_type = idl_type.preprocessed_type | 370 idl_type = idl_type.preprocessed_type |
| 371 extended_attributes = extended_attributes or {} |
358 | 372 |
359 # Simple types | 373 # Simple types |
360 base_idl_type = idl_type.base_type | 374 base_idl_type = idl_type.base_type |
361 if base_idl_type in INCLUDES_FOR_TYPE: | 375 if base_idl_type in INCLUDES_FOR_TYPE: |
362 return INCLUDES_FOR_TYPE[base_idl_type] | 376 return INCLUDES_FOR_TYPE[base_idl_type] |
363 if idl_type.is_basic_type: | 377 if idl_type.is_basic_type: |
364 return set() | 378 return set() |
365 if idl_type.is_typed_array_element_type: | |
366 return set(['bindings/core/v8/custom/V8%sCustom.h' % base_idl_type]) | |
367 if base_idl_type.endswith('ConstructorConstructor'): | 379 if base_idl_type.endswith('ConstructorConstructor'): |
368 # FIXME: rename to NamedConstructor | 380 # FIXME: rename to NamedConstructor |
369 # FIXME: replace with a [NamedConstructorAttribute] extended attribute | 381 # FIXME: replace with a [NamedConstructorAttribute] extended attribute |
370 # Ending with 'ConstructorConstructor' indicates a named constructor, | 382 # Ending with 'ConstructorConstructor' indicates a named constructor, |
371 # and these do not have header files, as they are part of the generated | 383 # and these do not have header files, as they are part of the generated |
372 # bindings for the interface | 384 # bindings for the interface |
373 return set() | 385 return set() |
374 if base_idl_type.endswith('Constructor'): | 386 if base_idl_type.endswith('Constructor'): |
375 # FIXME: replace with a [ConstructorAttribute] extended attribute | 387 # FIXME: replace with a [ConstructorAttribute] extended attribute |
376 base_idl_type = idl_type.constructor_type_name | 388 base_idl_type = idl_type.constructor_type_name |
377 if base_idl_type not in component_dir: | 389 if base_idl_type not in component_dir: |
378 return set() | 390 return set() |
379 return set(['bindings/%s/v8/V8%s.h' % (component_dir[base_idl_type], | 391 return set(['bindings/%s/v8/V8%s.h' % (component_dir[base_idl_type], |
380 base_idl_type)]) | 392 base_idl_type)]) |
381 | 393 |
382 IdlType.includes_for_type = property(includes_for_type) | 394 IdlType.includes_for_type = includes_for_type |
383 IdlUnionType.includes_for_type = property( | |
384 lambda self: set.union(*[member_type.includes_for_type | |
385 for member_type in self.member_types])) | |
386 IdlArrayOrSequenceType.includes_for_type = property( | |
387 lambda self: self.element_type.includes_for_type) | |
388 | 395 |
389 | 396 |
390 def add_includes_for_type(idl_type): | 397 def includes_for_union_type(idl_type, extended_attributes=None): |
391 includes.update(idl_type.includes_for_type) | 398 return set.union(*[member_type.includes_for_type(extended_attributes) |
| 399 for member_type in idl_type.member_types]) |
| 400 |
| 401 IdlUnionType.includes_for_type = includes_for_union_type |
| 402 |
| 403 |
| 404 def includes_for_array_or_sequence_type(idl_type, extended_attributes=None): |
| 405 return idl_type.element_type.includes_for_type(extended_attributes) |
| 406 |
| 407 IdlArrayOrSequenceType.includes_for_type = includes_for_array_or_sequence_type |
| 408 |
| 409 |
| 410 def add_includes_for_type(idl_type, extended_attributes=None): |
| 411 includes.update(idl_type.includes_for_type(extended_attributes)) |
392 | 412 |
393 IdlTypeBase.add_includes_for_type = add_includes_for_type | 413 IdlTypeBase.add_includes_for_type = add_includes_for_type |
394 | 414 |
395 | 415 |
396 def includes_for_interface(interface_name): | 416 def includes_for_interface(interface_name): |
397 return IdlType(interface_name).includes_for_type | 417 return IdlType(interface_name).includes_for_type() |
398 | 418 |
399 | 419 |
400 def add_includes_for_interface(interface_name): | 420 def add_includes_for_interface(interface_name): |
401 includes.update(includes_for_interface(interface_name)) | 421 includes.update(includes_for_interface(interface_name)) |
402 | 422 |
403 | 423 |
404 def impl_should_use_nullable_container(idl_type): | 424 def impl_should_use_nullable_container(idl_type): |
405 return not(idl_type.cpp_type_has_null_value) | 425 return not(idl_type.cpp_type_has_null_value) |
406 | 426 |
407 IdlTypeBase.impl_should_use_nullable_container = property( | 427 IdlTypeBase.impl_should_use_nullable_container = property( |
408 impl_should_use_nullable_container) | 428 impl_should_use_nullable_container) |
409 | 429 |
410 | 430 |
411 def impl_includes_for_type(idl_type, interfaces_info): | 431 def impl_includes_for_type(idl_type, interfaces_info): |
412 includes_for_type = set() | 432 includes_for_type = set() |
413 if idl_type.impl_should_use_nullable_container: | 433 if idl_type.impl_should_use_nullable_container: |
414 includes_for_type.add('bindings/common/Nullable.h') | 434 includes_for_type.add('bindings/core/v8/Nullable.h') |
415 | 435 |
416 idl_type = idl_type.preprocessed_type | 436 idl_type = idl_type.preprocessed_type |
417 native_array_element_type = idl_type.native_array_element_type | 437 native_array_element_type = idl_type.native_array_element_type |
418 if native_array_element_type: | 438 if native_array_element_type: |
419 includes_for_type.update(impl_includes_for_type( | 439 includes_for_type.update(impl_includes_for_type( |
420 native_array_element_type, interfaces_info)) | 440 native_array_element_type, interfaces_info)) |
421 includes_for_type.add('wtf/Vector.h') | 441 includes_for_type.add('wtf/Vector.h') |
422 | 442 |
423 base_idl_type = idl_type.base_type | 443 base_idl_type = idl_type.base_type |
424 if idl_type.is_string_type: | 444 if idl_type.is_string_type: |
425 includes_for_type.add('wtf/text/WTFString.h') | 445 includes_for_type.add('wtf/text/WTFString.h') |
426 if base_idl_type in interfaces_info: | 446 if base_idl_type in interfaces_info: |
427 interface_info = interfaces_info[idl_type.base_type] | 447 interface_info = interfaces_info[idl_type.base_type] |
428 includes_for_type.add(interface_info['include_path']) | 448 if interface_info['include_path']: |
| 449 includes_for_type.add(interface_info['include_path']) |
429 if base_idl_type in INCLUDES_FOR_TYPE: | 450 if base_idl_type in INCLUDES_FOR_TYPE: |
430 includes_for_type.update(INCLUDES_FOR_TYPE[base_idl_type]) | 451 includes_for_type.update(INCLUDES_FOR_TYPE[base_idl_type]) |
| 452 if idl_type.is_typed_array: |
| 453 return set(['core/dom/DOMTypedArray.h']) |
| 454 return includes_for_type |
| 455 |
| 456 |
| 457 def impl_includes_for_type_union(idl_type, interfaces_info): |
| 458 includes_for_type = set() |
| 459 for member_type in idl_type.member_types: |
| 460 includes_for_type.update(member_type.impl_includes_for_type(interfaces_i
nfo)) |
431 return includes_for_type | 461 return includes_for_type |
432 | 462 |
433 IdlTypeBase.impl_includes_for_type = impl_includes_for_type | 463 IdlTypeBase.impl_includes_for_type = impl_includes_for_type |
| 464 IdlUnionType.impl_includes_for_type = impl_includes_for_type_union |
434 | 465 |
435 | 466 |
436 component_dir = {} | 467 component_dir = {} |
437 | 468 |
438 | 469 |
439 def set_component_dirs(new_component_dirs): | 470 def set_component_dirs(new_component_dirs): |
440 component_dir.update(new_component_dirs) | 471 component_dir.update(new_component_dirs) |
441 | 472 |
442 | 473 |
443 ################################################################################ | 474 ################################################################################ |
444 # V8 -> C++ | 475 # V8 -> C++ |
445 ################################################################################ | 476 ################################################################################ |
446 | 477 |
447 V8_VALUE_TO_CPP_VALUE = { | 478 V8_VALUE_TO_CPP_VALUE = { |
448 # Basic | 479 # Basic |
449 'Date': 'toCoreDate({v8_value})', | 480 'Date': 'toCoreDate({isolate}, {v8_value})', |
450 'DOMString': '{v8_value}', | 481 'DOMString': '{v8_value}', |
451 'ByteString': 'toByteString({arguments})', | 482 'ByteString': 'toByteString({isolate}, {arguments})', |
452 'ScalarValueString': 'toScalarValueString({arguments})', | 483 'USVString': 'toUSVString({isolate}, {arguments})', |
453 'boolean': '{v8_value}->BooleanValue()', | 484 'boolean': 'toBoolean({isolate}, {arguments})', |
454 'float': 'toFloat({arguments})', | 485 'float': 'toRestrictedFloat({isolate}, {arguments})', |
455 'unrestricted float': 'toFloat({arguments})', | 486 'unrestricted float': 'toFloat({isolate}, {arguments})', |
456 'double': 'toDouble({arguments})', | 487 'double': 'toRestrictedDouble({isolate}, {arguments})', |
457 'unrestricted double': 'toDouble({arguments})', | 488 'unrestricted double': 'toDouble({isolate}, {arguments})', |
458 'byte': 'toInt8({arguments})', | 489 'byte': 'toInt8({isolate}, {arguments})', |
459 'octet': 'toUInt8({arguments})', | 490 'octet': 'toUInt8({isolate}, {arguments})', |
460 'short': 'toInt16({arguments})', | 491 'short': 'toInt16({isolate}, {arguments})', |
461 'unsigned short': 'toUInt16({arguments})', | 492 'unsigned short': 'toUInt16({isolate}, {arguments})', |
462 'long': 'toInt32({arguments})', | 493 'long': 'toInt32({isolate}, {arguments})', |
463 'unsigned long': 'toUInt32({arguments})', | 494 'unsigned long': 'toUInt32({isolate}, {arguments})', |
464 'long long': 'toInt64({arguments})', | 495 'long long': 'toInt64({isolate}, {arguments})', |
465 'unsigned long long': 'toUInt64({arguments})', | 496 'unsigned long long': 'toUInt64({isolate}, {arguments})', |
466 # Interface types | 497 # Interface types |
467 'Dictionary': 'Dictionary({v8_value}, {isolate})', | 498 'Dictionary': 'Dictionary({v8_value}, {isolate}, exceptionState)', |
468 'EventTarget': 'V8DOMWrapper::isDOMWrapper({v8_value}) ? toWrapperTypeInfo(v
8::Handle<v8::Object>::Cast({v8_value}))->toEventTarget(v8::Handle<v8::Object>::
Cast({v8_value})) : 0', | 499 'EventTarget': 'toEventTarget({isolate}, {v8_value})', |
469 'NodeFilter': 'toNodeFilter({v8_value}, info.Holder(), V8ScriptState::curren
t({isolate}))', | 500 'NodeFilter': 'toNodeFilter({v8_value}, info.Holder(), ScriptState::current(
{isolate}))', |
470 'Promise': 'V8ScriptPromise::cast(V8ScriptState::current({isolate}), {v8_val
ue})', | 501 'Promise': 'ScriptPromise::cast(ScriptState::current({isolate}), {v8_value})
', |
471 'SerializedScriptValue': 'SerializedScriptValue::create({v8_value}, 0, 0, ex
ceptionState, {isolate})', | 502 'SerializedScriptValue': 'SerializedScriptValueFactory::instance().create({i
solate}, {v8_value}, 0, 0, exceptionState)', |
472 'ScriptValue': 'ScriptValue(V8ScriptState::current({isolate}), {v8_value})', | 503 'ScriptValue': 'ScriptValue(ScriptState::current({isolate}), {v8_value})', |
473 'Window': 'toDOMWindow({v8_value}, {isolate})', | 504 'Window': 'toDOMWindow({isolate}, {v8_value})', |
474 'XPathNSResolver': 'toXPathNSResolver({v8_value}, {isolate})', | 505 'XPathNSResolver': 'toXPathNSResolver(ScriptState::current({isolate}), {v8_v
alue})', |
475 } | 506 } |
476 | 507 |
477 | 508 |
478 def v8_conversion_needs_exception_state(idl_type): | 509 def v8_conversion_needs_exception_state(idl_type): |
479 return (idl_type.is_numeric_type or | 510 return (idl_type.is_numeric_type or |
| 511 idl_type.is_enum or |
480 idl_type.is_dictionary or | 512 idl_type.is_dictionary or |
481 idl_type.name in ('ByteString', 'ScalarValueString', 'SerializedScri
ptValue')) | 513 idl_type.name in ('Boolean', 'ByteString', 'Dictionary', 'USVString'
, 'SerializedScriptValue')) |
482 | 514 |
483 IdlType.v8_conversion_needs_exception_state = property(v8_conversion_needs_excep
tion_state) | 515 IdlType.v8_conversion_needs_exception_state = property(v8_conversion_needs_excep
tion_state) |
484 IdlArrayOrSequenceType.v8_conversion_needs_exception_state = True | 516 IdlArrayOrSequenceType.v8_conversion_needs_exception_state = True |
| 517 IdlUnionType.v8_conversion_needs_exception_state = True |
485 | 518 |
486 | 519 |
487 TRIVIAL_CONVERSIONS = frozenset([ | 520 TRIVIAL_CONVERSIONS = frozenset([ |
488 'any', | 521 'any', |
489 'boolean', | 522 'boolean', |
490 'Date', | 523 'Date', |
491 'Dictionary', | 524 'Dictionary', |
492 'NodeFilter', | 525 'NodeFilter', |
493 'XPathNSResolver', | 526 'XPathNSResolver', |
494 'Promise' | 527 'Promise' |
495 ]) | 528 ]) |
496 | 529 |
497 | 530 |
498 def v8_conversion_is_trivial(idl_type): | 531 def v8_conversion_is_trivial(idl_type): |
499 # The conversion is a simple expression that returns the converted value and | 532 # The conversion is a simple expression that returns the converted value and |
500 # cannot raise an exception. | 533 # cannot raise an exception. |
501 return (idl_type.base_type in TRIVIAL_CONVERSIONS or | 534 return (idl_type.base_type in TRIVIAL_CONVERSIONS or |
502 idl_type.is_wrapper_type) | 535 idl_type.is_wrapper_type) |
503 | 536 |
504 IdlType.v8_conversion_is_trivial = property(v8_conversion_is_trivial) | 537 IdlType.v8_conversion_is_trivial = property(v8_conversion_is_trivial) |
505 | 538 |
506 | 539 |
507 def v8_value_to_cpp_value(idl_type, extended_attributes, v8_value, index, isolat
e): | 540 def v8_value_to_cpp_value(idl_type, extended_attributes, v8_value, variable_name
, index, isolate, restricted_float=False): |
508 if idl_type.name == 'void': | 541 if idl_type.name == 'void': |
509 return '' | 542 return '' |
510 | 543 |
511 # Array or sequence types | 544 # Array or sequence types |
512 native_array_element_type = idl_type.native_array_element_type | 545 native_array_element_type = idl_type.native_array_element_type |
513 if native_array_element_type: | 546 if native_array_element_type: |
514 return v8_value_to_cpp_value_array_or_sequence(native_array_element_type
, v8_value, index) | 547 return v8_value_to_cpp_value_array_or_sequence(native_array_element_type
, v8_value, index, isolate) |
515 | 548 |
516 # Simple types | 549 # Simple types |
517 idl_type = idl_type.preprocessed_type | 550 idl_type = idl_type.preprocessed_type |
518 add_includes_for_type(idl_type) | 551 base_idl_type = idl_type.as_union_type.name if idl_type.is_union_type else i
dl_type.base_type |
519 base_idl_type = idl_type.base_type | |
520 | 552 |
521 if 'EnforceRange' in extended_attributes: | 553 if idl_type.is_integer_type: |
522 arguments = ', '.join([v8_value, 'EnforceRange', 'exceptionState']) | 554 configuration = 'NormalConversion' |
523 elif 'Clamp' in extended_attributes: | 555 if 'EnforceRange' in extended_attributes: |
524 arguments = ', '.join([v8_value, 'Clamp', 'exceptionState']) | 556 configuration = 'EnforceRange' |
| 557 elif 'Clamp' in extended_attributes: |
| 558 configuration = 'Clamp' |
| 559 arguments = ', '.join([v8_value, configuration, 'exceptionState']) |
525 elif idl_type.v8_conversion_needs_exception_state: | 560 elif idl_type.v8_conversion_needs_exception_state: |
526 arguments = ', '.join([v8_value, 'exceptionState']) | 561 arguments = ', '.join([v8_value, 'exceptionState']) |
527 else: | 562 else: |
528 arguments = v8_value | 563 arguments = v8_value |
529 | |
530 if base_idl_type in V8_VALUE_TO_CPP_VALUE: | 564 if base_idl_type in V8_VALUE_TO_CPP_VALUE: |
531 cpp_expression_format = V8_VALUE_TO_CPP_VALUE[base_idl_type] | 565 cpp_expression_format = V8_VALUE_TO_CPP_VALUE[base_idl_type] |
532 elif idl_type.is_typed_array_element_type: | 566 elif idl_type.is_array_buffer_or_view: |
533 cpp_expression_format = ( | 567 cpp_expression_format = ( |
534 '{v8_value}->Is{idl_type}() ? ' | 568 '{v8_value}->Is{idl_type}() ? ' |
535 'V8{idl_type}::toImpl(v8::Handle<v8::{idl_type}>::Cast({v8_value}))
: 0') | 569 'V8{idl_type}::toImpl(v8::Local<v8::{idl_type}>::Cast({v8_value})) :
0') |
536 elif idl_type.is_dictionary: | 570 elif idl_type.use_output_parameter_for_result: |
537 cpp_expression_format = 'V8{idl_type}::toImpl({isolate}, {v8_value}, exc
eptionState)' | 571 if idl_type.includes_nullable_type: |
| 572 base_idl_type = idl_type.cpp_type + 'OrNull' |
| 573 cpp_expression_format = 'V8{idl_type}::toImpl({isolate}, {v8_value}, {va
riable_name}, exceptionState)' |
538 else: | 574 else: |
539 cpp_expression_format = ( | 575 cpp_expression_format = ( |
540 'V8{idl_type}::toImplWithTypeCheck({isolate}, {v8_value})') | 576 'V8{idl_type}::toImplWithTypeCheck({isolate}, {v8_value})') |
541 | 577 |
542 return cpp_expression_format.format(arguments=arguments, idl_type=base_idl_t
ype, v8_value=v8_value, isolate=isolate) | 578 return cpp_expression_format.format(arguments=arguments, idl_type=base_idl_t
ype, v8_value=v8_value, variable_name=variable_name, isolate=isolate) |
543 | 579 |
544 | 580 |
545 def v8_value_to_cpp_value_array_or_sequence(native_array_element_type, v8_value,
index, isolate='info.GetIsolate()'): | 581 def v8_value_to_cpp_value_array_or_sequence(native_array_element_type, v8_value,
index, isolate='info.GetIsolate()'): |
546 # Index is None for setters, index (starting at 0) for method arguments, | 582 # Index is None for setters, index (starting at 0) for method arguments, |
547 # and is used to provide a human-readable exception message | 583 # and is used to provide a human-readable exception message |
548 if index is None: | 584 if index is None: |
549 index = 0 # special case, meaning "setter" | 585 index = 0 # special case, meaning "setter" |
550 else: | 586 else: |
551 index += 1 # human-readable index | 587 index += 1 # human-readable index |
552 if (native_array_element_type.is_interface_type and | 588 if (native_array_element_type.is_interface_type and |
553 native_array_element_type.name != 'Dictionary'): | 589 native_array_element_type.name != 'Dictionary'): |
554 this_cpp_type = None | 590 this_cpp_type = None |
555 ref_ptr_type = cpp_ptr_type('RefPtr', 'Member', native_array_element_typ
e.gc_type) | 591 ref_ptr_type = cpp_ptr_type('RefPtr', 'Member', native_array_element_typ
e.gc_type) |
556 expression_format = '(to{ref_ptr_type}NativeArray<{native_array_element_
type}, V8{native_array_element_type}>({v8_value}, {index}, {isolate}, exceptionS
tate))' | 592 expression_format = '(to{ref_ptr_type}NativeArray<{native_array_element_
type}, V8{native_array_element_type}>({v8_value}, {index}, {isolate}, exceptionS
tate))' |
557 add_includes_for_type(native_array_element_type) | |
558 else: | 593 else: |
559 ref_ptr_type = None | 594 ref_ptr_type = None |
560 this_cpp_type = native_array_element_type.cpp_type | 595 this_cpp_type = native_array_element_type.cpp_type |
561 expression_format = 'toImplArray<{cpp_type}>({v8_value}, {index}, {isola
te}, exceptionState)' | 596 if native_array_element_type.is_dictionary or native_array_element_type.
is_union_type: |
| 597 vector_type = 'HeapVector' |
| 598 else: |
| 599 vector_type = 'Vector' |
| 600 expression_format = 'toImplArray<%s<{cpp_type}>>({v8_value}, {index}, {i
solate}, exceptionState)' % vector_type |
562 expression = expression_format.format(native_array_element_type=native_array
_element_type.name, cpp_type=this_cpp_type, index=index, ref_ptr_type=ref_ptr_ty
pe, v8_value=v8_value, isolate=isolate) | 601 expression = expression_format.format(native_array_element_type=native_array
_element_type.name, cpp_type=this_cpp_type, index=index, ref_ptr_type=ref_ptr_ty
pe, v8_value=v8_value, isolate=isolate) |
563 return expression | 602 return expression |
564 | 603 |
565 | 604 |
566 def v8_value_to_local_cpp_value(idl_type, extended_attributes, v8_value, variabl
e_name, index=None, declare_variable=True, isolate='info.GetIsolate()', used_in_
private_script=False, return_promise=False): | 605 # FIXME: this function should be refactored, as this takes too many flags. |
| 606 def v8_value_to_local_cpp_value(idl_type, extended_attributes, v8_value, variabl
e_name, index=None, declare_variable=True, isolate='info.GetIsolate()', bailout_
return_value=None, use_exception_state=False, restricted_float=False): |
567 """Returns an expression that converts a V8 value to a C++ value and stores
it as a local value.""" | 607 """Returns an expression that converts a V8 value to a C++ value and stores
it as a local value.""" |
568 | 608 |
569 # FIXME: Support union type. | |
570 if idl_type.is_union_type: | |
571 return '/* no V8 -> C++ conversion for IDL union type: %s */' % idl_type
.name | |
572 | |
573 this_cpp_type = idl_type.cpp_type_args(extended_attributes=extended_attribut
es, raw_type=True) | 609 this_cpp_type = idl_type.cpp_type_args(extended_attributes=extended_attribut
es, raw_type=True) |
574 idl_type = idl_type.preprocessed_type | 610 idl_type = idl_type.preprocessed_type |
575 | 611 |
576 if idl_type.base_type in ('void', 'object', 'EventHandler', 'EventListener')
: | 612 cpp_value = v8_value_to_cpp_value(idl_type, extended_attributes, v8_value, v
ariable_name, index, isolate, restricted_float=restricted_float) |
577 return '/* no V8 -> C++ conversion for IDL type: %s */' % idl_type.name | |
578 | 613 |
579 cpp_value = v8_value_to_cpp_value(idl_type, extended_attributes, v8_value, i
ndex, isolate) | 614 # Optional expression that returns a value to be assigned to the local varia
ble. |
| 615 assign_expression = None |
| 616 # Optional void expression executed unconditionally. |
| 617 set_expression = None |
| 618 # Optional expression that returns true if the conversion fails. |
| 619 check_expression = None |
| 620 # Optional expression used as the return value when returning. Only |
| 621 # meaningful if 'check_expression' is not None. |
| 622 return_expression = bailout_return_value |
| 623 |
580 if idl_type.is_string_type or idl_type.v8_conversion_needs_exception_state: | 624 if idl_type.is_string_type or idl_type.v8_conversion_needs_exception_state: |
581 # Types that need error handling and use one of a group of (C++) macros | 625 # Types for which conversion can fail and that need error handling. |
582 # to take care of this. | |
583 | 626 |
584 args = [variable_name, cpp_value] | 627 if use_exception_state: |
| 628 check_expression = 'exceptionState.hadException()' |
| 629 else: |
| 630 check_expression = 'exceptionState.throwIfNeeded()' |
585 | 631 |
586 if idl_type.v8_conversion_needs_exception_state: | 632 if idl_type.is_dictionary or idl_type.is_union_type: |
587 macro = 'TONATIVE_DEFAULT_EXCEPTIONSTATE' if used_in_private_script
else 'TONATIVE_VOID_EXCEPTIONSTATE' | 633 set_expression = cpp_value |
588 elif return_promise: | |
589 macro = 'TOSTRING_VOID_EXCEPTIONSTATE' | |
590 else: | 634 else: |
591 macro = 'TOSTRING_DEFAULT' if used_in_private_script else 'TOSTRING_
VOID' | 635 assign_expression = cpp_value |
592 | 636 # Note: 'not idl_type.v8_conversion_needs_exception_state' implies |
593 if macro.endswith('_EXCEPTIONSTATE'): | 637 # 'idl_type.is_string_type', but there are types for which both are |
594 args.append('exceptionState') | 638 # true (ByteString and USVString), so using idl_type.is_string_type |
595 | 639 # as the condition here would be wrong. |
596 if used_in_private_script: | 640 if not idl_type.v8_conversion_needs_exception_state: |
597 args.append('false') | 641 if use_exception_state: |
598 | 642 check_expression = '!%s.prepare(exceptionState)' % variable_
name |
599 suffix = '' | 643 else: |
600 | 644 check_expression = '!%s.prepare()' % variable_name |
601 if return_promise: | 645 elif not idl_type.v8_conversion_is_trivial: |
602 suffix += '_PROMISE' | 646 return { |
603 args.append('info') | 647 'error_message': 'no V8 -> C++ conversion for IDL type: %s' % idl_ty
pe.name |
604 if macro.endswith('_EXCEPTIONSTATE'): | 648 } |
605 args.append('V8ScriptState::current(%s)' % isolate) | 649 else: |
606 | 650 assign_expression = cpp_value |
607 if declare_variable: | |
608 args.insert(0, this_cpp_type) | |
609 else: | |
610 suffix += '_INTERNAL' | |
611 | |
612 return '%s(%s)' % (macro + suffix, ', '.join(args)) | |
613 | 651 |
614 # Types that don't need error handling, and simply assign a value to the | 652 # Types that don't need error handling, and simply assign a value to the |
615 # local variable. | 653 # local variable. |
616 | 654 |
617 if not idl_type.v8_conversion_is_trivial: | 655 return { |
618 raise Exception('unclassified V8 -> C++ conversion for IDL type: %s' % i
dl_type.name) | 656 'assign_expression': assign_expression, |
619 | 657 'check_expression': check_expression, |
620 assignment = '%s = %s' % (variable_name, cpp_value) | 658 'cpp_type': this_cpp_type, |
621 if declare_variable: | 659 'cpp_name': variable_name, |
622 return '%s %s' % (this_cpp_type, assignment) | 660 'declare_variable': declare_variable, |
623 return assignment | 661 'return_expression': bailout_return_value, |
| 662 'set_expression': set_expression, |
| 663 } |
624 | 664 |
625 | 665 |
626 IdlTypeBase.v8_value_to_local_cpp_value = v8_value_to_local_cpp_value | 666 IdlTypeBase.v8_value_to_local_cpp_value = v8_value_to_local_cpp_value |
627 | 667 |
628 | 668 |
| 669 def use_output_parameter_for_result(idl_type): |
| 670 """True when methods/getters which return the given idl_type should |
| 671 take the output argument. |
| 672 """ |
| 673 return idl_type.is_dictionary or idl_type.is_union_type |
| 674 |
| 675 IdlTypeBase.use_output_parameter_for_result = property(use_output_parameter_for_
result) |
| 676 |
| 677 |
629 ################################################################################ | 678 ################################################################################ |
630 # C++ -> V8 | 679 # C++ -> V8 |
631 ################################################################################ | 680 ################################################################################ |
632 | 681 |
633 def preprocess_idl_type(idl_type): | 682 def preprocess_idl_type(idl_type): |
| 683 if idl_type.is_nullable: |
| 684 return IdlNullableType(idl_type.inner_type.preprocessed_type) |
634 if idl_type.is_enum: | 685 if idl_type.is_enum: |
635 # Enumerations are internally DOMStrings | 686 # Enumerations are internally DOMStrings |
636 return IdlType('DOMString') | 687 return IdlType('DOMString') |
637 if (idl_type.name in ['Any', 'Object'] or idl_type.is_callback_function): | 688 if idl_type.base_type in ['any', 'object'] or idl_type.is_callback_function: |
638 return IdlType('ScriptValue') | 689 return IdlType('ScriptValue') |
639 return idl_type | 690 return idl_type |
640 | 691 |
641 IdlTypeBase.preprocessed_type = property(preprocess_idl_type) | 692 IdlTypeBase.preprocessed_type = property(preprocess_idl_type) |
642 | 693 |
643 | 694 |
644 def preprocess_idl_type_and_value(idl_type, cpp_value, extended_attributes): | 695 def preprocess_idl_type_and_value(idl_type, cpp_value, extended_attributes): |
645 """Returns IDL type and value, with preliminary type conversions applied.""" | 696 """Returns IDL type and value, with preliminary type conversions applied.""" |
646 idl_type = idl_type.preprocessed_type | 697 idl_type = idl_type.preprocessed_type |
647 if idl_type.name == 'Promise': | 698 if idl_type.name == 'Promise': |
(...skipping 20 matching lines...) Expand all Loading... |
668 | 719 |
669 def v8_conversion_type(idl_type, extended_attributes): | 720 def v8_conversion_type(idl_type, extended_attributes): |
670 """Returns V8 conversion type, adding any additional includes. | 721 """Returns V8 conversion type, adding any additional includes. |
671 | 722 |
672 The V8 conversion type is used to select the C++ -> V8 conversion function | 723 The V8 conversion type is used to select the C++ -> V8 conversion function |
673 or v8SetReturnValue* function; it can be an idl_type, a cpp_type, or a | 724 or v8SetReturnValue* function; it can be an idl_type, a cpp_type, or a |
674 separate name for the type of conversion (e.g., 'DOMWrapper'). | 725 separate name for the type of conversion (e.g., 'DOMWrapper'). |
675 """ | 726 """ |
676 extended_attributes = extended_attributes or {} | 727 extended_attributes = extended_attributes or {} |
677 | 728 |
678 # FIXME: Support union type. | 729 # Nullable dictionaries need to be handled differently than either |
679 if idl_type.is_union_type: | 730 # non-nullable dictionaries or unions. |
680 return '' | 731 if idl_type.is_dictionary and idl_type.is_nullable: |
| 732 return 'NullableDictionary' |
| 733 |
| 734 if idl_type.is_dictionary or idl_type.is_union_type: |
| 735 return 'DictionaryOrUnion' |
681 | 736 |
682 # Array or sequence types | 737 # Array or sequence types |
683 native_array_element_type = idl_type.native_array_element_type | 738 native_array_element_type = idl_type.native_array_element_type |
684 if native_array_element_type: | 739 if native_array_element_type: |
685 if native_array_element_type.is_interface_type: | |
686 add_includes_for_type(native_array_element_type) | |
687 return 'array' | 740 return 'array' |
688 | 741 |
689 # Simple types | 742 # Simple types |
690 base_idl_type = idl_type.base_type | 743 base_idl_type = idl_type.base_type |
691 # Basic types, without additional includes | 744 # Basic types, without additional includes |
692 if base_idl_type in CPP_INT_TYPES: | 745 if base_idl_type in CPP_INT_TYPES: |
693 return 'int' | 746 return 'int' |
694 if base_idl_type in CPP_UNSIGNED_TYPES: | 747 if base_idl_type in CPP_UNSIGNED_TYPES: |
695 return 'unsigned' | 748 return 'unsigned' |
696 if idl_type.is_string_type: | 749 if idl_type.is_string_type: |
697 if idl_type.is_nullable: | 750 if idl_type.is_nullable: |
698 return 'StringOrNull' | 751 return 'StringOrNull' |
699 if 'TreatReturnedNullStringAs' not in extended_attributes: | 752 if 'TreatReturnedNullStringAs' not in extended_attributes: |
700 return base_idl_type | 753 return base_idl_type |
701 treat_returned_null_string_as = extended_attributes['TreatReturnedNullSt
ringAs'] | 754 treat_returned_null_string_as = extended_attributes['TreatReturnedNullSt
ringAs'] |
702 if treat_returned_null_string_as == 'Null': | 755 if treat_returned_null_string_as == 'Null': |
703 return 'StringOrNull' | 756 return 'StringOrNull' |
704 if treat_returned_null_string_as == 'Undefined': | 757 if treat_returned_null_string_as == 'Undefined': |
705 return 'StringOrUndefined' | 758 return 'StringOrUndefined' |
706 raise 'Unrecognized TreatReturnedNullStringAs value: "%s"' % treat_retur
ned_null_string_as | 759 raise 'Unrecognized TreatReturnedNullStringAs value: "%s"' % treat_retur
ned_null_string_as |
707 if idl_type.is_basic_type or base_idl_type == 'ScriptValue': | 760 if idl_type.is_basic_type or base_idl_type == 'ScriptValue': |
708 return base_idl_type | 761 return base_idl_type |
| 762 # Generic dictionary type |
| 763 if base_idl_type == 'Dictionary': |
| 764 return 'Dictionary' |
709 | 765 |
710 # Data type with potential additional includes | 766 # Data type with potential additional includes |
711 add_includes_for_type(idl_type) | |
712 if base_idl_type in V8_SET_RETURN_VALUE: # Special v8SetReturnValue treatme
nt | 767 if base_idl_type in V8_SET_RETURN_VALUE: # Special v8SetReturnValue treatme
nt |
713 return base_idl_type | 768 return base_idl_type |
714 | 769 |
715 # Pointer type | 770 # Pointer type |
716 return 'DOMWrapper' | 771 return 'DOMWrapper' |
717 | 772 |
718 IdlTypeBase.v8_conversion_type = v8_conversion_type | 773 IdlTypeBase.v8_conversion_type = v8_conversion_type |
719 | 774 |
720 | 775 |
721 V8_SET_RETURN_VALUE = { | 776 V8_SET_RETURN_VALUE = { |
722 'boolean': 'v8SetReturnValueBool(info, {cpp_value})', | 777 'boolean': 'v8SetReturnValueBool(info, {cpp_value})', |
723 'int': 'v8SetReturnValueInt(info, {cpp_value})', | 778 'int': 'v8SetReturnValueInt(info, {cpp_value})', |
724 'unsigned': 'v8SetReturnValueUnsigned(info, {cpp_value})', | 779 'unsigned': 'v8SetReturnValueUnsigned(info, {cpp_value})', |
725 'DOMString': 'v8SetReturnValueString(info, {cpp_value}, info.GetIsolate())', | 780 'DOMString': 'v8SetReturnValueString(info, {cpp_value}, info.GetIsolate())', |
726 'ByteString': 'v8SetReturnValueString(info, {cpp_value}, info.GetIsolate())'
, | 781 'ByteString': 'v8SetReturnValueString(info, {cpp_value}, info.GetIsolate())'
, |
727 'ScalarValueString': 'v8SetReturnValueString(info, {cpp_value}, info.GetIsol
ate())', | 782 'USVString': 'v8SetReturnValueString(info, {cpp_value}, info.GetIsolate())', |
728 # [TreatReturnedNullStringAs] | 783 # [TreatReturnedNullStringAs] |
729 'StringOrNull': 'v8SetReturnValueStringOrNull(info, {cpp_value}, info.GetIso
late())', | 784 'StringOrNull': 'v8SetReturnValueStringOrNull(info, {cpp_value}, info.GetIso
late())', |
730 'StringOrUndefined': 'v8SetReturnValueStringOrUndefined(info, {cpp_value}, i
nfo.GetIsolate())', | 785 'StringOrUndefined': 'v8SetReturnValueStringOrUndefined(info, {cpp_value}, i
nfo.GetIsolate())', |
731 'void': '', | 786 'void': '', |
732 # No special v8SetReturnValue* function (set value directly) | 787 # No special v8SetReturnValue* function (set value directly) |
733 'float': 'v8SetReturnValue(info, {cpp_value})', | 788 'float': 'v8SetReturnValue(info, {cpp_value})', |
734 'unrestricted float': 'v8SetReturnValue(info, {cpp_value})', | 789 'unrestricted float': 'v8SetReturnValue(info, {cpp_value})', |
735 'double': 'v8SetReturnValue(info, {cpp_value})', | 790 'double': 'v8SetReturnValue(info, {cpp_value})', |
736 'unrestricted double': 'v8SetReturnValue(info, {cpp_value})', | 791 'unrestricted double': 'v8SetReturnValue(info, {cpp_value})', |
737 # No special v8SetReturnValue* function, but instead convert value to V8 | 792 # No special v8SetReturnValue* function, but instead convert value to V8 |
738 # and then use general v8SetReturnValue. | 793 # and then use general v8SetReturnValue. |
739 'array': 'v8SetReturnValue(info, {cpp_value})', | 794 'array': 'v8SetReturnValue(info, {cpp_value})', |
740 'Date': 'v8SetReturnValue(info, {cpp_value})', | 795 'Date': 'v8SetReturnValue(info, {cpp_value})', |
741 'EventHandler': 'v8SetReturnValue(info, {cpp_value})', | 796 'EventHandler': 'v8SetReturnValue(info, {cpp_value})', |
742 'ScriptValue': 'v8SetReturnValue(info, {cpp_value})', | 797 'ScriptValue': 'v8SetReturnValue(info, {cpp_value})', |
743 'SerializedScriptValue': 'v8SetReturnValue(info, {cpp_value})', | 798 'SerializedScriptValue': 'v8SetReturnValue(info, {cpp_value})', |
744 # DOMWrapper | 799 # DOMWrapper |
745 'DOMWrapperForMainWorld': 'v8SetReturnValueForMainWorld(info, WTF::getPtr({c
pp_value}))', | 800 'DOMWrapperForMainWorld': 'v8SetReturnValueForMainWorld(info, WTF::getPtr({c
pp_value}))', |
746 'DOMWrapperFast': 'v8SetReturnValueFast(info, WTF::getPtr({cpp_value}), {scr
ipt_wrappable})', | 801 'DOMWrapperFast': 'v8SetReturnValueFast(info, WTF::getPtr({cpp_value}), {scr
ipt_wrappable})', |
747 'DOMWrapperDefault': 'v8SetReturnValue(info, {cpp_value})', | 802 'DOMWrapperDefault': 'v8SetReturnValue(info, {cpp_value})', |
| 803 # Note that static attributes and operations do not check whether |this| is |
| 804 # an instance of the interface nor |this|'s creation context is the same as |
| 805 # the current context. So we must always use the current context as the |
| 806 # creation context of the DOM wrapper for the return value. |
| 807 'DOMWrapperStatic': 'v8SetReturnValue(info, {cpp_value}, info.GetIsolate()->
GetCurrentContext()->Global())', |
| 808 # Generic dictionary type |
| 809 'Dictionary': 'v8SetReturnValue(info, {cpp_value})', |
| 810 'DictionaryStatic': '#error not implemented yet', |
| 811 # Nullable dictionaries |
| 812 'NullableDictionary': 'v8SetReturnValue(info, result.get())', |
| 813 'NullableDictionaryStatic': '#error not implemented yet', |
| 814 # Union types or dictionaries |
| 815 'DictionaryOrUnion': 'v8SetReturnValue(info, result)', |
| 816 'DictionaryOrUnionStatic': '#error not implemented yet', |
748 } | 817 } |
749 | 818 |
750 | 819 |
751 def v8_set_return_value(idl_type, cpp_value, extended_attributes=None, script_wr
appable='', release=False, for_main_world=False): | 820 def v8_set_return_value(idl_type, cpp_value, extended_attributes=None, script_wr
appable='', release=False, for_main_world=False, is_static=False): |
752 """Returns a statement that converts a C++ value to a V8 value and sets it a
s a return value. | 821 """Returns a statement that converts a C++ value to a V8 value and sets it a
s a return value. |
753 | 822 |
754 """ | 823 """ |
755 def dom_wrapper_conversion_type(): | 824 def dom_wrapper_conversion_type(): |
| 825 if is_static: |
| 826 return 'DOMWrapperStatic' |
756 if not script_wrappable: | 827 if not script_wrappable: |
757 return 'DOMWrapperDefault' | 828 return 'DOMWrapperDefault' |
758 if for_main_world: | 829 if for_main_world: |
759 return 'DOMWrapperForMainWorld' | 830 return 'DOMWrapperForMainWorld' |
760 return 'DOMWrapperFast' | 831 return 'DOMWrapperFast' |
761 | 832 |
762 idl_type, cpp_value = preprocess_idl_type_and_value(idl_type, cpp_value, ext
ended_attributes) | 833 idl_type, cpp_value = preprocess_idl_type_and_value(idl_type, cpp_value, ext
ended_attributes) |
763 this_v8_conversion_type = idl_type.v8_conversion_type(extended_attributes) | 834 this_v8_conversion_type = idl_type.v8_conversion_type(extended_attributes) |
764 # SetReturn-specific overrides | 835 # SetReturn-specific overrides |
765 if this_v8_conversion_type in ['Date', 'EventHandler', 'ScriptValue', 'Seria
lizedScriptValue', 'array']: | 836 if this_v8_conversion_type in ['Date', 'EventHandler', 'ScriptValue', 'Seria
lizedScriptValue', 'array']: |
766 # Convert value to V8 and then use general v8SetReturnValue | 837 # Convert value to V8 and then use general v8SetReturnValue |
767 cpp_value = idl_type.cpp_value_to_v8_value(cpp_value, extended_attribute
s=extended_attributes) | 838 cpp_value = idl_type.cpp_value_to_v8_value(cpp_value, extended_attribute
s=extended_attributes) |
768 if this_v8_conversion_type == 'DOMWrapper': | 839 if this_v8_conversion_type == 'DOMWrapper': |
769 this_v8_conversion_type = dom_wrapper_conversion_type() | 840 this_v8_conversion_type = dom_wrapper_conversion_type() |
| 841 if is_static and this_v8_conversion_type in ('Dictionary', 'NullableDictiona
ry', 'DictionaryOrUnion'): |
| 842 this_v8_conversion_type += 'Static' |
770 | 843 |
771 format_string = V8_SET_RETURN_VALUE[this_v8_conversion_type] | 844 format_string = V8_SET_RETURN_VALUE[this_v8_conversion_type] |
772 # FIXME: oilpan: Remove .release() once we remove all RefPtrs from generated
code. | 845 # FIXME: oilpan: Remove .release() once we remove all RefPtrs from generated
code. |
773 if release: | 846 if release: |
774 cpp_value = '%s.release()' % cpp_value | 847 cpp_value = '%s.release()' % cpp_value |
775 statement = format_string.format(cpp_value=cpp_value, script_wrappable=scrip
t_wrappable) | 848 statement = format_string.format(cpp_value=cpp_value, script_wrappable=scrip
t_wrappable) |
776 return statement | 849 return statement |
777 | 850 |
778 | 851 |
779 def v8_set_return_value_union(idl_type, cpp_value, extended_attributes=None, scr
ipt_wrappable='', release=False, for_main_world=False): | |
780 # FIXME: Need to revisit the design of union support. | |
781 # http://crbug.com/240176 | |
782 return None | |
783 | |
784 | |
785 IdlTypeBase.v8_set_return_value = v8_set_return_value | 852 IdlTypeBase.v8_set_return_value = v8_set_return_value |
786 IdlUnionType.v8_set_return_value = v8_set_return_value_union | |
787 | 853 |
788 IdlType.release = property(lambda self: self.is_interface_type) | 854 IdlType.release = property(lambda self: self.is_interface_type) |
789 IdlUnionType.release = property( | 855 IdlUnionType.release = False |
790 lambda self: [member_type.is_interface_type | |
791 for member_type in self.member_types]) | |
792 | 856 |
793 | 857 |
794 CPP_VALUE_TO_V8_VALUE = { | 858 CPP_VALUE_TO_V8_VALUE = { |
795 # Built-in types | 859 # Built-in types |
796 'Date': 'v8DateOrNaN({cpp_value}, {isolate})', | 860 'Date': 'v8DateOrNaN({isolate}, {cpp_value})', |
797 'DOMString': 'v8String({isolate}, {cpp_value})', | 861 'DOMString': 'v8String({isolate}, {cpp_value})', |
798 'ByteString': 'v8String({isolate}, {cpp_value})', | 862 'ByteString': 'v8String({isolate}, {cpp_value})', |
799 'ScalarValueString': 'v8String({isolate}, {cpp_value})', | 863 'USVString': 'v8String({isolate}, {cpp_value})', |
800 'boolean': 'v8Boolean({cpp_value}, {isolate})', | 864 'boolean': 'v8Boolean({cpp_value}, {isolate})', |
801 'int': 'v8::Integer::New({isolate}, {cpp_value})', | 865 'int': 'v8::Integer::New({isolate}, {cpp_value})', |
802 'unsigned': 'v8::Integer::NewFromUnsigned({isolate}, {cpp_value})', | 866 'unsigned': 'v8::Integer::NewFromUnsigned({isolate}, {cpp_value})', |
803 'float': 'v8::Number::New({isolate}, {cpp_value})', | 867 'float': 'v8::Number::New({isolate}, {cpp_value})', |
804 'unrestricted float': 'v8::Number::New({isolate}, {cpp_value})', | 868 'unrestricted float': 'v8::Number::New({isolate}, {cpp_value})', |
805 'double': 'v8::Number::New({isolate}, {cpp_value})', | 869 'double': 'v8::Number::New({isolate}, {cpp_value})', |
806 'unrestricted double': 'v8::Number::New({isolate}, {cpp_value})', | 870 'unrestricted double': 'v8::Number::New({isolate}, {cpp_value})', |
807 'void': 'v8Undefined()', | 871 'void': 'v8Undefined()', |
808 # [TreatReturnedNullStringAs] | 872 # [TreatReturnedNullStringAs] |
809 'StringOrNull': '{cpp_value}.isNull() ? v8::Handle<v8::Value>(v8::Null({isol
ate})) : v8String({isolate}, {cpp_value})', | 873 'StringOrNull': '{cpp_value}.isNull() ? v8::Local<v8::Value>(v8::Null({isola
te})) : v8String({isolate}, {cpp_value})', |
810 'StringOrUndefined': '{cpp_value}.isNull() ? v8Undefined() : v8String({isola
te}, {cpp_value})', | 874 'StringOrUndefined': '{cpp_value}.isNull() ? v8Undefined() : v8String({isola
te}, {cpp_value})', |
811 # Special cases | 875 # Special cases |
812 'EventHandler': '{cpp_value} ? v8::Handle<v8::Value>(V8AbstractEventListener
::cast({cpp_value})->getListenerObject(impl->executionContext())) : v8::Handle<v
8::Value>(v8::Null({isolate}))', | 876 'Dictionary': '{cpp_value}.v8Value()', |
| 877 'EventHandler': '{cpp_value} ? v8::Local<v8::Value>(V8AbstractEventListener:
:cast({cpp_value})->getListenerObject(impl->executionContext())) : v8::Local<v8:
:Value>(v8::Null({isolate}))', |
813 'ScriptValue': '{cpp_value}.v8Value()', | 878 'ScriptValue': '{cpp_value}.v8Value()', |
814 'SerializedScriptValue': '{cpp_value} ? {cpp_value}->deserialize() : v8::Han
dle<v8::Value>(v8::Null({isolate}))', | 879 'SerializedScriptValue': '{cpp_value} ? {cpp_value}->deserialize() : v8::Loc
al<v8::Value>(v8::Null({isolate}))', |
815 # General | 880 # General |
816 'array': 'v8Array({cpp_value}, {creation_context}, {isolate})', | 881 'array': 'toV8({cpp_value}, {creation_context}, {isolate})', |
817 'DOMWrapper': 'toV8({cpp_value}, {creation_context}, {isolate})', | 882 'DOMWrapper': 'toV8({cpp_value}, {creation_context}, {isolate})', |
| 883 # Passing nullable dictionaries isn't a pattern currently used |
| 884 # anywhere in the web platform, and more work would be needed in |
| 885 # the code generator to distinguish between passing null, and |
| 886 # passing an object which happened to not contain any of the |
| 887 # dictionary's defined attributes. For now, don't define |
| 888 # NullableDictionary here, which will cause an exception to be |
| 889 # thrown during code generation if an argument to a method is a |
| 890 # nullable dictionary type. |
| 891 # |
| 892 # Union types or dictionaries |
| 893 'DictionaryOrUnion': 'toV8({cpp_value}, {creation_context}, {isolate})', |
818 } | 894 } |
819 | 895 |
820 | 896 |
821 def cpp_value_to_v8_value(idl_type, cpp_value, isolate='info.GetIsolate()', crea
tion_context='info.Holder()', extended_attributes=None): | 897 def cpp_value_to_v8_value(idl_type, cpp_value, isolate='info.GetIsolate()', crea
tion_context='info.Holder()', extended_attributes=None): |
822 """Returns an expression that converts a C++ value to a V8 value.""" | 898 """Returns an expression that converts a C++ value to a V8 value.""" |
823 # the isolate parameter is needed for callback interfaces | 899 # the isolate parameter is needed for callback interfaces |
824 idl_type, cpp_value = preprocess_idl_type_and_value(idl_type, cpp_value, ext
ended_attributes) | 900 idl_type, cpp_value = preprocess_idl_type_and_value(idl_type, cpp_value, ext
ended_attributes) |
825 this_v8_conversion_type = idl_type.v8_conversion_type(extended_attributes) | 901 this_v8_conversion_type = idl_type.v8_conversion_type(extended_attributes) |
826 format_string = CPP_VALUE_TO_V8_VALUE[this_v8_conversion_type] | 902 format_string = CPP_VALUE_TO_V8_VALUE[this_v8_conversion_type] |
827 statement = format_string.format(cpp_value=cpp_value, isolate=isolate, creat
ion_context=creation_context) | 903 statement = format_string.format(cpp_value=cpp_value, isolate=isolate, creat
ion_context=creation_context) |
828 return statement | 904 return statement |
829 | 905 |
830 IdlTypeBase.cpp_value_to_v8_value = cpp_value_to_v8_value | 906 IdlTypeBase.cpp_value_to_v8_value = cpp_value_to_v8_value |
831 | 907 |
832 | 908 |
833 def literal_cpp_value(idl_type, idl_literal): | 909 def literal_cpp_value(idl_type, idl_literal): |
834 """Converts an expression that is a valid C++ literal for this type.""" | 910 """Converts an expression that is a valid C++ literal for this type.""" |
835 # FIXME: add validation that idl_type and idl_literal are compatible | 911 # FIXME: add validation that idl_type and idl_literal are compatible |
| 912 if idl_type.base_type in ('any', 'object') and idl_literal.is_null: |
| 913 return 'ScriptValue()' |
836 literal_value = str(idl_literal) | 914 literal_value = str(idl_literal) |
837 if idl_type.base_type in CPP_UNSIGNED_TYPES: | 915 if idl_type.base_type in CPP_UNSIGNED_TYPES: |
838 return literal_value + 'u' | 916 return literal_value + 'u' |
839 return literal_value | 917 return literal_value |
840 | 918 |
| 919 |
| 920 def union_literal_cpp_value(idl_type, idl_literal): |
| 921 if idl_literal.is_null: |
| 922 return idl_type.name + '()' |
| 923 elif idl_literal.idl_type == 'DOMString': |
| 924 member_type = idl_type.string_member_type |
| 925 elif idl_literal.idl_type in ('integer', 'float'): |
| 926 member_type = idl_type.numeric_member_type |
| 927 elif idl_literal.idl_type == 'boolean': |
| 928 member_type = idl_type.boolean_member_type |
| 929 else: |
| 930 raise ValueError('Unsupported literal type: ' + idl_literal.idl_type) |
| 931 |
| 932 return '%s::from%s(%s)' % (idl_type.name, member_type.name, |
| 933 member_type.literal_cpp_value(idl_literal)) |
| 934 |
| 935 |
| 936 def array_or_sequence_literal_cpp_value(idl_type, idl_literal): |
| 937 # Only support empty arrays. |
| 938 if idl_literal.value == '[]': |
| 939 return cpp_type(idl_type) + '()' |
| 940 raise ValueError('Unsupported literal type: ' + idl_literal.idl_type) |
| 941 |
| 942 |
841 IdlType.literal_cpp_value = literal_cpp_value | 943 IdlType.literal_cpp_value = literal_cpp_value |
| 944 IdlUnionType.literal_cpp_value = union_literal_cpp_value |
| 945 IdlArrayOrSequenceType.literal_cpp_value = array_or_sequence_literal_cpp_value |
842 | 946 |
843 | 947 |
844 ################################################################################ | 948 ################################################################################ |
845 # Utility properties for nullable types | 949 # Utility properties for nullable types |
846 ################################################################################ | 950 ################################################################################ |
847 | 951 |
848 | 952 |
849 def cpp_type_has_null_value(idl_type): | 953 def cpp_type_has_null_value(idl_type): |
850 # - String types (String/AtomicString) represent null as a null string, | 954 # - String types (String/AtomicString) represent null as a null string, |
851 # i.e. one for which String::isNull() returns true. | 955 # i.e. one for which String::isNull() returns true. |
852 # - Enum types, as they are implemented as Strings. | 956 # - Enum types, as they are implemented as Strings. |
853 # - Wrapper types (raw pointer or RefPtr/PassRefPtr) represent null as | 957 # - Interface types (raw pointer or RefPtr/PassRefPtr) represent null as |
854 # a null pointer. | 958 # a null pointer. |
855 # - Dictionary types represent null as a null pointer. They are garbage | 959 # - Union types, as thier container classes can represent null value. |
856 # collected so their type is raw pointer. | 960 # - 'Object' and 'any' type. We use ScriptValue for object type. |
857 # - 'Object' type. We use ScriptValue for object type. | 961 return (idl_type.is_string_type or idl_type.is_interface_type or |
858 return (idl_type.is_string_type or idl_type.is_wrapper_type or | 962 idl_type.is_enum or idl_type.is_union_type |
859 idl_type.is_enum or idl_type.is_dictionary or idl_type.base_type ==
'object') | 963 or idl_type.base_type == 'object' or idl_type.base_type == 'any' |
| 964 or idl_type.is_callback_function or idl_type.is_callback_interface) |
860 | 965 |
861 IdlTypeBase.cpp_type_has_null_value = property(cpp_type_has_null_value) | 966 IdlTypeBase.cpp_type_has_null_value = property(cpp_type_has_null_value) |
862 | 967 |
863 | 968 |
864 def is_implicit_nullable(idl_type): | 969 def is_implicit_nullable(idl_type): |
865 # Nullable type where the corresponding C++ type supports a null value. | 970 # Nullable type where the corresponding C++ type supports a null value. |
866 return idl_type.is_nullable and idl_type.cpp_type_has_null_value | 971 return idl_type.is_nullable and idl_type.cpp_type_has_null_value |
867 | 972 |
868 | 973 |
869 def is_explicit_nullable(idl_type): | 974 def is_explicit_nullable(idl_type): |
870 # Nullable type that isn't implicit nullable (see above.) For such types, | 975 # Nullable type that isn't implicit nullable (see above.) For such types, |
871 # we use Nullable<T> or similar explicit ways to represent a null value. | 976 # we use Nullable<T> or similar explicit ways to represent a null value. |
872 return idl_type.is_nullable and not idl_type.is_implicit_nullable | 977 return idl_type.is_nullable and not idl_type.is_implicit_nullable |
873 | 978 |
874 IdlTypeBase.is_implicit_nullable = property(is_implicit_nullable) | 979 IdlTypeBase.is_implicit_nullable = property(is_implicit_nullable) |
875 IdlUnionType.is_implicit_nullable = False | 980 IdlUnionType.is_implicit_nullable = False |
876 IdlTypeBase.is_explicit_nullable = property(is_explicit_nullable) | 981 IdlTypeBase.is_explicit_nullable = property(is_explicit_nullable) |
| 982 |
| 983 |
| 984 def number_of_nullable_member_types_union(idl_type): |
| 985 # http://heycam.github.io/webidl/#dfn-number-of-nullable-member-types |
| 986 count = 0 |
| 987 for member in idl_type.member_types: |
| 988 if member.is_nullable: |
| 989 count += 1 |
| 990 member = member.inner_type |
| 991 if member.is_union_type: |
| 992 count += number_of_nullable_member_types_union(member) |
| 993 return count |
| 994 |
| 995 IdlUnionType.number_of_nullable_member_types = property( |
| 996 number_of_nullable_member_types_union) |
| 997 |
| 998 |
| 999 def includes_nullable_type_union(idl_type): |
| 1000 # http://heycam.github.io/webidl/#dfn-includes-a-nullable-type |
| 1001 return idl_type.number_of_nullable_member_types == 1 |
| 1002 |
| 1003 IdlTypeBase.includes_nullable_type = False |
| 1004 IdlNullableType.includes_nullable_type = True |
| 1005 IdlUnionType.includes_nullable_type = property(includes_nullable_type_union) |
OLD | NEW |