Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(174)

Unified Diff: Source/bindings/scripts/v8_types.py

Issue 17572008: WIP IDL compiler rewrite (Closed) Base URL: https://chromium.googlesource.com/chromium/blink@master
Patch Set: Branch: const + primitive type readonly attributes Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/bindings/scripts/v8_special_accessors.py ('k') | Source/bindings/scripts/v8_utilities.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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]))
« no previous file with comments | « Source/bindings/scripts/v8_special_accessors.py ('k') | Source/bindings/scripts/v8_utilities.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698