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