| 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]))
|
|
|