Index: Source/bindings/scripts/v8_types.py |
diff --git a/Source/bindings/scripts/v8_types.py b/Source/bindings/scripts/v8_types.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..aa19886b8cde96446f5a60901fbdbb8bdd72eb69 |
--- /dev/null |
+++ b/Source/bindings/scripts/v8_types.py |
@@ -0,0 +1,534 @@ |
+# Copyright (C) 2013 Google Inc. All rights reserved. |
+# |
+# Redistribution and use in source and binary forms, with or without |
+# modification, are permitted provided that the following conditions are |
+# met: |
+# |
+# * Redistributions of source code must retain the above copyright |
+# notice, this list of conditions and the following disclaimer. |
+# * Redistributions in binary form must reproduce the above |
+# copyright notice, this list of conditions and the following disclaimer |
+# in the documentation and/or other materials provided with the |
+# distribution. |
+# * Neither the name of Google Inc. nor the names of its |
+# contributors may be used to endorse or promote products derived from |
+# this software without specific prior written permission. |
+# |
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
+# 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
+ |
+import re |
+ |
+# WIP |
+import idl_definitions # for UnionType |
+from code_generator_idl_reader import implemented_as_cpp_name_from_idl_type, is_callback_interface_base |
+from v8_utilities import uncapitalize # for non-type function? |
+ |
+CPP_TYPE_SAME_AS_IDL_TYPE = set([ |
+ 'double', |
+ 'float', |
+ 'int', # FIXME: int is not an IDL type |
+ 'long long', |
+ 'unsigned long long', |
+]) |
+CPP_INT_TYPE = set([ |
+ 'byte', |
+ 'long', |
+ 'short', |
+]) |
+CPP_UNSIGNED_TYPE = set([ |
+ 'octet', |
+ 'unsigned int', |
+ 'unsigned long', |
+ 'unsigned short', |
+]) |
+CPP_TYPE_SPECIAL_CONVERSION_RULES = { |
+ 'boolean': 'bool', |
+ 'DOMString': 'const String&', |
+} |
+PRIMITIVE_TYPES = set([ |
+ # http://www.w3.org/TR/WebIDL/#dfn-primitive-type |
+ 'boolean', |
+ 'float', |
+ # unrestricted float is not supported |
+ 'double', |
+ # unrestricted double is not supported |
+ # integer types |
+ # http://www.w3.org/TR/WebIDL/#dfn-integer-type |
+ 'byte', |
+ 'octet', |
+ 'short', |
+ 'unsigned short', |
+ # int and unsigned are not IDL types |
+ 'long', |
+ 'unsigned long', |
+ 'long long', |
+ 'unsigned long long', |
+ # Blink-specific additions |
+ 'Date', |
+ 'void', |
+]) |
+ |
+ |
+def primitive_type(data_type): |
+ return data_type in PRIMITIVE_TYPES |
+ |
+ |
+def get_sequence_type(data_type): |
+ matched = re.match(r'sequence<([\w\d_\s]+)>', data_type) |
+ return matched and matched.group(1) |
+ |
+ |
+def get_array_type(data_type): |
+ matched = re.match(r'([\w\d_\s]+)\[\]', data_type) |
+ return matched and matched.group(1) |
+ |
+ |
+def get_array_or_sequence_type(data_type): |
+ return get_array_type(data_type) or get_sequence_type(data_type) |
+ |
+ |
+def cpp_type(data_type, pointer_type=None): |
+ """Returns the C++ type corresponding to the IDL type. |
+ |
+ Args: |
+ pointer_type: |
+ 'raw': return raw pointer form (e.g. Foo*) |
+ 'RefPtr': return RefPtr form (e.g. RefPtr<Foo>) |
+ 'PassRefPtr': return PassRefPtr form (e.g. RefPtr<Foo>) |
+ """ |
+ if data_type in CPP_TYPE_SAME_AS_IDL_TYPE: |
+ return data_type |
+ if data_type in CPP_INT_TYPE: |
+ return 'int' |
+ if data_type in CPP_UNSIGNED_TYPE: |
+ return 'unsigned' |
+ if data_type in CPP_TYPE_SPECIAL_CONVERSION_RULES: |
+ return CPP_TYPE_SPECIAL_CONVERSION_RULES[data_type] |
+ array_or_sequence_type = get_array_or_sequence_type(data_type) |
+ if array_or_sequence_type: |
+ # FIXME: const? |
+ # return 'const Vector<%s >&' % cpp_type(array_or_sequence_type, 'RefPtr') |
+ return 'Vector<%s >' % cpp_type(array_or_sequence_type, 'RefPtr') |
+ if pointer_type == 'raw': |
+ return data_type + '*' |
+ if pointer_type in ['RefPtr', 'PassRefPtr']: |
+ return '%s<%s>' % (pointer_type, data_type) |
+ raise Exception('Unrecognized pointer type: "%s"' % pointer_type) |
+ |
+ |
+def v8_type(data_type): |
+ return 'V8' + data_type |
+ |
+ |
+def get_v8_class_name(interface): |
+ return v8_type(interface.name) |
+ |
+ |
+################################################################################ |
+# WIP |
+################################################################################ |
+ |
+# name -> values |
+enum_types = {} |
+callback_function_types = set() |
+ |
+NON_WRAPPER_TYPES = set([ |
+ 'CompareHow', |
+ 'DOMTimeStamp', |
+ 'Dictionary', |
+ 'EventListener', |
+ 'EventHandler', |
+ 'MediaQueryListListener', |
+ 'NodeFilter', |
+ 'SerializedScriptValue', |
+ 'any', |
+]) |
+DOM_NODE_TYPES = set([ |
+ 'Attr', |
+ 'CDATASection', |
+ 'CharacterData', |
+ 'Comment', |
+ 'Document', |
+ 'DocumentFragment', |
+ 'DocumentType', |
+ 'Element', |
+ 'Entity', |
+ 'HTMLDocument', |
+ 'Node', |
+ 'Notation', |
+ 'ProcessingInstruction', |
+ 'ShadowRoot', |
+ 'SVGDocument', |
+ 'Text', |
+ 'TestNode', |
+]) |
+SVG_ATTRIBUTES_IN_HTML = set([ |
+ 'class', |
+ 'id', |
+ 'onabort', |
+ 'onclick', |
+ 'onerror', |
+ 'onload', |
+ 'onmousedown', |
+ 'onmousemove', |
+ 'onmouseout', |
+ 'onmouseover', |
+ 'onmouseup', |
+ 'onresize', |
+ 'onscroll', |
+ 'onunload', |
+]) |
+ |
+# IDL type: [element's C++ type, V8 type] |
+TYPED_ARRAYS = { |
+ 'ArrayBuffer': [], |
+ 'ArrayBufferView': [], |
+ 'Uint8Array': ['unsigned char', 'v8::kExternalUnsignedByteArray'], |
+ 'Uint8ClampedArray': ['unsigned char', 'v8::kExternalPixelArray'], |
+ 'Uint16Array': ['unsigned short', 'v8::kExternalUnsignedShortArray'], |
+ 'Uint32Array': ['unsigned int', 'v8::kExternalUnsignedIntArray'], |
+ 'Int8Array': ['signed char', 'v8::kExternalByteArray'], |
+ 'Int16Array': ['short', 'v8::kExternalShortArray'], |
+ 'Int32Array': ['int', 'v8::kExternalIntArray'], |
+ 'Float32Array': ['float', 'v8::kExternalFloatArray'], |
+ 'Float64Array': ['double', 'v8::kExternalDoubleArray'], |
+} |
+ |
+SVG_TYPE_NEEDING_TEAR_OFF_DICT = { |
+ 'SVGAngle': 'SVGPropertyTearOff<SVGAngle>', |
+ 'SVGLength': 'SVGPropertyTearOff<SVGLength>', |
+ 'SVGLengthList': 'SVGListPropertyTearOff<SVGLengthList>', |
+ 'SVGMatrix': 'SVGPropertyTearOff<SVGMatrix>', |
+ 'SVGNumber': 'SVGPropertyTearOff<SVGNumber>', |
+ 'SVGNumberList': 'SVGListPropertyTearOff<SVGNumberList>', |
+ 'SVGPathSegList': 'SVGPathSegListPropertyTearOff', |
+ 'SVGPoint': 'SVGPropertyTearOff<SVGPoint>', |
+ 'SVGPointList': 'SVGListPropertyTearOff<SVGPointList>', |
+ 'SVGPreserveAspectRatio': 'SVGPropertyTearOff<SVGPreserveAspectRatio>', |
+ 'SVGRect': 'SVGPropertyTearOff<SVGRect>', |
+ 'SVGStringList': 'SVGStaticListPropertyTearOff<SVGStringList>', |
+ 'SVGTransform': 'SVGPropertyTearOff<SVGTransform>', |
+ 'SVGTransformList': 'SVGTransformListPropertyTearOff', |
+} |
+ |
+ |
+def is_wrapper_type(data_type): |
+ return not( |
+ is_union_type(data_type) or |
+ get_array_type(data_type) or |
+ get_sequence_type(data_type) or |
+ is_callback_function_type(data_type) or |
+ is_enum_type(data_type) or |
+ is_primitive_type(data_type) or |
+ data_type == 'DOMString' or |
+ # FIXME: SVGPropertyTearOff<SVGAngle> -> False. is this OK? |
+ 'SVG' in data_type or |
+ data_type in NON_WRAPPER_TYPES) |
+ |
+ |
+def is_callback_interface_etc(data_type): |
+ return (data_type != 'ArrayBuffer' and |
+ is_wrapper_type(data_type) and |
+ is_callback_interface_base(data_type)) |
+ |
+ |
+# TODO: GetNativeTypeOfTypedArray |
+ |
+ |
+def is_typed_array_type(data_type): |
+ return data_type in TYPED_ARRAYS |
+ |
+ |
+def is_ref_ptr_type(data_type): |
+ return not( |
+ is_union_type(data_type) or |
+ data_type in ['any', 'DOMString'] or |
+ is_primitive_type(data_type) or |
+ get_array_type(data_type) or |
+ get_sequence_type(data_type) or |
+ is_callback_function_type(data_type) or |
+ is_enum_type(data_type)) |
+ |
+ |
+def is_primitive_type(data_type): |
+ return data_type in PRIMITIVE_TYPES |
+ |
+ |
+def is_enum_type(data_type): |
+ return data_type in enum_types |
+ |
+ |
+def is_callback_function_type(data_type): |
+ return data_type in callback_function_types |
+ |
+ |
+def is_dom_node_type(data_type): |
+ return (data_type in DOM_NODE_TYPES or |
+ (data_type.startswith(('HTML', 'SVG')) and data_type.endswith('Element'))) |
+ |
+ |
+def is_union_type(data_type): |
+ return isinstance(data_type, idl_definitions.IdlUnionType) |
+ |
+ |
+def skip_include_header(data_type): |
+ return (is_primitive_type(data_type) or |
+ is_enum_type(data_type) or |
+ is_callback_function_type(data_type) or |
+ data_type == 'DOMString') |
+ |
+ |
+################################################################################ |
+# SVG |
+################################################################################ |
+ |
+ |
+def is_svg_animated_type(data_type): |
+ return data_type.startswith('SVGAnimated') |
+ |
+ |
+def get_svg_type_needing_tear_off(data_type): |
+ return SVG_TYPE_NEEDING_TEAR_OFF_DICT.get(data_type, '') |
+ |
+ |
+def svg_type_with_writable_properties_needing_tear_off(data_type): |
+ return data_type in ['SVGPoint', 'SVGMatrix'] |
+ |
+ |
+def get_svg_wrapped_type_needing_tear_off(data_type): |
+ svg_type_needing_tear_off = get_svg_type_needing_tear_off(data_type) |
+ if not svg_type_needing_tear_off: |
+ return '' |
+ |
+ for name in ['SVGPropertyTearOff<', 'SVGListPropertyTearOff<', 'SVGStaticListPropertyTearOff<', 'SVGTransformListPropertyTearOff<']: |
+ svg_type_needing_tear_off = svg_type_needing_tear_off.replace(name, '') |
+ |
+ svg_type_needing_tear_off = svg_type_needing_tear_off.replace('>', '') |
+ return svg_type_needing_tear_off |
+ |
+ |
+def get_svg_property_types(cpp_type): |
+ header_includes = [] |
+ cpp_includes = [] |
+ svg_property_type = '' |
+ svg_list_property_type = '' |
+ svg_native_type = '' |
+ # print '[get_svg_property_types] svg_native_type', cpp_type |
+ |
+ if not re.search('SVG', cpp_type): |
+ return '', '', '', [], [] |
+ |
+ svg_native_type = get_svg_type_needing_tear_off(cpp_type) |
+ # print '[svg_native_type]', svg_native_type |
+ if not svg_native_type: |
+ return '', '', '', [], [] |
+ |
+ # Append space to avoid compilation errors when using PassRefPtr<$svgNativeType> |
+ svg_native_type += ' ' |
+ |
+ svg_wrapped_native_type = get_svg_wrapped_type_needing_tear_off(cpp_type) |
+ # print '[svg_wrapped_native_type]', svg_wrapped_native_type |
+ |
+ if 'SVGPropertyTearOff' in svg_native_type: |
+ svg_property_type = svg_wrapped_native_type |
+ header_includes.append('core/svg/properties/SVGAnimatedPropertyTearOff.h') |
+ elif 'SVGListPropertyTearOff' in svg_native_type or 'SVGStaticListPropertyTearOff' in svg_native_type or 'SVGTransformListPropertyTearOff' in svg_native_type: |
+ svg_list_property_type = svg_wrapped_native_type |
+ header_includes.append('core/svg/properties/SVGAnimatedListPropertyTearOff.h') |
+ elif 'SVGPathSegListPropertyTearOff' in svg_native_type: |
+ svg_list_property_type = svg_wrapped_native_type |
+ header_includes.append('core/svg/properties/SVGPathSegListPropertyTearOff.h') |
+ |
+ return svg_property_type, svg_list_property_type, svg_native_type, header_includes, cpp_includes |
+ |
+################################################################################ |
+# Not type functions? |
+################################################################################ |
+ |
+ |
+def is_read_only(attribute): |
+ return attribute.is_read_only and 'Replaceable' not in attribute.extended_attributes |
+ |
+ |
+def is_constructable(interface): |
+ return any([name in interface.extended_attributes |
+ for name in ['CustomConstructor', 'Constructor', 'ConstructorTemplate']]) |
+ |
+ |
+def has_custom_constructor(interface): |
+ return 'CustomConstructor' in interface.extended_attributes |
+ |
+ |
+def has_custom_implementation(operation): |
+ return operation and 'Custom' in operation.extended_attributes |
+ |
+ |
+def has_custom_getter(attribute): |
+ return any([name in attribute.extended_attributes |
+ for name in ['Custom', 'CustomGetter']]) |
+ |
+ |
+def has_custom_setter(attribute): |
+ return any([name in attribute.extended_attributes |
+ for name in ['Custom', 'CustomSetter']]) |
+ |
+ |
+def is_constructor_template(interface, template_name): |
+ return interface.extended_attributes.get('ConstructorTemplate') == template_name |
+ |
+ |
+def needs_opaque_root_for_gc(interface): |
+ return any([name in interface.extended_attributes |
+ for name in ['GenerateIsReachable', 'CustomIsReachable']]) |
+ |
+ |
+def get_context_enable_function(interface_or_attribute_or_function): |
+ # If a parameter is given (e.g. 'EnabledPerContext=FeatureName') return the {FeatureName}Allowed() method. |
+ enabled_per_context = interface_or_attribute_or_function.extended_attributes.get('EnabledPerContext') |
+ if enabled_per_context and interface_or_attribute_or_function.extended_attributes.get('EnabledPerContext') is not None: |
+ return 'ContextFeatures::%sEnabled' % uncapitalize(enabled_per_context) |
+ |
+ # Or it fallbacks to the attribute name if the parameter value is missing. |
+ return 'ContextFeatures::%sEnabled' % uncapitalize(interface_or_attribute_or_function.name) |
+ |
+ |
+def set_callback_function_types(callback_functions): |
+ callback_function_types = set(callback_functions) |
+ |
+ |
+def set_enum_types(enumerations): |
+ enum_types = dict([[enum.name, enum.values] for enum in enumerations.values()]) |
+ |
+ |
+def get_enum_values(data_type): |
+ return enum_types.get(data_type, []) |
+ |
+ |
+def get_native_type(idl_type, called_by_webcore=False, used_as_parameter=False, used_to_assign_js_value=False, extended_attributes=None): |
+ """ |
+ Return native type corresponds to IDL type. |
+ @param[in] idl_type ... IDL type |
+ @param[in] called_by_webcore |
+ @param[in] used_as_parameter |
+ |
+ TODO support used_as_parameter for all types |
+ """ |
+ extended_attributes = extended_attributes or {} |
+ # print '[get_native_type]', type |
+ if idl_type in ['float', 'double', 'long long', 'unsigned long long']: |
+ return idl_type |
+ if idl_type in ['int', 'long', 'short', 'byte']: |
+ return 'int' |
+ if idl_type in ['unsigned long', 'unsigned int', 'unsigned short', 'octet']: |
+ return 'unsigned' |
+ if idl_type == 'boolean': |
+ return 'bool' |
+ if idl_type == 'DOMString' or is_enum_type(idl_type): |
+ if used_to_assign_js_value: |
+ # FIXME: This implements [TreatNullAs=NullString] and [TreatUndefinedAs=NullString], |
+ # but the Web IDL spec requires [TreatNullAs=EmptyString] and [TreatUndefinedAs=EmptyString]. |
+ mode = '' |
+ if extended_attributes.get('TreatNullAs') == 'NullString' and extended_attributes.get('TreatUndefinedAs') == 'NullString': |
+ mode = 'WithUndefinedOrNullCheck' |
+ elif extended_attributes.get('TreatNullAs') == 'NullString' or 'Reflect' in extended_attributes: |
+ mode = 'WithNullCheck' |
+ # FIXME: Add the case for 'elsif ($attributeOrParameter->extendedAttributes->{'TreatUndefinedAs'} and $attributeOrParameter->extendedAttributes->{'TreatUndefinedAs'} eq 'NullString'))'. |
+ return 'V8StringResource<%s>' % mode |
+ if called_by_webcore: |
+ return 'const String&' |
+ return 'String' |
+ |
+ # FIXME: remove this!!! :( |
+ adhoc_rules = { |
+ 'CompareHow': 'Range::CompareHow', |
+ 'DOMTimeStamp': 'DOMTimeStamp', |
+ 'Date': 'double', |
+ 'Dictionary': 'Dictionary', |
+ 'DOMStringList': 'RefPtr<DOMStringList>', |
+ 'MediaQueryListListener': 'RefPtr<MediaQueryListListener>', |
+ 'NodeFilter': 'RefPtr<NodeFilter>', |
+ 'SerializedScriptValue': 'RefPtr<SerializedScriptValue>', |
+ 'XPathNSResolver': 'RefPtr<XPathNSResolver>', |
+ } |
+ if idl_type in adhoc_rules: |
+ if used_as_parameter: |
+ return adhoc_rules[idl_type].replace('RefPtr', 'PassRefPtr') |
+ return adhoc_rules[idl_type] |
+ if idl_type == 'any' or is_callback_function_type(idl_type): |
+ return 'ScriptValue' |
+ |
+ if is_union_type(idl_type): |
+ raise Exception('UnionType is not supported') |
+ |
+ if idl_type == 'ArrayBuffer': |
+ if used_as_parameter: |
+ return 'ArrayBuffer*' |
+ else: |
+ return 'RefPtr<ArrayBuffer>' |
+ |
+ # We need to check [ImplementedAs] extended attribute for wrapper types. |
+ if is_wrapper_type(idl_type): |
+ # print '[] parse_interface', idl_type |
+ idl_type = implemented_as_cpp_name_from_idl_type(idl_type) |
+ |
+ array_or_sequence_type = get_array_or_sequence_type(idl_type) |
+ if array_or_sequence_type: |
+ idl_type = get_native_type(array_or_sequence_type) |
+ idl_type = idl_type.replace('>', '> ') |
+ return 'Vector<%s>' % idl_type |
+ |
+ if called_by_webcore: |
+ return idl_type + '*' |
+ elif used_to_assign_js_value: |
+ return idl_type + '*' |
+ elif used_as_parameter: |
+ if idl_type.endswith('>'): |
+ idl_type += ' ' |
+ return 'PassRefPtr<%s>' % idl_type |
+ else: |
+ return 'RefPtr<%s>' % idl_type |
+ |
+ |
+def get_is_null_expression(data_type, variable_name): |
+ if is_union_type(data_type): |
+ expression = [] |
+ for i, union_member_type in enumerate(data_type.union_member_types): |
+ union_member_variable = '%s%d' % (variable_name, i) |
+ is_null_expression = get_is_null_expression(union_member_type, union_member_variable) |
+ expression.append(is_null_expression) |
+ return ' && '.join(expression) |
+ if is_ref_ptr_type(data_type): |
+ return '!' + variable_name |
+ elif data_type == 'DOMString': |
+ return variable_name + '.isNull()' |
+ return '' |
+ |
+ |
+def get_is_standard_function(interface, function): |
+ return not( |
+ any([key in function.extended_attributes for key in ['Unforgeable', 'EnabledAtRuntime', 'EnabledPerContext', 'DoNotCheckSignature', 'NotEnumerable', 'ReadOnly']]) or |
+ function.is_static or |
+ get_requires_custom_signature(function) or |
+ ('DoNotCheckSecurity' in function.extended_attributes and 'CheckSecurity' in interface.extended_attributes or interface.name == 'Window')) |
+ |
+ |
+def get_requires_custom_signature(operation): |
+ return (not( |
+ # No signature needed for Custom function |
+ has_custom_implementation(operation) or |
+ # No signature needed for overloaded function |
+ len(operation.overloads) > 1 or |
+ operation.is_static or |
+ operation.extended_attributes.get('StrictTypeChecking') or |
+ any([parameter.is_optional and not parameter.extended_attributes.get('Default') or is_callback_interface_etc(parameter.data_type) for parameter in operation.arguments])) and |
+ any([is_wrapper_type(parameter.data_type) for parameter in operation.arguments])) |