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 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
104 CPP_UNSIGNED_TYPES = set([ | 104 CPP_UNSIGNED_TYPES = set([ |
105 'octet', | 105 'octet', |
106 'unsigned int', | 106 'unsigned int', |
107 'unsigned long', | 107 'unsigned long', |
108 'unsigned short', | 108 'unsigned short', |
109 ]) | 109 ]) |
110 CPP_SPECIAL_CONVERSION_RULES = { | 110 CPP_SPECIAL_CONVERSION_RULES = { |
111 'Date': 'double', | 111 'Date': 'double', |
112 'Dictionary': 'Dictionary', | 112 'Dictionary': 'Dictionary', |
113 'EventHandler': 'EventListener*', | 113 'EventHandler': 'EventListener*', |
114 'NodeFilter': 'RawPtr<NodeFilter>', | 114 'NodeFilter': 'NodeFilter*', |
115 'Promise': 'ScriptPromise', | 115 'Promise': 'ScriptPromise', |
116 'ScriptValue': 'ScriptValue', | 116 'ScriptValue': 'ScriptValue', |
117 # FIXME: Eliminate custom bindings for XPathNSResolver http://crbug.com/345
529 | 117 # FIXME: Eliminate custom bindings for XPathNSResolver http://crbug.com/345
529 |
118 'XPathNSResolver': 'RawPtr<XPathNSResolver>', | 118 'XPathNSResolver': 'XPathNSResolver*', |
119 'boolean': 'bool', | 119 'boolean': 'bool', |
120 'unrestricted double': 'double', | 120 'unrestricted double': 'double', |
121 'unrestricted float': 'float', | 121 'unrestricted float': 'float', |
122 } | 122 } |
123 | 123 |
124 | 124 |
125 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): | 125 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): |
126 """Returns C++ type corresponding to IDL type. | 126 """Returns C++ type corresponding to IDL type. |
127 | 127 |
128 |idl_type| argument is of type IdlType, while return value is a string | 128 |idl_type| argument is of type IdlType, while return value is a string |
(...skipping 25 matching lines...) Expand all Loading... |
154 | 154 |
155 extended_attributes = extended_attributes or {} | 155 extended_attributes = extended_attributes or {} |
156 idl_type = idl_type.preprocessed_type | 156 idl_type = idl_type.preprocessed_type |
157 | 157 |
158 # Array or sequence types | 158 # Array or sequence types |
159 if used_as_variadic_argument: | 159 if used_as_variadic_argument: |
160 native_array_element_type = idl_type | 160 native_array_element_type = idl_type |
161 else: | 161 else: |
162 native_array_element_type = idl_type.native_array_element_type | 162 native_array_element_type = idl_type.native_array_element_type |
163 if native_array_element_type: | 163 if native_array_element_type: |
164 vector_type = cpp_ptr_type('Vector', 'HeapVector', native_array_element_
type.gc_type) | 164 vector_type = cpp_ptr_type('Vector', 'HeapVector', native_array_element_
type.is_gc_type) |
165 vector_template_type = cpp_template_type(vector_type, native_array_eleme
nt_type.cpp_type_args(used_in_cpp_sequence=True)) | 165 vector_template_type = cpp_template_type(vector_type, native_array_eleme
nt_type.cpp_type_args(used_in_cpp_sequence=True)) |
166 if used_as_rvalue_type: | 166 if used_as_rvalue_type: |
167 return 'const %s&' % vector_template_type | 167 return 'const %s&' % vector_template_type |
168 return vector_template_type | 168 return vector_template_type |
169 | 169 |
170 # Simple types | 170 # Simple types |
171 base_idl_type = idl_type.base_type | 171 base_idl_type = idl_type.base_type |
172 | 172 |
173 if base_idl_type in CPP_TYPE_SAME_AS_IDL_TYPE: | 173 if base_idl_type in CPP_TYPE_SAME_AS_IDL_TYPE: |
174 return base_idl_type | 174 return base_idl_type |
(...skipping 10 matching lines...) Expand all Loading... |
185 if not raw_type: | 185 if not raw_type: |
186 return 'String' | 186 return 'String' |
187 return 'V8StringResource<%s>' % string_mode() | 187 return 'V8StringResource<%s>' % string_mode() |
188 | 188 |
189 if idl_type.base_type == 'ArrayBufferView' and 'FlexibleArrayBufferView' in
extended_attributes: | 189 if idl_type.base_type == 'ArrayBufferView' and 'FlexibleArrayBufferView' in
extended_attributes: |
190 return 'FlexibleArrayBufferView' | 190 return 'FlexibleArrayBufferView' |
191 if idl_type.base_type in TYPED_ARRAY_TYPES and 'FlexibleArrayBufferView' in
extended_attributes: | 191 if idl_type.base_type in TYPED_ARRAY_TYPES and 'FlexibleArrayBufferView' in
extended_attributes: |
192 return 'Flexible' + idl_type.base_type + 'View' | 192 return 'Flexible' + idl_type.base_type + 'View' |
193 if idl_type.is_interface_type: | 193 if idl_type.is_interface_type: |
194 implemented_as_class = idl_type.implemented_as | 194 implemented_as_class = idl_type.implemented_as |
195 if raw_type or (used_as_rvalue_type and idl_type.is_garbage_collected): | 195 if raw_type or (used_as_rvalue_type and idl_type.is_garbage_collected) o
r not used_in_cpp_sequence: |
196 return implemented_as_class + '*' | 196 return implemented_as_class + '*' |
197 new_type = 'Member' if used_in_cpp_sequence else 'RawPtr' | 197 if not used_in_cpp_sequence: |
198 ptr_type = cpp_ptr_type(('PassRefPtr' if used_as_rvalue_type else 'RefPt
r'), new_type, idl_type.gc_type) | 198 return implemented_as_class + '*' |
199 return cpp_template_type(ptr_type, implemented_as_class) | 199 return cpp_template_type('Member', implemented_as_class) |
200 if idl_type.is_dictionary: | 200 if idl_type.is_dictionary: |
201 return base_idl_type | 201 return base_idl_type |
202 if idl_type.is_union_type: | 202 if idl_type.is_union_type: |
203 # Avoid "AOrNullOrB" for cpp type of (A? or B) because we generate | 203 # Avoid "AOrNullOrB" for cpp type of (A? or B) because we generate |
204 # V8AOrBOrNull to handle nulle for (A? or B), (A or B?) and (A or B)? | 204 # V8AOrBOrNull to handle nulle for (A? or B), (A or B?) and (A or B)? |
205 def member_cpp_name(idl_type): | 205 def member_cpp_name(idl_type): |
206 if idl_type.is_nullable: | 206 if idl_type.is_nullable: |
207 return idl_type.inner_type.name | 207 return idl_type.inner_type.name |
208 return idl_type.name | 208 return idl_type.name |
209 idl_type_name = "Or".join(member_cpp_name(member) | 209 idl_type_name = "Or".join(member_cpp_name(member) |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
248 IdlArrayOrSequenceType.native_array_element_type = property( | 248 IdlArrayOrSequenceType.native_array_element_type = property( |
249 lambda self: self.element_type) | 249 lambda self: self.element_type) |
250 | 250 |
251 | 251 |
252 def cpp_template_type(template, inner_type): | 252 def cpp_template_type(template, inner_type): |
253 """Returns C++ template specialized to type.""" | 253 """Returns C++ template specialized to type.""" |
254 format_string = '{template}<{inner_type}>' | 254 format_string = '{template}<{inner_type}>' |
255 return format_string.format(template=template, inner_type=inner_type) | 255 return format_string.format(template=template, inner_type=inner_type) |
256 | 256 |
257 | 257 |
258 def cpp_ptr_type(old_type, new_type, gc_type): | 258 def cpp_ptr_type(old_type, new_type, is_gc_type): |
259 if gc_type == 'GarbageCollectedObject': | 259 if is_gc_type: |
260 return new_type | 260 return new_type |
261 return old_type | 261 return old_type |
262 | 262 |
263 | 263 |
264 def v8_type(interface_name): | 264 def v8_type(interface_name): |
265 return 'V8' + interface_name | 265 return 'V8' + interface_name |
266 | 266 |
267 | 267 |
268 # [ImplementedAs] | 268 # [ImplementedAs] |
269 # This handles [ImplementedAs] on interface types, not [ImplementedAs] in the | 269 # This handles [ImplementedAs] on interface types, not [ImplementedAs] in the |
(...skipping 24 matching lines...) Expand all Loading... |
294 IdlType.garbage_collected_types = set() | 294 IdlType.garbage_collected_types = set() |
295 | 295 |
296 IdlType.is_garbage_collected = property( | 296 IdlType.is_garbage_collected = property( |
297 lambda self: self.base_type in IdlType.garbage_collected_types) | 297 lambda self: self.base_type in IdlType.garbage_collected_types) |
298 | 298 |
299 IdlType.set_garbage_collected_types = classmethod( | 299 IdlType.set_garbage_collected_types = classmethod( |
300 lambda cls, new_garbage_collected_types: | 300 lambda cls, new_garbage_collected_types: |
301 cls.garbage_collected_types.update(new_garbage_collected_types)) | 301 cls.garbage_collected_types.update(new_garbage_collected_types)) |
302 | 302 |
303 | 303 |
304 def gc_type(idl_type): | 304 def is_gc_type(idl_type): |
305 if idl_type.is_garbage_collected or idl_type.is_dictionary or idl_type.is_un
ion_type: | 305 return idl_type.is_garbage_collected or idl_type.is_dictionary or idl_type.i
s_union_type |
306 return 'GarbageCollectedObject' | |
307 return 'RefCountedObject' | |
308 | 306 |
309 IdlTypeBase.gc_type = property(gc_type) | 307 |
| 308 IdlTypeBase.is_gc_type = property(is_gc_type) |
310 | 309 |
311 | 310 |
312 def is_traceable(idl_type): | 311 def is_traceable(idl_type): |
313 return (idl_type.is_garbage_collected or idl_type.is_dictionary) | 312 return (idl_type.is_garbage_collected or idl_type.is_dictionary) |
314 | 313 |
315 IdlTypeBase.is_traceable = property(is_traceable) | 314 IdlTypeBase.is_traceable = property(is_traceable) |
316 IdlUnionType.is_traceable = property(lambda self: True) | 315 IdlUnionType.is_traceable = property(lambda self: True) |
317 IdlArrayOrSequenceType.is_traceable = property( | 316 IdlArrayOrSequenceType.is_traceable = property( |
318 lambda self: self.element_type.is_traceable) | 317 lambda self: self.element_type.is_traceable) |
319 | 318 |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
581 def v8_value_to_cpp_value_array_or_sequence(native_array_element_type, v8_value,
index, isolate='info.GetIsolate()'): | 580 def v8_value_to_cpp_value_array_or_sequence(native_array_element_type, v8_value,
index, isolate='info.GetIsolate()'): |
582 # Index is None for setters, index (starting at 0) for method arguments, | 581 # Index is None for setters, index (starting at 0) for method arguments, |
583 # and is used to provide a human-readable exception message | 582 # and is used to provide a human-readable exception message |
584 if index is None: | 583 if index is None: |
585 index = 0 # special case, meaning "setter" | 584 index = 0 # special case, meaning "setter" |
586 else: | 585 else: |
587 index += 1 # human-readable index | 586 index += 1 # human-readable index |
588 if (native_array_element_type.is_interface_type and | 587 if (native_array_element_type.is_interface_type and |
589 native_array_element_type.name != 'Dictionary'): | 588 native_array_element_type.name != 'Dictionary'): |
590 this_cpp_type = None | 589 this_cpp_type = None |
591 ref_ptr_type = cpp_ptr_type('RefPtr', 'Member', native_array_element_typ
e.gc_type) | 590 ref_ptr_type = 'Member' |
592 expression_format = '(to{ref_ptr_type}NativeArray<{native_array_element_
type}, V8{native_array_element_type}>({v8_value}, {index}, {isolate}, exceptionS
tate))' | 591 expression_format = '(to{ref_ptr_type}NativeArray<{native_array_element_
type}, V8{native_array_element_type}>({v8_value}, {index}, {isolate}, exceptionS
tate))' |
593 else: | 592 else: |
594 ref_ptr_type = None | 593 ref_ptr_type = None |
595 this_cpp_type = native_array_element_type.cpp_type | 594 this_cpp_type = native_array_element_type.cpp_type |
596 if native_array_element_type.is_dictionary or native_array_element_type.
is_union_type: | 595 if native_array_element_type.is_dictionary or native_array_element_type.
is_union_type: |
597 vector_type = 'HeapVector' | 596 vector_type = 'HeapVector' |
598 else: | 597 else: |
599 vector_type = 'Vector' | 598 vector_type = 'Vector' |
600 expression_format = 'toImplArray<%s<{cpp_type}>>({v8_value}, {index}, {i
solate}, exceptionState)' % vector_type | 599 expression_format = 'toImplArray<%s<{cpp_type}>>({v8_value}, {index}, {i
solate}, exceptionState)' % vector_type |
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) | 600 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) |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
785 'double': 'v8SetReturnValue(info, {cpp_value})', | 784 'double': 'v8SetReturnValue(info, {cpp_value})', |
786 'unrestricted double': 'v8SetReturnValue(info, {cpp_value})', | 785 'unrestricted double': 'v8SetReturnValue(info, {cpp_value})', |
787 # No special v8SetReturnValue* function, but instead convert value to V8 | 786 # No special v8SetReturnValue* function, but instead convert value to V8 |
788 # and then use general v8SetReturnValue. | 787 # and then use general v8SetReturnValue. |
789 'array': 'v8SetReturnValue(info, {cpp_value})', | 788 'array': 'v8SetReturnValue(info, {cpp_value})', |
790 'Date': 'v8SetReturnValue(info, {cpp_value})', | 789 'Date': 'v8SetReturnValue(info, {cpp_value})', |
791 'EventHandler': 'v8SetReturnValue(info, {cpp_value})', | 790 'EventHandler': 'v8SetReturnValue(info, {cpp_value})', |
792 'ScriptValue': 'v8SetReturnValue(info, {cpp_value})', | 791 'ScriptValue': 'v8SetReturnValue(info, {cpp_value})', |
793 'SerializedScriptValue': 'v8SetReturnValue(info, {cpp_value})', | 792 'SerializedScriptValue': 'v8SetReturnValue(info, {cpp_value})', |
794 # DOMWrapper | 793 # DOMWrapper |
795 'DOMWrapperForMainWorld': 'v8SetReturnValueForMainWorld(info, WTF::getPtr({c
pp_value}))', | 794 'DOMWrapperForMainWorld': 'v8SetReturnValueForMainWorld(info, {cpp_value})', |
796 'DOMWrapperFast': 'v8SetReturnValueFast(info, WTF::getPtr({cpp_value}), {scr
ipt_wrappable})', | 795 'DOMWrapperFast': 'v8SetReturnValueFast(info, {cpp_value}, {script_wrappable
})', |
797 'DOMWrapperDefault': 'v8SetReturnValue(info, {cpp_value})', | 796 'DOMWrapperDefault': 'v8SetReturnValue(info, {cpp_value})', |
798 # Note that static attributes and operations do not check whether |this| is | 797 # Note that static attributes and operations do not check whether |this| is |
799 # an instance of the interface nor |this|'s creation context is the same as | 798 # an instance of the interface nor |this|'s creation context is the same as |
800 # the current context. So we must always use the current context as the | 799 # the current context. So we must always use the current context as the |
801 # creation context of the DOM wrapper for the return value. | 800 # creation context of the DOM wrapper for the return value. |
802 'DOMWrapperStatic': 'v8SetReturnValue(info, {cpp_value}, info.GetIsolate()->
GetCurrentContext()->Global())', | 801 'DOMWrapperStatic': 'v8SetReturnValue(info, {cpp_value}, info.GetIsolate()->
GetCurrentContext()->Global())', |
803 # Generic dictionary type | 802 # Generic dictionary type |
804 'Dictionary': 'v8SetReturnValue(info, {cpp_value})', | 803 'Dictionary': 'v8SetReturnValue(info, {cpp_value})', |
805 'DictionaryStatic': '#error not implemented yet', | 804 'DictionaryStatic': '#error not implemented yet', |
806 # Nullable dictionaries | 805 # Nullable dictionaries |
807 'NullableDictionary': 'v8SetReturnValue(info, result.get())', | 806 'NullableDictionary': 'v8SetReturnValue(info, result.get())', |
808 'NullableDictionaryStatic': '#error not implemented yet', | 807 'NullableDictionaryStatic': '#error not implemented yet', |
809 # Union types or dictionaries | 808 # Union types or dictionaries |
810 'DictionaryOrUnion': 'v8SetReturnValue(info, result)', | 809 'DictionaryOrUnion': 'v8SetReturnValue(info, result)', |
811 'DictionaryOrUnionStatic': '#error not implemented yet', | 810 'DictionaryOrUnionStatic': '#error not implemented yet', |
812 } | 811 } |
813 | 812 |
814 | 813 |
815 def v8_set_return_value(idl_type, cpp_value, extended_attributes=None, script_wr
appable='', release=False, for_main_world=False, is_static=False): | 814 def v8_set_return_value(idl_type, cpp_value, extended_attributes=None, script_wr
appable='', for_main_world=False, is_static=False): |
816 """Returns a statement that converts a C++ value to a V8 value and sets it a
s a return value. | 815 """Returns a statement that converts a C++ value to a V8 value and sets it a
s a return value. |
817 | 816 |
818 """ | 817 """ |
819 def dom_wrapper_conversion_type(): | 818 def dom_wrapper_conversion_type(): |
820 if is_static: | 819 if is_static: |
821 return 'DOMWrapperStatic' | 820 return 'DOMWrapperStatic' |
822 if not script_wrappable: | 821 if not script_wrappable: |
823 return 'DOMWrapperDefault' | 822 return 'DOMWrapperDefault' |
824 if for_main_world: | 823 if for_main_world: |
825 return 'DOMWrapperForMainWorld' | 824 return 'DOMWrapperForMainWorld' |
826 return 'DOMWrapperFast' | 825 return 'DOMWrapperFast' |
827 | 826 |
828 idl_type, cpp_value = preprocess_idl_type_and_value(idl_type, cpp_value, ext
ended_attributes) | 827 idl_type, cpp_value = preprocess_idl_type_and_value(idl_type, cpp_value, ext
ended_attributes) |
829 this_v8_conversion_type = idl_type.v8_conversion_type(extended_attributes) | 828 this_v8_conversion_type = idl_type.v8_conversion_type(extended_attributes) |
830 # SetReturn-specific overrides | 829 # SetReturn-specific overrides |
831 if this_v8_conversion_type in ['Date', 'EventHandler', 'ScriptValue', 'Seria
lizedScriptValue', 'array']: | 830 if this_v8_conversion_type in ['Date', 'EventHandler', 'ScriptValue', 'Seria
lizedScriptValue', 'array']: |
832 # Convert value to V8 and then use general v8SetReturnValue | 831 # Convert value to V8 and then use general v8SetReturnValue |
833 cpp_value = idl_type.cpp_value_to_v8_value(cpp_value, extended_attribute
s=extended_attributes) | 832 cpp_value = idl_type.cpp_value_to_v8_value(cpp_value, extended_attribute
s=extended_attributes) |
834 if this_v8_conversion_type == 'DOMWrapper': | 833 if this_v8_conversion_type == 'DOMWrapper': |
835 this_v8_conversion_type = dom_wrapper_conversion_type() | 834 this_v8_conversion_type = dom_wrapper_conversion_type() |
836 if is_static and this_v8_conversion_type in ('Dictionary', 'NullableDictiona
ry', 'DictionaryOrUnion'): | 835 if is_static and this_v8_conversion_type in ('Dictionary', 'NullableDictiona
ry', 'DictionaryOrUnion'): |
837 this_v8_conversion_type += 'Static' | 836 this_v8_conversion_type += 'Static' |
838 | 837 |
839 format_string = V8_SET_RETURN_VALUE[this_v8_conversion_type] | 838 format_string = V8_SET_RETURN_VALUE[this_v8_conversion_type] |
840 # FIXME: oilpan: Remove .release() once we remove all RefPtrs from generated
code. | |
841 if release: | |
842 cpp_value = '%s.release()' % cpp_value | |
843 statement = format_string.format(cpp_value=cpp_value, script_wrappable=scrip
t_wrappable) | 839 statement = format_string.format(cpp_value=cpp_value, script_wrappable=scrip
t_wrappable) |
844 return statement | 840 return statement |
845 | 841 |
846 | 842 |
847 IdlTypeBase.v8_set_return_value = v8_set_return_value | 843 IdlTypeBase.v8_set_return_value = v8_set_return_value |
848 | 844 |
849 IdlType.release = property(lambda self: self.is_interface_type) | |
850 IdlUnionType.release = False | |
851 | |
852 | 845 |
853 CPP_VALUE_TO_V8_VALUE = { | 846 CPP_VALUE_TO_V8_VALUE = { |
854 # Built-in types | 847 # Built-in types |
855 'Date': 'v8DateOrNaN({isolate}, {cpp_value})', | 848 'Date': 'v8DateOrNaN({isolate}, {cpp_value})', |
856 'DOMString': 'v8String({isolate}, {cpp_value})', | 849 'DOMString': 'v8String({isolate}, {cpp_value})', |
857 'ByteString': 'v8String({isolate}, {cpp_value})', | 850 'ByteString': 'v8String({isolate}, {cpp_value})', |
858 'USVString': 'v8String({isolate}, {cpp_value})', | 851 'USVString': 'v8String({isolate}, {cpp_value})', |
859 'boolean': 'v8Boolean({cpp_value}, {isolate})', | 852 'boolean': 'v8Boolean({cpp_value}, {isolate})', |
860 'int': 'v8::Integer::New({isolate}, {cpp_value})', | 853 'int': 'v8::Integer::New({isolate}, {cpp_value})', |
861 'unsigned': 'v8::Integer::NewFromUnsigned({isolate}, {cpp_value})', | 854 'unsigned': 'v8::Integer::NewFromUnsigned({isolate}, {cpp_value})', |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
989 number_of_nullable_member_types_union) | 982 number_of_nullable_member_types_union) |
990 | 983 |
991 | 984 |
992 def includes_nullable_type_union(idl_type): | 985 def includes_nullable_type_union(idl_type): |
993 # http://heycam.github.io/webidl/#dfn-includes-a-nullable-type | 986 # http://heycam.github.io/webidl/#dfn-includes-a-nullable-type |
994 return idl_type.number_of_nullable_member_types == 1 | 987 return idl_type.number_of_nullable_member_types == 1 |
995 | 988 |
996 IdlTypeBase.includes_nullable_type = False | 989 IdlTypeBase.includes_nullable_type = False |
997 IdlNullableType.includes_nullable_type = True | 990 IdlNullableType.includes_nullable_type = True |
998 IdlUnionType.includes_nullable_type = property(includes_nullable_type_union) | 991 IdlUnionType.includes_nullable_type = property(includes_nullable_type_union) |
OLD | NEW |