| Index: Source/bindings/scripts/v8_attributes.py
|
| diff --git a/Source/bindings/scripts/v8_attributes.py b/Source/bindings/scripts/v8_attributes.py
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..eaf9ff36300820da4fe007cfaa62cc15af2cc363
|
| --- /dev/null
|
| +++ b/Source/bindings/scripts/v8_attributes.py
|
| @@ -0,0 +1,618 @@
|
| +# 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.
|
| +
|
| +"""Generate template values for attributes.
|
| +
|
| +FIXME: rename "parameter/parameters":
|
| +"template parameters" is easily confused with "function parameters"
|
| +Also, "parameter*s*", not "parameter".
|
| +"""
|
| +
|
| +import v8_types
|
| +from v8_types import cpp_type, v8_type
|
| +from v8_utilities import generate_conditional_string, implemented_as_cpp_name, uncapitalize
|
| +import v8_values
|
| +
|
| +# WIP
|
| +import re
|
| +
|
| +from code_generator_idl_reader import inherits_interface, implemented_as_from_implemented_by
|
| +from v8_includes import *
|
| +from v8_types import *
|
| +from v8_utilities import capitalize, runtime_enable_function_name, strip_suffix
|
| +from v8_utilities import ACTIVITY_LOGGING_INCLUDES, get_call_with_parameter, get_custom_element_invocation_scope_parameter, get_feature_observation_parameter, get_deprecation_notification_parameter, has_activity_logging
|
| +from v8_values import get_js_value_to_native_statement, get_native_to_js_value_statement, get_pass_owner_expression
|
| +
|
| +
|
| +def generate_attributes(interface):
|
| + def generate_attribute(attribute):
|
| + attribute_contents, attribute_includes = generate_attribute_and_includes(interface, attribute)
|
| + includes.update(attribute_includes)
|
| + return attribute_contents
|
| +
|
| + includes = set()
|
| + contents = generate_attributes_common(interface)
|
| + contents['attributes'] = [generate_attribute(attribute) for attribute in interface.attributes]
|
| + return contents, includes
|
| +
|
| +
|
| +def generate_attributes_common(interface):
|
| + attributes = interface.attributes
|
| + v8_class_name = v8_types.get_v8_class_name(interface)
|
| + return {
|
| + # Size 0 constant array is not allowed in VC++
|
| + # FIXME: rename Attrs to Attributes
|
| + 'number_of_attributes': 'WTF_ARRAY_LENGTH(%sAttrs)' % v8_class_name if attributes else '0',
|
| + 'attribute_templates': v8_class_name + 'Attrs' if attributes else '0',
|
| + }
|
| +
|
| +
|
| +def generate_attribute_and_includes(interface, attribute):
|
| + data_type = attribute.data_type
|
| + # FIXME: need to check should_keep_attribute_alive, but for now sufficient
|
| + # to check if primitive.
|
| + should_keep_attribute_alive = not v8_types.primitive_type(data_type)
|
| + # FIXME: eliminate should_keep_attribute_alive
|
| + if should_keep_attribute_alive:
|
| + return_js_value_statement = None # unused
|
| + includes = includes_for_type(data_type)
|
| + includes.add('bindings/v8/V8HiddenPropertyName.h')
|
| + else:
|
| + cpp_value = getter_expression(interface, attribute)
|
| + return_js_value_statement = v8_values.cpp_value_to_js_value_return(data_type, cpp_value, callback_info='info')
|
| + includes = []
|
| + contents = {
|
| + 'name': attribute.name,
|
| + 'conditional_string': generate_conditional_string(attribute),
|
| + 'cpp_method_name': implemented_as_cpp_name(attribute),
|
| + 'cpp_type': cpp_type(data_type, pointer_type='RefPtr'),
|
| + 'should_keep_attribute_alive': should_keep_attribute_alive,
|
| + 'return_js_value_statement': return_js_value_statement,
|
| + 'v8_type': v8_type(data_type),
|
| + }
|
| + return contents, includes
|
| +
|
| +
|
| +def getter_expression(interface, attribute):
|
| + # FIXME: very incomplete
|
| + return 'imp->%s()' % uncapitalize(attribute.name)
|
| +
|
| +
|
| +################################################################################
|
| +# WIP
|
| +################################################################################
|
| +
|
| +
|
| +def generate_attributes_wip(interface):
|
| + def generate_attribute(attribute):
|
| + attribute_contents, attribute_includes = generate_attribute_and_includes_wip(interface, attribute)
|
| + includes.extend(attribute_includes)
|
| + return attribute_contents
|
| +
|
| + includes = []
|
| + contents = [generate_attribute(attribute) for attribute in interface.attributes]
|
| + return contents, includes
|
| +
|
| +
|
| +def generate_attribute_and_includes_wip(interface, attribute):
|
| + cpp_class_name = implemented_as_cpp_name(interface)
|
| + per_world_bindings = 'PerWorldBindings' in attribute.extended_attributes
|
| + for_main_world_suffixes = ['']
|
| + if per_world_bindings:
|
| + for_main_world_suffixes.append('ForMainWorld')
|
| +
|
| + includes = []
|
| + # print
|
| + # print '#'*30
|
| + # print '[get_attribute_parameter] ', attribute.data_type, attribute.name
|
| +
|
| + check_security_for_node = 'CheckSecurityForNode' in attribute.extended_attributes
|
| + if check_security_for_node:
|
| + includes.append('bindings/v8/BindingSecurity.h')
|
| + if attribute.data_type == 'SerializedScriptValue':
|
| + includes.append('bindings/v8/SerializedScriptValue.h')
|
| +
|
| + getter_activity_logging = set()
|
| + for for_main_world_suffix in for_main_world_suffixes:
|
| + if has_activity_logging(for_main_world_suffix, attribute.extended_attributes, 'Getter'):
|
| + getter_activity_logging.add(for_main_world_suffix)
|
| + includes += ACTIVITY_LOGGING_INCLUDES
|
| +
|
| + custom_element_invocation_scope_parameter, custom_element_invocation_scope_includes = get_custom_element_invocation_scope_parameter(attribute)
|
| + includes += custom_element_invocation_scope_includes
|
| +# print '[[]]', custom_element_invocation_scope_parameter
|
| +
|
| + enable_function = runtime_enable_function_name(attribute)
|
| +
|
| + replaceable = 'Replaceable' in attribute.extended_attributes
|
| + custom_getter = has_custom_getter(attribute)
|
| + custom_setter = has_custom_setter(attribute)
|
| + has_replaceable = not custom_setter and replaceable
|
| + has_normal_setter = (custom_setter or not has_replaceable) and not is_read_only(attribute)
|
| +
|
| + should_keep_attribute_alive = get_should_keep_attribute_alive(interface, attribute)
|
| +# print '[] should_keep_attribute_alive', should_keep_attribute_alive
|
| +
|
| + native_type = ''
|
| + array_type = ''
|
| + if not custom_getter:
|
| + native_type = get_native_type(attribute.data_type, extended_attributes=attribute.extended_attributes)
|
| + # currently array_type is always False
|
| + array_type = get_array_type(native_type)
|
| + if should_keep_attribute_alive:
|
| + if array_type:
|
| + includes.append('V8%s.h' % array_type)
|
| + else:
|
| + includes += get_includes_for_type(attribute.data_type)
|
| + includes.append('bindings/v8/V8HiddenPropertyName.h')
|
| + if (setter_use_exception(attribute) and not custom_setter) or getter_use_exception(attribute):
|
| + includes.append('bindings/v8/ExceptionState.h')
|
| +
|
| + batched_attribute, batched_attribute_includes = generate_batched_attribute(interface, attribute, ',')
|
| + includes += batched_attribute_includes
|
| +
|
| + enabled_at_runtime = False
|
| + enabled_per_context = False
|
| + if interface.name == 'Window' and 'Unforgeable' in attribute.extended_attributes:
|
| + pass
|
| + elif 'EnabledPerContext' in attribute.extended_attributes:
|
| + enabled_per_context = True
|
| + elif 'EnabledAtRuntime' in attribute.extended_attributes:
|
| + enabled_at_runtime = True
|
| + else:
|
| + pass
|
| +
|
| + if enabled_at_runtime:
|
| + batched_attribute, batched_attribute_includes = generate_batched_attribute(interface, attribute, ';')
|
| + includes += batched_attribute_includes
|
| +
|
| + compact_getter = 'Reflect' in attribute.extended_attributes and 'URL' not in attribute.extended_attributes and inherits_interface(interface, 'Node') and attribute.data_type == 'DOMString'
|
| + compact_setter = 'Reflect' in attribute.extended_attributes and inherits_interface(interface, 'Node') and attribute.data_type == 'DOMString'
|
| + compact_setter_namespace = ''
|
| + compact_setter_content_attribute_name = ''
|
| + if compact_setter:
|
| + compact_setter_content_attribute_name = attribute.name.lower()
|
| + if attribute.extended_attributes.get('Reflect'):
|
| + compact_setter_content_attribute_name = attribute.extended_attributes.get('Reflect')
|
| + compact_setter_namespace = namespace_for_attribute_name(interface.name, compact_setter_content_attribute_name)
|
| + includes.append('%s.h' % compact_setter_namespace)
|
| +
|
| + feature_observation_parameter, feature_observation_includes = get_feature_observation_parameter(interface)
|
| + includes += feature_observation_includes
|
| + deprecation_notification_parameter, deprecation_notification_includes = get_deprecation_notification_parameter(attribute)
|
| + includes += deprecation_notification_includes
|
| +
|
| + getter_function = ''
|
| + event_listener_setter_function_name = ''
|
| + event_listener_setter_function_name_not_inherits_node = ''
|
| + not_inherits_node = False
|
| + if attribute.data_type == 'EventListener':
|
| + # FIXME: Pass the main world ID for main-world-only getters.
|
| + includes.append('bindings/v8/V8AbstractEventListener.h')
|
| + includes.append('bindings/v8/V8EventListenerList.h')
|
| + getter_function = uncapitalize(attribute.name)
|
| + event_listener_setter_function_name = capitalize(attribute.name)
|
| + not_inherits_node = not inherits_interface(interface, 'Node')
|
| + if not_inherits_node:
|
| + event_listener_setter_function_name_not_inherits_node = implemented_as_cpp_name(attribute)
|
| + event_listener_on_error = (interface.name == 'Window' or interface.name == 'WorkerGlobalScope') and attribute.name == 'onerror'
|
| + if event_listener_on_error:
|
| + includes.append('bindings/v8/V8ErrorHandler.h')
|
| +
|
| + svg_animated_type = is_svg_animated_type(interface.name)
|
| + svg_type_needing_tear_off = get_svg_type_needing_tear_off(attribute.data_type)
|
| +
|
| + ##################### Getter
|
| + getter_native_value_expression, getter_function_call_parameter, getter_includes = get_attribute_function_call_expression(interface, attribute)
|
| + includes += getter_includes
|
| +# print '[]', getter_native_value_expression
|
| +
|
| + tear_off_and_not_list = svg_type_needing_tear_off and not interface.name.endswith('List')
|
| +
|
| + wrapped_value = ''
|
| + return_js_value_statements = {}
|
| + assign_native_value_to_local_variable_statement = ''
|
| + if not custom_getter:
|
| + if (svg_animated_type or interface.name == 'SVGViewSpec') and svg_type_needing_tear_off:
|
| + includes.append('V8%s.h' % attribute.data_type)
|
| + elif tear_off_and_not_list:
|
| + includes.append('V8%s.h' % attribute.data_type)
|
| + includes.append('core/svg/properties/SVGPropertyTearOff.h')
|
| + if svg_type_with_writable_properties_needing_tear_off(attribute.data_type) and 'Immutable' not in attribute.extended_attributes:
|
| + getter = getter_native_value_expression
|
| + getter = getter.replace('imp->', '')
|
| + getter = getter.replace('\(\)', '')
|
| +
|
| + update_method = '&%s::update%s' % (cpp_class_name, capitalize(getter))
|
| +
|
| + self_is_tear_off_type = get_svg_type_needing_tear_off(interface.name)
|
| + if self_is_tear_off_type:
|
| + includes.append('core/svg/properties/SVGStaticPropertyWithParentTearOff.h')
|
| + svg_type_needing_tear_off = svg_type_needing_tear_off.replace('SVGPropertyTearOff<', 'SVGStaticPropertyWithParentTearOff<%s, ' % cpp_class_name)
|
| + wrapped_value = 'WTF::getPtr(%s::create(wrapper, %s, %s))' % (svg_type_needing_tear_off, getter_native_value_expression, update_method)
|
| + else:
|
| + includes.append('core/svg/properties/SVGStaticPropertyTearOff.h')
|
| + svg_type_needing_tear_off = svg_type_needing_tear_off.replace('SVGPropertyTearOff<', 'SVGStaticPropertyTearOff<%s, ' % cpp_class_name)
|
| + wrapped_value = 'WTF::getPtr(%s::create(imp, %s, %s))' % (svg_type_needing_tear_off, getter_native_value_expression, update_method)
|
| + elif 'SVGStaticListPropertyTearOff' in svg_type_needing_tear_off:
|
| + wrapped_value = 'WTF::getPtr(%s::create(imp, %s))' % (svg_type_needing_tear_off, getter_native_value_expression)
|
| + elif re.search('SVG(Point|PathSeg)List', svg_type_needing_tear_off):
|
| + wrapped_value = 'WTF::getPtr(%s)' % getter_native_value_expression
|
| + else:
|
| + wrapped_value = 'WTF::getPtr(%s::create(%s))' % (svg_type_needing_tear_off, getter_native_value_expression)
|
| + elif attribute.data_type == 'SerializedScriptValue' and 'CachedAttribute' in attribute.extended_attributes:
|
| + pass
|
| + elif attribute.data_type == 'EventListener':
|
| + pass
|
| + else:
|
| + original_getter_native_value_expression = getter_native_value_expression
|
| + # Fix amigious conversion problem, by casting to the base type first ($getterString returns a type that inherits from SVGAnimatedEnumeration, not the base class directly).
|
| + if attribute.data_type == 'SVGAnimatedEnumeration':
|
| + getter_native_value_expression = 'static_pointer_cast<SVGAnimatedEnumeration>(%s)' % getter_native_value_expression
|
| +
|
| + # print '[get_attribute_parameter] native_type', native_type
|
| + if attribute.is_nullable or getter_use_exception(attribute):
|
| + # used in local variable type
|
| + assign_native_value_to_local_variable_statement = '%s v = %s;' % (native_type, getter_native_value_expression)
|
| + getter_native_value_expression = get_pass_owner_expression(attribute.data_type, 'v')
|
| +
|
| + for for_main_world_suffix in for_main_world_suffixes:
|
| + if attribute.data_type != 'EventListener':
|
| + return_js_value_statement, native_to_js_value_includes = get_native_to_js_value_statement(attribute.data_type, attribute.extended_attributes, getter_native_value_expression, creation_context='info.Holder()', isolate='info.GetIsolate()', callback_info='info', script_wrappable='imp', for_main_world_suffix=for_main_world_suffix, used_as_return_value=True)
|
| + return_js_value_statements[for_main_world_suffix] = return_js_value_statement
|
| + if should_keep_attribute_alive:
|
| + assign_native_value_to_local_variable_statement = '%s v = %s;' % (native_type, original_getter_native_value_expression)
|
| + getter_native_value_expression = original_getter_native_value_expression
|
| + else:
|
| + includes += native_to_js_value_includes
|
| +
|
| + ##################### Setter
|
| + # native to JS (getter)
|
| + assign_js_value_to_local_variable_statement = ''
|
| + setter_native_value_expression = ''
|
| + set_value_statement = ''
|
| + setter_activity_logging = set()
|
| + setter_function_call_parameter = {}
|
| + if has_normal_setter:
|
| + for for_main_world_suffix in for_main_world_suffixes:
|
| + if has_activity_logging(for_main_world_suffix, attribute.extended_attributes, 'Setter'):
|
| + setter_activity_logging.add(for_main_world_suffix)
|
| + includes += ACTIVITY_LOGGING_INCLUDES
|
| +
|
| + # JS to native (setter)
|
| + if attribute.data_type != 'EventListener':
|
| + assign_js_value_to_local_variable_statement, js_value_to_native_includes = get_js_value_to_native_statement(attribute.data_type, attribute.extended_attributes, 'value', 'v', 'info.GetIsolate()')
|
| + includes += js_value_to_native_includes
|
| +
|
| + setter_native_value_expression = 'v'
|
| + if is_ref_ptr_type(attribute.data_type) and not get_array_type(attribute.data_type):
|
| + setter_native_value_expression = 'WTF::getPtr(%s)' % setter_native_value_expression
|
| +
|
| + # set native value statement
|
| + setter_native_value_expression, setter_function_call_parameter, setter_includes = get_attribute_function_call_expression(interface, attribute, is_setter=True, setter_native_value_expression=setter_native_value_expression)
|
| + includes += setter_includes
|
| +
|
| + set_value_statement = '%s;' % setter_native_value_expression
|
| +# print '[attribute] set_value_statement', set_value_statement
|
| +
|
| + is_normal = False
|
| + if interface.name == 'Window' and 'Unforgeable' in attribute.extended_attributes:
|
| + pass
|
| + elif 'EnabledAtRuntime' in attribute.extended_attributes or 'EnabledPerContext' in attribute.extended_attributes:
|
| + pass
|
| + else:
|
| + is_normal = True
|
| +
|
| + parameter = {
|
| + 'name': attribute.name,
|
| + 'type': attribute.data_type,
|
| + 'is_static': attribute.is_static,
|
| + 'is_normal': is_normal,
|
| + 'native_type': native_type,
|
| + 'svg_animated_type': svg_animated_type,
|
| + 'svg_type_needing_tear_off': svg_type_needing_tear_off,
|
| + 'tear_off_and_not_list': tear_off_and_not_list,
|
| + 'check_security_for_node': check_security_for_node,
|
| + 'enable_function': enable_function,
|
| +
|
| + # EventListner hack
|
| + 'getter_function': getter_function,
|
| + 'event_listener_setter_function_name': event_listener_setter_function_name,
|
| + 'event_listener_setter_function_name_not_inherits_node': event_listener_setter_function_name_not_inherits_node,
|
| + 'not_inherits_node': not_inherits_node,
|
| +
|
| + 'getter_native_value_expression': getter_native_value_expression,
|
| + 'setter_native_value_expression': setter_native_value_expression,
|
| + 'return_js_value_statements': return_js_value_statements,
|
| + 'set_value_statement': set_value_statement,
|
| + 'conditional_string': generate_conditional_string(attribute),
|
| + 'batched_attribute': batched_attribute,
|
| + 'getter_use_exceptions': getter_use_exception(attribute),
|
| + 'setter_use_exceptions': setter_use_exception(attribute),
|
| + 'is_nullable': attribute.is_nullable,
|
| + 'assign_native_value_to_local_variable_statement': assign_native_value_to_local_variable_statement,
|
| + 'assign_js_value_to_local_variable_statement': assign_js_value_to_local_variable_statement,
|
| + 'has_replaceable': has_replaceable,
|
| + 'has_normal_setter': has_normal_setter,
|
| + 'has_custom_getter': custom_getter,
|
| + 'has_custom_setter': custom_setter,
|
| + 'per_world_bindings': per_world_bindings,
|
| + 'for_main_world_suffixes': for_main_world_suffixes,
|
| + 'should_keep_attribute_alive': should_keep_attribute_alive,
|
| + 'array_type': array_type,
|
| + 'getter_activity_logging': getter_activity_logging,
|
| + 'setter_activity_logging': setter_activity_logging,
|
| + 'enabled_at_runtime': enabled_at_runtime,
|
| + 'enabled_per_context': enabled_per_context,
|
| + 'compact_getter': compact_getter,
|
| + 'compact_setter': compact_setter,
|
| + 'compact_setter_namespace': compact_setter_namespace,
|
| + 'compact_setter_content_attribute_name': compact_setter_content_attribute_name,
|
| + 'cached_attribute': 'CachedAttribute' in attribute.extended_attributes,
|
| + 'wrapped_value': wrapped_value,
|
| + 'cpp_name': implemented_as_cpp_name(attribute),
|
| + 'initialized_by_event_constructor': 'InitializedByEventConstructor' in attribute.extended_attributes,
|
| + 'setter': 'setSerialized' + capitalize(attribute.name),
|
| + }
|
| + parameter.update(feature_observation_parameter)
|
| + parameter.update(deprecation_notification_parameter)
|
| + parameter.update(custom_element_invocation_scope_parameter)
|
| + parameter.update(getter_function_call_parameter)
|
| + parameter.update(setter_function_call_parameter)
|
| + return parameter, includes
|
| +
|
| +
|
| +def generate_batched_attribute(interface, attribute, delimiter, indent=''):
|
| + # GenerateSingleBatchedAttribute in perl
|
| + cpp_class_name = implemented_as_cpp_name(interface)
|
| + v8_class_name = get_v8_class_name(interface)
|
| + is_constructor = attribute.data_type.endswith('Constructor')
|
| +# print '[--]', attribute.name, attribute.data_type, is_constructor
|
| + includes = []
|
| +
|
| + access_control = 'v8::DEFAULT'
|
| + if attribute.extended_attributes.get('DoNotCheckSecurityOnGetter'):
|
| + access_control = 'v8::ALL_CAN_READ'
|
| + elif attribute.extended_attributes.get('DoNotCheckSecurityOnSetter'):
|
| + access_control = 'v8::ALL_CAN_WRITE'
|
| + elif attribute.extended_attributes.get('DoNotCheckSecurity'):
|
| + access_control = 'v8::ALL_CAN_READ'
|
| + if not is_read_only(attribute):
|
| + access_control += ' | v8::ALL_CAN_WRITE'
|
| + if attribute.extended_attributes.get('Unforgeable'):
|
| + access_control += ' | v8::PROHIBITS_OVERWRITING'
|
| + access_control = 'static_cast<v8::AccessControl>(%s)' % access_control
|
| +
|
| + prop_attr = 'v8::None'
|
| + # Check attributes.
|
| + # As per Web IDL specification, constructor properties on the ECMAScript global object should be
|
| + # configurable and should not be enumerable.
|
| + if 'NotEnumerable' in attribute.extended_attributes or is_constructor:
|
| + prop_attr += ' | v8::DontEnum'
|
| + if 'Unforgeable' in attribute.extended_attributes and not is_constructor:
|
| + prop_attr += ' | v8::DontDelete'
|
| +
|
| + on_proto = '0 /* on instance */'
|
| + if is_constructor:
|
| + constructor_type = strip_suffix(attribute.data_type, 'Constructor')
|
| + # $constructorType ~= /Constructor$/ indicates that it is NamedConstructor.
|
| + # We do not generate the header file for NamedConstructor of class XXXX,
|
| + # since we generate the NamedConstructor declaration into the header file of class XXXX.
|
| + # FIXME: We just stripped the 'Constructor' suffix!
|
| + if not constructor_type.endswith('Constructor') or attribute.extended_attributes.get('CustomConstructor'):
|
| + includes.append('V8%s.h' % constructor_type)
|
| + getter = '%sV8Internal::%sConstructorGetter' % (cpp_class_name, cpp_class_name)
|
| + setter = '%sV8Internal::%sReplaceableAttrSetterCallback' % (cpp_class_name, cpp_class_name)
|
| + getter_for_main_world = '0'
|
| + setter_for_main_world = '0'
|
| + data = '&V8${constructorType}::info'
|
| + else:
|
| + # Default Getter and Setter
|
| + getter = '%sV8Internal::%sAttrGetterCallback' % (cpp_class_name, attribute.name)
|
| + setter = '%sV8Internal::%sAttrSetterCallback' % (cpp_class_name, attribute.name)
|
| + getter_for_main_world = getter + 'ForMainWorld'
|
| + setter_for_main_world = setter + 'ForMainWorld'
|
| + data = '0 /* no data */'
|
| + if not has_custom_setter(attribute) and attribute.extended_attributes.get('Replaceable'):
|
| + setter = '%sV8Internal::%sReplaceableAttrSetterCallback' % (cpp_class_name, cpp_class_name)
|
| + setter_for_main_world = '0'
|
| + # Read only attributes
|
| + if is_read_only(attribute):
|
| + setter = '0'
|
| + setter_for_main_world = '0'
|
| + if 'PerWorldBindings' not in attribute.extended_attributes:
|
| + getter_for_main_world = '0'
|
| + setter_for_main_world = '0'
|
| +
|
| + # An accessor can be installed on the proto
|
| + if attribute.extended_attributes.get('OnProto'):
|
| + on_proto = '1 /* on proto */'
|
| +
|
| + code = (
|
| + '{"%s", %s, %s, %s, %s, %s, %s, static_cast<v8::PropertyAttribute>(%s), %s}%s' %
|
| + (attribute.name, getter, setter, getter_for_main_world, setter_for_main_world, data, access_control, prop_attr, on_proto, delimiter))
|
| + return code, includes
|
| +
|
| +
|
| +# Auxiliary functions
|
| +
|
| +
|
| +def get_should_keep_attribute_alive(interface, attribute):
|
| + return (
|
| + 'KeepAttributeAliveForGC' in attribute.extended_attributes or
|
| + # Basically, for readonly or replaceable attributes, we have to
|
| + # guarantee that JS wrappers don't get garbage-collected prematually
|
| + # when their lifetime is strongly tied to their owner.
|
| + ((is_wrapper_type(attribute.data_type) and
|
| + (is_read_only(attribute) or
|
| + 'Replaceable' in attribute.extended_attributes)) and
|
| + # However, there are a couple of exceptions.
|
| + not(
|
| + # Node lifetime is managed by object grouping.
|
| + inherits_interface(interface, 'Node') or
|
| + is_dom_node_type(attribute.data_type) or
|
| + # To avoid adding a reference to itself.
|
| + # FIXME: Introduce [DoNotKeepAttributeAliveForGC] and remove
|
| + # this hack of depending on the attribute name.
|
| + attribute.name == 'self' or
|
| + # FIXME: Remove these hard-coded hacks.
|
| + attribute.data_type in ['EventTarget', 'SerializedScriptValue', 'Window'] or
|
| + 'SVG' in attribute.data_type or
|
| + 'HTML' in attribute.data_type)))
|
| +
|
| +
|
| +def get_attribute_function_call_expression(interface, attribute, is_setter=False, setter_native_value_expression=None):
|
| + """
|
| + @return function_call_expression, includes
|
| + """
|
| + # GetterExpression / SetterExpression in perl
|
| + includes = []
|
| + arguments = []
|
| + interface_name = interface.name
|
| + cpp_class_name = implemented_as_cpp_name(interface)
|
| + content_attribute_name, additional_includes = get_content_attribute_name(interface_name, attribute)
|
| + includes += additional_includes
|
| +
|
| + function_name = ''
|
| + if is_setter:
|
| + if content_attribute_name:
|
| + if attribute.data_type == 'boolean':
|
| + function_name = 'setBooleanAttribute'
|
| + elif attribute.data_type == 'long':
|
| + function_name = 'setIntegralAttribute'
|
| + elif attribute.data_type == 'unsigned long':
|
| + function_name = 'setUnsignedIntegralAttribute'
|
| + else:
|
| + function_name = 'setAttribute'
|
| + else:
|
| + function_name = 'set' + capitalize(implemented_as_cpp_name(attribute))
|
| + else:
|
| + if content_attribute_name:
|
| + if 'URL' in attribute.extended_attributes:
|
| + function_name = 'getURLAttribute'
|
| + elif attribute.data_type == 'boolean':
|
| + function_name = 'fastHasAttribute'
|
| + elif attribute.data_type == 'long':
|
| + function_name = 'getIntegralAttribute'
|
| + elif attribute.data_type == 'unsigned long':
|
| + function_name = 'getUnsignedIntegralAttribute'
|
| + elif content_attribute_name == 'WebCore::HTMLNames::idAttr':
|
| + function_name = 'getIdAttribute'
|
| + content_attribute_name = ''
|
| + elif content_attribute_name == 'WebCore::HTMLNames::nameAttr':
|
| + function_name = 'getNameAttribute'
|
| + content_attribute_name = ''
|
| + elif content_attribute_name == 'WebCore::HTMLNames::classAttr':
|
| + function_name = 'getClassAttribute'
|
| + content_attribute_name = ''
|
| + elif is_svg_animated_type(attribute.data_type):
|
| + # We cannot use fast attributes for animated SVG types.
|
| + function_name = 'getAttribute'
|
| + else:
|
| + function_name = 'fastGetAttribute'
|
| + else:
|
| + function_name = uncapitalize(implemented_as_cpp_name(attribute))
|
| +# print '[[]]', function_name
|
| + if content_attribute_name:
|
| + arguments.append(content_attribute_name)
|
| +
|
| + implemented_by = attribute.extended_attributes.get('ImplementedBy')
|
| + if implemented_by:
|
| + implemented_by_cpp_name = implemented_as_from_implemented_by(implemented_by)
|
| + includes += header_files_for_interface(implemented_by, implemented_by_cpp_name)
|
| + if not attribute.is_static:
|
| + arguments = ['imp'] + arguments
|
| + function_name = '%s::%s' % (implemented_by_cpp_name, function_name)
|
| + elif attribute.is_static:
|
| + function_name = '%s::%s' % (cpp_class_name, function_name)
|
| + else:
|
| + function_name = 'imp->%s' % function_name
|
| +
|
| + if is_setter:
|
| + arguments.append(setter_native_value_expression)
|
| + if setter_use_exception(attribute):
|
| + arguments.append('es')
|
| + call_with = attribute.extended_attributes.get('SetterCallWith') or attribute.extended_attributes.get('CallWith')
|
| + else:
|
| + if attribute.is_nullable:
|
| + arguments.append('isNull')
|
| + if getter_use_exception(attribute):
|
| + arguments.append('es')
|
| + call_with = attribute.extended_attributes.get('CallWith')
|
| +
|
| + call_with_arguments, call_with_parameter, call_with_includes = get_call_with_parameter(call_with)
|
| + includes += call_with_includes
|
| + arguments = call_with_arguments + arguments
|
| +
|
| + function_call_expression = '%s(%s)' % (function_name, ', '.join(arguments))
|
| + return function_call_expression, call_with_parameter, includes
|
| +
|
| +
|
| +def get_custom_element_invocation_scope_parameter(interface_or_attribute_or_function):
|
| +# print '[[]]', interface_or_attribute_or_function.extended_attributes
|
| + custom_element_invocation_scope = has_extended_attribute(interface_or_attribute_or_function, ['DeliverCustomElementCallbacks', 'Reflect'])
|
| + parameter = {
|
| + 'custom_element_invocation_scope': custom_element_invocation_scope,
|
| + }
|
| + if custom_element_invocation_scope:
|
| + includes = ['core/dom/CustomElementCallbackDispatcher.h']
|
| + else:
|
| + includes = []
|
| + return parameter, includes
|
| +
|
| +
|
| +def has_extended_attribute(item, extended_attribute_list):
|
| + # FIXME: useful function, use widely
|
| + return any([extended_attribute in item.extended_attributes
|
| + for extended_attribute in extended_attribute_list])
|
| +
|
| +
|
| +def getter_use_exception(attribute):
|
| + return has_extended_attribute(attribute, ['GetterRaisesException', 'RaisesException'])
|
| +
|
| +
|
| +def setter_use_exception(attribute):
|
| + return has_extended_attribute(attribute, ['SetterRaisesException', 'RaisesException'])
|
| +
|
| +
|
| +def namespace_for_attribute_name(interface_name, attribute_name):
|
| + if (interface_name.startswith('SVG') and
|
| + attribute_name not in SVG_ATTRIBUTES_IN_HTML):
|
| + return 'SVGNames'
|
| + return 'HTMLNames'
|
| +
|
| +
|
| +def get_content_attribute_name(interface_name, attribute):
|
| + if 'Reflect' not in attribute.extended_attributes:
|
| + return None, []
|
| + default_content_attribute_name = implemented_as_cpp_name(attribute).lower()
|
| + content_attribute_name = attribute.extended_attributes['Reflect'] or default_content_attribute_name
|
| + namespace = namespace_for_attribute_name(interface_name, content_attribute_name)
|
| + scoped_name = 'WebCore::%s::%sAttr' % (namespace, content_attribute_name)
|
| + includes = [namespace + '.h']
|
| + return scoped_name, includes
|
|
|