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

Unified Diff: Source/bindings/scripts/v8_attributes.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/idl_compiler.py ('k') | Source/bindings/scripts/v8_constructors.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
« no previous file with comments | « Source/bindings/scripts/idl_compiler.py ('k') | Source/bindings/scripts/v8_constructors.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698