| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 # Copyright (C) 2013 Google Inc. All rights reserved. | 
|  | 2 # | 
|  | 3 # Redistribution and use in source and binary forms, with or without | 
|  | 4 # modification, are permitted provided that the following conditions are | 
|  | 5 # met: | 
|  | 6 # | 
|  | 7 #     * Redistributions of source code must retain the above copyright | 
|  | 8 # notice, this list of conditions and the following disclaimer. | 
|  | 9 #     * Redistributions in binary form must reproduce the above | 
|  | 10 # copyright notice, this list of conditions and the following disclaimer | 
|  | 11 # in the documentation and/or other materials provided with the | 
|  | 12 # distribution. | 
|  | 13 #     * Neither the name of Google Inc. nor the names of its | 
|  | 14 # contributors may be used to endorse or promote products derived from | 
|  | 15 # this software without specific prior written permission. | 
|  | 16 # | 
|  | 17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 
|  | 18 # 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 
|  | 19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 
|  | 20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 
|  | 21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 
|  | 22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 
|  | 23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 
|  | 24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 
|  | 25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 
|  | 26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 
|  | 27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
|  | 28 | 
|  | 29 """Generate template values for attributes. | 
|  | 30 | 
|  | 31 FIXME: rename "parameter/parameters": | 
|  | 32 "template parameters" is easily confused with "function parameters" | 
|  | 33 Also, "parameter*s*", not "parameter". | 
|  | 34 """ | 
|  | 35 | 
|  | 36 import v8_types | 
|  | 37 from v8_types import cpp_type, v8_type | 
|  | 38 from v8_utilities import generate_conditional_string, implemented_as_cpp_name, u
     ncapitalize | 
|  | 39 import v8_values | 
|  | 40 | 
|  | 41 # WIP | 
|  | 42 import re | 
|  | 43 | 
|  | 44 from code_generator_idl_reader import inherits_interface, implemented_as_from_im
     plemented_by | 
|  | 45 from v8_includes import * | 
|  | 46 from v8_types import * | 
|  | 47 from v8_utilities import capitalize, runtime_enable_function_name, strip_suffix | 
|  | 48 from v8_utilities import ACTIVITY_LOGGING_INCLUDES, get_call_with_parameter, get
     _custom_element_invocation_scope_parameter, get_feature_observation_parameter, g
     et_deprecation_notification_parameter, has_activity_logging | 
|  | 49 from v8_values import get_js_value_to_native_statement, get_native_to_js_value_s
     tatement, get_pass_owner_expression | 
|  | 50 | 
|  | 51 | 
|  | 52 def generate_attributes(interface): | 
|  | 53     def generate_attribute(attribute): | 
|  | 54         attribute_contents, attribute_includes = generate_attribute_and_includes
     (interface, attribute) | 
|  | 55         includes.update(attribute_includes) | 
|  | 56         return attribute_contents | 
|  | 57 | 
|  | 58     includes = set() | 
|  | 59     contents = generate_attributes_common(interface) | 
|  | 60     contents['attributes'] = [generate_attribute(attribute) for attribute in int
     erface.attributes] | 
|  | 61     return contents, includes | 
|  | 62 | 
|  | 63 | 
|  | 64 def generate_attributes_common(interface): | 
|  | 65     attributes = interface.attributes | 
|  | 66     v8_class_name = v8_types.get_v8_class_name(interface) | 
|  | 67     return { | 
|  | 68         # Size 0 constant array is not allowed in VC++ | 
|  | 69         # FIXME: rename Attrs to Attributes | 
|  | 70         'number_of_attributes': 'WTF_ARRAY_LENGTH(%sAttrs)' % v8_class_name if a
     ttributes else '0', | 
|  | 71         'attribute_templates': v8_class_name + 'Attrs' if attributes else '0', | 
|  | 72     } | 
|  | 73 | 
|  | 74 | 
|  | 75 def generate_attribute_and_includes(interface, attribute): | 
|  | 76     data_type = attribute.data_type | 
|  | 77     # FIXME: need to check should_keep_attribute_alive, but for now sufficient | 
|  | 78     # to check if primitive. | 
|  | 79     should_keep_attribute_alive = not v8_types.primitive_type(data_type) | 
|  | 80     # FIXME: eliminate should_keep_attribute_alive | 
|  | 81     if should_keep_attribute_alive: | 
|  | 82         return_js_value_statement = None  # unused | 
|  | 83         includes = includes_for_type(data_type) | 
|  | 84         includes.add('bindings/v8/V8HiddenPropertyName.h') | 
|  | 85     else: | 
|  | 86         cpp_value = getter_expression(interface, attribute) | 
|  | 87         return_js_value_statement = v8_values.cpp_value_to_js_value_return(data_
     type, cpp_value, callback_info='info') | 
|  | 88         includes = [] | 
|  | 89     contents = { | 
|  | 90         'name': attribute.name, | 
|  | 91         'conditional_string': generate_conditional_string(attribute), | 
|  | 92         'cpp_method_name': implemented_as_cpp_name(attribute), | 
|  | 93         'cpp_type': cpp_type(data_type, pointer_type='RefPtr'), | 
|  | 94         'should_keep_attribute_alive': should_keep_attribute_alive, | 
|  | 95         'return_js_value_statement': return_js_value_statement, | 
|  | 96         'v8_type': v8_type(data_type), | 
|  | 97     } | 
|  | 98     return contents, includes | 
|  | 99 | 
|  | 100 | 
|  | 101 def getter_expression(interface, attribute): | 
|  | 102     # FIXME: very incomplete | 
|  | 103     return 'imp->%s()' % uncapitalize(attribute.name) | 
|  | 104 | 
|  | 105 | 
|  | 106 ################################################################################ | 
|  | 107 # WIP | 
|  | 108 ################################################################################ | 
|  | 109 | 
|  | 110 | 
|  | 111 def generate_attributes_wip(interface): | 
|  | 112     def generate_attribute(attribute): | 
|  | 113         attribute_contents, attribute_includes = generate_attribute_and_includes
     _wip(interface, attribute) | 
|  | 114         includes.extend(attribute_includes) | 
|  | 115         return attribute_contents | 
|  | 116 | 
|  | 117     includes = [] | 
|  | 118     contents = [generate_attribute(attribute) for attribute in interface.attribu
     tes] | 
|  | 119     return contents, includes | 
|  | 120 | 
|  | 121 | 
|  | 122 def generate_attribute_and_includes_wip(interface, attribute): | 
|  | 123     cpp_class_name = implemented_as_cpp_name(interface) | 
|  | 124     per_world_bindings = 'PerWorldBindings' in attribute.extended_attributes | 
|  | 125     for_main_world_suffixes = [''] | 
|  | 126     if per_world_bindings: | 
|  | 127         for_main_world_suffixes.append('ForMainWorld') | 
|  | 128 | 
|  | 129     includes = [] | 
|  | 130     # print | 
|  | 131     # print '#'*30 | 
|  | 132     # print '[get_attribute_parameter] ', attribute.data_type, attribute.name | 
|  | 133 | 
|  | 134     check_security_for_node = 'CheckSecurityForNode' in attribute.extended_attri
     butes | 
|  | 135     if check_security_for_node: | 
|  | 136         includes.append('bindings/v8/BindingSecurity.h') | 
|  | 137     if attribute.data_type == 'SerializedScriptValue': | 
|  | 138         includes.append('bindings/v8/SerializedScriptValue.h') | 
|  | 139 | 
|  | 140     getter_activity_logging = set() | 
|  | 141     for for_main_world_suffix in for_main_world_suffixes: | 
|  | 142         if has_activity_logging(for_main_world_suffix, attribute.extended_attrib
     utes, 'Getter'): | 
|  | 143             getter_activity_logging.add(for_main_world_suffix) | 
|  | 144             includes += ACTIVITY_LOGGING_INCLUDES | 
|  | 145 | 
|  | 146     custom_element_invocation_scope_parameter, custom_element_invocation_scope_i
     ncludes = get_custom_element_invocation_scope_parameter(attribute) | 
|  | 147     includes += custom_element_invocation_scope_includes | 
|  | 148 #         print '[[]]', custom_element_invocation_scope_parameter | 
|  | 149 | 
|  | 150     enable_function = runtime_enable_function_name(attribute) | 
|  | 151 | 
|  | 152     replaceable = 'Replaceable' in attribute.extended_attributes | 
|  | 153     custom_getter = has_custom_getter(attribute) | 
|  | 154     custom_setter = has_custom_setter(attribute) | 
|  | 155     has_replaceable = not custom_setter and replaceable | 
|  | 156     has_normal_setter = (custom_setter or not has_replaceable) and not is_read_o
     nly(attribute) | 
|  | 157 | 
|  | 158     should_keep_attribute_alive = get_should_keep_attribute_alive(interface, att
     ribute) | 
|  | 159 #         print '[] should_keep_attribute_alive', should_keep_attribute_alive | 
|  | 160 | 
|  | 161     native_type = '' | 
|  | 162     array_type = '' | 
|  | 163     if not custom_getter: | 
|  | 164         native_type = get_native_type(attribute.data_type, extended_attributes=a
     ttribute.extended_attributes) | 
|  | 165         # currently array_type is always False | 
|  | 166         array_type = get_array_type(native_type) | 
|  | 167         if should_keep_attribute_alive: | 
|  | 168             if array_type: | 
|  | 169                 includes.append('V8%s.h' % array_type) | 
|  | 170             else: | 
|  | 171                 includes += get_includes_for_type(attribute.data_type) | 
|  | 172                 includes.append('bindings/v8/V8HiddenPropertyName.h') | 
|  | 173         if (setter_use_exception(attribute) and not custom_setter) or getter_use
     _exception(attribute): | 
|  | 174             includes.append('bindings/v8/ExceptionState.h') | 
|  | 175 | 
|  | 176     batched_attribute, batched_attribute_includes = generate_batched_attribute(i
     nterface, attribute, ',') | 
|  | 177     includes += batched_attribute_includes | 
|  | 178 | 
|  | 179     enabled_at_runtime = False | 
|  | 180     enabled_per_context = False | 
|  | 181     if interface.name == 'Window' and 'Unforgeable' in attribute.extended_attrib
     utes: | 
|  | 182         pass | 
|  | 183     elif 'EnabledPerContext' in attribute.extended_attributes: | 
|  | 184         enabled_per_context = True | 
|  | 185     elif 'EnabledAtRuntime' in attribute.extended_attributes: | 
|  | 186         enabled_at_runtime = True | 
|  | 187     else: | 
|  | 188         pass | 
|  | 189 | 
|  | 190     if enabled_at_runtime: | 
|  | 191         batched_attribute, batched_attribute_includes = generate_batched_attribu
     te(interface, attribute, ';') | 
|  | 192         includes += batched_attribute_includes | 
|  | 193 | 
|  | 194     compact_getter = 'Reflect' in attribute.extended_attributes and 'URL' not in
      attribute.extended_attributes and inherits_interface(interface, 'Node') and att
     ribute.data_type == 'DOMString' | 
|  | 195     compact_setter = 'Reflect' in attribute.extended_attributes and inherits_int
     erface(interface, 'Node') and attribute.data_type == 'DOMString' | 
|  | 196     compact_setter_namespace = '' | 
|  | 197     compact_setter_content_attribute_name = '' | 
|  | 198     if compact_setter: | 
|  | 199         compact_setter_content_attribute_name = attribute.name.lower() | 
|  | 200         if attribute.extended_attributes.get('Reflect'): | 
|  | 201             compact_setter_content_attribute_name = attribute.extended_attribute
     s.get('Reflect') | 
|  | 202         compact_setter_namespace = namespace_for_attribute_name(interface.name, 
     compact_setter_content_attribute_name) | 
|  | 203         includes.append('%s.h' % compact_setter_namespace) | 
|  | 204 | 
|  | 205     feature_observation_parameter, feature_observation_includes = get_feature_ob
     servation_parameter(interface) | 
|  | 206     includes += feature_observation_includes | 
|  | 207     deprecation_notification_parameter, deprecation_notification_includes = get_
     deprecation_notification_parameter(attribute) | 
|  | 208     includes += deprecation_notification_includes | 
|  | 209 | 
|  | 210     getter_function = '' | 
|  | 211     event_listener_setter_function_name = '' | 
|  | 212     event_listener_setter_function_name_not_inherits_node = '' | 
|  | 213     not_inherits_node = False | 
|  | 214     if attribute.data_type == 'EventListener': | 
|  | 215         # FIXME: Pass the main world ID for main-world-only getters. | 
|  | 216         includes.append('bindings/v8/V8AbstractEventListener.h') | 
|  | 217         includes.append('bindings/v8/V8EventListenerList.h') | 
|  | 218         getter_function = uncapitalize(attribute.name) | 
|  | 219         event_listener_setter_function_name = capitalize(attribute.name) | 
|  | 220         not_inherits_node = not inherits_interface(interface, 'Node') | 
|  | 221         if not_inherits_node: | 
|  | 222             event_listener_setter_function_name_not_inherits_node = implemented_
     as_cpp_name(attribute) | 
|  | 223         event_listener_on_error = (interface.name == 'Window' or interface.name 
     == 'WorkerGlobalScope') and attribute.name == 'onerror' | 
|  | 224         if event_listener_on_error: | 
|  | 225             includes.append('bindings/v8/V8ErrorHandler.h') | 
|  | 226 | 
|  | 227     svg_animated_type = is_svg_animated_type(interface.name) | 
|  | 228     svg_type_needing_tear_off = get_svg_type_needing_tear_off(attribute.data_typ
     e) | 
|  | 229 | 
|  | 230     ##################### Getter | 
|  | 231     getter_native_value_expression, getter_function_call_parameter, getter_inclu
     des = get_attribute_function_call_expression(interface, attribute) | 
|  | 232     includes += getter_includes | 
|  | 233 #         print '[]', getter_native_value_expression | 
|  | 234 | 
|  | 235     tear_off_and_not_list = svg_type_needing_tear_off and not interface.name.end
     swith('List') | 
|  | 236 | 
|  | 237     wrapped_value = '' | 
|  | 238     return_js_value_statements = {} | 
|  | 239     assign_native_value_to_local_variable_statement = '' | 
|  | 240     if not custom_getter: | 
|  | 241         if (svg_animated_type or interface.name == 'SVGViewSpec') and svg_type_n
     eeding_tear_off: | 
|  | 242             includes.append('V8%s.h' % attribute.data_type) | 
|  | 243         elif tear_off_and_not_list: | 
|  | 244             includes.append('V8%s.h' % attribute.data_type) | 
|  | 245             includes.append('core/svg/properties/SVGPropertyTearOff.h') | 
|  | 246             if svg_type_with_writable_properties_needing_tear_off(attribute.data
     _type) and 'Immutable' not in attribute.extended_attributes: | 
|  | 247                 getter = getter_native_value_expression | 
|  | 248                 getter = getter.replace('imp->', '') | 
|  | 249                 getter = getter.replace('\(\)', '') | 
|  | 250 | 
|  | 251                 update_method = '&%s::update%s' % (cpp_class_name, capitalize(ge
     tter)) | 
|  | 252 | 
|  | 253                 self_is_tear_off_type = get_svg_type_needing_tear_off(interface.
     name) | 
|  | 254                 if self_is_tear_off_type: | 
|  | 255                     includes.append('core/svg/properties/SVGStaticPropertyWithPa
     rentTearOff.h') | 
|  | 256                     svg_type_needing_tear_off = svg_type_needing_tear_off.replac
     e('SVGPropertyTearOff<', 'SVGStaticPropertyWithParentTearOff<%s, ' % cpp_class_n
     ame) | 
|  | 257                     wrapped_value = 'WTF::getPtr(%s::create(wrapper, %s, %s))' %
      (svg_type_needing_tear_off, getter_native_value_expression, update_method) | 
|  | 258                 else: | 
|  | 259                     includes.append('core/svg/properties/SVGStaticPropertyTearOf
     f.h') | 
|  | 260                     svg_type_needing_tear_off = svg_type_needing_tear_off.replac
     e('SVGPropertyTearOff<', 'SVGStaticPropertyTearOff<%s, ' % cpp_class_name) | 
|  | 261                     wrapped_value = 'WTF::getPtr(%s::create(imp, %s, %s))' % (sv
     g_type_needing_tear_off, getter_native_value_expression, update_method) | 
|  | 262             elif 'SVGStaticListPropertyTearOff' in svg_type_needing_tear_off: | 
|  | 263                 wrapped_value = 'WTF::getPtr(%s::create(imp, %s))' % (svg_type_n
     eeding_tear_off, getter_native_value_expression) | 
|  | 264             elif re.search('SVG(Point|PathSeg)List', svg_type_needing_tear_off): | 
|  | 265                 wrapped_value = 'WTF::getPtr(%s)' % getter_native_value_expressi
     on | 
|  | 266             else: | 
|  | 267                 wrapped_value = 'WTF::getPtr(%s::create(%s))' % (svg_type_needin
     g_tear_off, getter_native_value_expression) | 
|  | 268         elif attribute.data_type == 'SerializedScriptValue' and 'CachedAttribute
     ' in attribute.extended_attributes: | 
|  | 269             pass | 
|  | 270         elif attribute.data_type == 'EventListener': | 
|  | 271             pass | 
|  | 272         else: | 
|  | 273             original_getter_native_value_expression = getter_native_value_expres
     sion | 
|  | 274             # Fix amigious conversion problem, by casting to the base type first
      ($getterString returns a type that inherits from SVGAnimatedEnumeration, not th
     e base class directly). | 
|  | 275             if attribute.data_type == 'SVGAnimatedEnumeration': | 
|  | 276                 getter_native_value_expression = 'static_pointer_cast<SVGAnimate
     dEnumeration>(%s)' % getter_native_value_expression | 
|  | 277 | 
|  | 278     #         print '[get_attribute_parameter] native_type', native_type | 
|  | 279             if attribute.is_nullable or getter_use_exception(attribute): | 
|  | 280                 # used in local variable type | 
|  | 281                 assign_native_value_to_local_variable_statement = '%s v = %s;' %
      (native_type, getter_native_value_expression) | 
|  | 282                 getter_native_value_expression = get_pass_owner_expression(attri
     bute.data_type, 'v') | 
|  | 283 | 
|  | 284             for for_main_world_suffix in for_main_world_suffixes: | 
|  | 285                 if attribute.data_type != 'EventListener': | 
|  | 286                     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='inf
     o.GetIsolate()', callback_info='info', script_wrappable='imp', for_main_world_su
     ffix=for_main_world_suffix, used_as_return_value=True) | 
|  | 287                     return_js_value_statements[for_main_world_suffix] = return_j
     s_value_statement | 
|  | 288                     if should_keep_attribute_alive: | 
|  | 289                         assign_native_value_to_local_variable_statement = '%s v 
     = %s;' % (native_type, original_getter_native_value_expression) | 
|  | 290                         getter_native_value_expression = original_getter_native_
     value_expression | 
|  | 291                     else: | 
|  | 292                         includes += native_to_js_value_includes | 
|  | 293 | 
|  | 294     ##################### Setter | 
|  | 295     # native to JS (getter) | 
|  | 296     assign_js_value_to_local_variable_statement = '' | 
|  | 297     setter_native_value_expression = '' | 
|  | 298     set_value_statement = '' | 
|  | 299     setter_activity_logging = set() | 
|  | 300     setter_function_call_parameter = {} | 
|  | 301     if has_normal_setter: | 
|  | 302         for for_main_world_suffix in for_main_world_suffixes: | 
|  | 303             if has_activity_logging(for_main_world_suffix, attribute.extended_at
     tributes, 'Setter'): | 
|  | 304                 setter_activity_logging.add(for_main_world_suffix) | 
|  | 305                 includes += ACTIVITY_LOGGING_INCLUDES | 
|  | 306 | 
|  | 307         # JS to native (setter) | 
|  | 308         if attribute.data_type != 'EventListener': | 
|  | 309             assign_js_value_to_local_variable_statement, js_value_to_native_incl
     udes = get_js_value_to_native_statement(attribute.data_type, attribute.extended_
     attributes, 'value', 'v', 'info.GetIsolate()') | 
|  | 310             includes += js_value_to_native_includes | 
|  | 311 | 
|  | 312         setter_native_value_expression = 'v' | 
|  | 313         if is_ref_ptr_type(attribute.data_type) and not get_array_type(attribute
     .data_type): | 
|  | 314             setter_native_value_expression = 'WTF::getPtr(%s)' % setter_native_v
     alue_expression | 
|  | 315 | 
|  | 316         # set native value statement | 
|  | 317         setter_native_value_expression, setter_function_call_parameter, setter_i
     ncludes = get_attribute_function_call_expression(interface, attribute, is_setter
     =True, setter_native_value_expression=setter_native_value_expression) | 
|  | 318         includes += setter_includes | 
|  | 319 | 
|  | 320         set_value_statement = '%s;' % setter_native_value_expression | 
|  | 321 #             print '[attribute] set_value_statement', set_value_statement | 
|  | 322 | 
|  | 323     is_normal = False | 
|  | 324     if interface.name == 'Window' and 'Unforgeable' in attribute.extended_attrib
     utes: | 
|  | 325         pass | 
|  | 326     elif 'EnabledAtRuntime' in attribute.extended_attributes or 'EnabledPerConte
     xt' in attribute.extended_attributes: | 
|  | 327         pass | 
|  | 328     else: | 
|  | 329         is_normal = True | 
|  | 330 | 
|  | 331     parameter = { | 
|  | 332         'name': attribute.name, | 
|  | 333         'type': attribute.data_type, | 
|  | 334         'is_static': attribute.is_static, | 
|  | 335         'is_normal': is_normal, | 
|  | 336         'native_type': native_type, | 
|  | 337         'svg_animated_type': svg_animated_type, | 
|  | 338         'svg_type_needing_tear_off': svg_type_needing_tear_off, | 
|  | 339         'tear_off_and_not_list': tear_off_and_not_list, | 
|  | 340         'check_security_for_node': check_security_for_node, | 
|  | 341         'enable_function': enable_function, | 
|  | 342 | 
|  | 343         # EventListner hack | 
|  | 344         'getter_function': getter_function, | 
|  | 345         'event_listener_setter_function_name': event_listener_setter_function_na
     me, | 
|  | 346         'event_listener_setter_function_name_not_inherits_node': event_listener_
     setter_function_name_not_inherits_node, | 
|  | 347         'not_inherits_node': not_inherits_node, | 
|  | 348 | 
|  | 349         'getter_native_value_expression': getter_native_value_expression, | 
|  | 350         'setter_native_value_expression': setter_native_value_expression, | 
|  | 351         'return_js_value_statements': return_js_value_statements, | 
|  | 352         'set_value_statement': set_value_statement, | 
|  | 353         'conditional_string': generate_conditional_string(attribute), | 
|  | 354         'batched_attribute': batched_attribute, | 
|  | 355         'getter_use_exceptions': getter_use_exception(attribute), | 
|  | 356         'setter_use_exceptions': setter_use_exception(attribute), | 
|  | 357         'is_nullable': attribute.is_nullable, | 
|  | 358         'assign_native_value_to_local_variable_statement': assign_native_value_t
     o_local_variable_statement, | 
|  | 359         'assign_js_value_to_local_variable_statement': assign_js_value_to_local_
     variable_statement, | 
|  | 360         'has_replaceable': has_replaceable, | 
|  | 361         'has_normal_setter': has_normal_setter, | 
|  | 362         'has_custom_getter': custom_getter, | 
|  | 363         'has_custom_setter': custom_setter, | 
|  | 364         'per_world_bindings': per_world_bindings, | 
|  | 365         'for_main_world_suffixes': for_main_world_suffixes, | 
|  | 366         'should_keep_attribute_alive': should_keep_attribute_alive, | 
|  | 367         'array_type': array_type, | 
|  | 368         'getter_activity_logging': getter_activity_logging, | 
|  | 369         'setter_activity_logging': setter_activity_logging, | 
|  | 370         'enabled_at_runtime': enabled_at_runtime, | 
|  | 371         'enabled_per_context': enabled_per_context, | 
|  | 372         'compact_getter': compact_getter, | 
|  | 373         'compact_setter': compact_setter, | 
|  | 374         'compact_setter_namespace': compact_setter_namespace, | 
|  | 375         'compact_setter_content_attribute_name': compact_setter_content_attribut
     e_name, | 
|  | 376         'cached_attribute': 'CachedAttribute' in attribute.extended_attributes, | 
|  | 377         'wrapped_value': wrapped_value, | 
|  | 378         'cpp_name': implemented_as_cpp_name(attribute), | 
|  | 379         'initialized_by_event_constructor': 'InitializedByEventConstructor' in a
     ttribute.extended_attributes, | 
|  | 380         'setter': 'setSerialized' + capitalize(attribute.name), | 
|  | 381     } | 
|  | 382     parameter.update(feature_observation_parameter) | 
|  | 383     parameter.update(deprecation_notification_parameter) | 
|  | 384     parameter.update(custom_element_invocation_scope_parameter) | 
|  | 385     parameter.update(getter_function_call_parameter) | 
|  | 386     parameter.update(setter_function_call_parameter) | 
|  | 387     return parameter, includes | 
|  | 388 | 
|  | 389 | 
|  | 390 def generate_batched_attribute(interface, attribute, delimiter, indent=''): | 
|  | 391     # GenerateSingleBatchedAttribute in perl | 
|  | 392     cpp_class_name = implemented_as_cpp_name(interface) | 
|  | 393     v8_class_name = get_v8_class_name(interface) | 
|  | 394     is_constructor = attribute.data_type.endswith('Constructor') | 
|  | 395 #         print '[--]', attribute.name, attribute.data_type, is_constructor | 
|  | 396     includes = [] | 
|  | 397 | 
|  | 398     access_control = 'v8::DEFAULT' | 
|  | 399     if attribute.extended_attributes.get('DoNotCheckSecurityOnGetter'): | 
|  | 400         access_control = 'v8::ALL_CAN_READ' | 
|  | 401     elif attribute.extended_attributes.get('DoNotCheckSecurityOnSetter'): | 
|  | 402         access_control = 'v8::ALL_CAN_WRITE' | 
|  | 403     elif attribute.extended_attributes.get('DoNotCheckSecurity'): | 
|  | 404         access_control = 'v8::ALL_CAN_READ' | 
|  | 405         if not is_read_only(attribute): | 
|  | 406             access_control += ' | v8::ALL_CAN_WRITE' | 
|  | 407     if attribute.extended_attributes.get('Unforgeable'): | 
|  | 408         access_control += ' | v8::PROHIBITS_OVERWRITING' | 
|  | 409     access_control = 'static_cast<v8::AccessControl>(%s)' % access_control | 
|  | 410 | 
|  | 411     prop_attr = 'v8::None' | 
|  | 412     # Check attributes. | 
|  | 413     # As per Web IDL specification, constructor properties on the ECMAScript glo
     bal object should be | 
|  | 414     # configurable and should not be enumerable. | 
|  | 415     if 'NotEnumerable' in attribute.extended_attributes or is_constructor: | 
|  | 416         prop_attr += ' | v8::DontEnum' | 
|  | 417     if 'Unforgeable' in attribute.extended_attributes and not is_constructor: | 
|  | 418         prop_attr += ' | v8::DontDelete' | 
|  | 419 | 
|  | 420     on_proto = '0 /* on instance */' | 
|  | 421     if is_constructor: | 
|  | 422         constructor_type = strip_suffix(attribute.data_type, 'Constructor') | 
|  | 423         # $constructorType ~= /Constructor$/ indicates that it is NamedConstruct
     or. | 
|  | 424         # We do not generate the header file for NamedConstructor of class XXXX, | 
|  | 425         # since we generate the NamedConstructor declaration into the header fil
     e of class XXXX. | 
|  | 426         # FIXME: We just stripped the 'Constructor' suffix! | 
|  | 427         if not constructor_type.endswith('Constructor') or attribute.extended_at
     tributes.get('CustomConstructor'): | 
|  | 428             includes.append('V8%s.h' % constructor_type) | 
|  | 429         getter = '%sV8Internal::%sConstructorGetter' % (cpp_class_name, cpp_clas
     s_name) | 
|  | 430         setter = '%sV8Internal::%sReplaceableAttrSetterCallback' % (cpp_class_na
     me, cpp_class_name) | 
|  | 431         getter_for_main_world = '0' | 
|  | 432         setter_for_main_world = '0' | 
|  | 433         data = '&V8${constructorType}::info' | 
|  | 434     else: | 
|  | 435         # Default Getter and Setter | 
|  | 436         getter = '%sV8Internal::%sAttrGetterCallback' % (cpp_class_name, attribu
     te.name) | 
|  | 437         setter = '%sV8Internal::%sAttrSetterCallback' % (cpp_class_name, attribu
     te.name) | 
|  | 438         getter_for_main_world = getter + 'ForMainWorld' | 
|  | 439         setter_for_main_world = setter + 'ForMainWorld' | 
|  | 440         data = '0 /* no data */' | 
|  | 441         if not has_custom_setter(attribute) and attribute.extended_attributes.ge
     t('Replaceable'): | 
|  | 442             setter = '%sV8Internal::%sReplaceableAttrSetterCallback' % (cpp_clas
     s_name, cpp_class_name) | 
|  | 443             setter_for_main_world = '0' | 
|  | 444     # Read only attributes | 
|  | 445     if is_read_only(attribute): | 
|  | 446         setter = '0' | 
|  | 447         setter_for_main_world = '0' | 
|  | 448     if 'PerWorldBindings' not in attribute.extended_attributes: | 
|  | 449         getter_for_main_world = '0' | 
|  | 450         setter_for_main_world = '0' | 
|  | 451 | 
|  | 452     # An accessor can be installed on the proto | 
|  | 453     if attribute.extended_attributes.get('OnProto'): | 
|  | 454         on_proto = '1 /* on proto */' | 
|  | 455 | 
|  | 456     code = ( | 
|  | 457         '{"%s", %s, %s, %s, %s, %s, %s, static_cast<v8::PropertyAttribute>(%s), 
     %s}%s' % | 
|  | 458         (attribute.name, getter, setter, getter_for_main_world, setter_for_main_
     world, data, access_control, prop_attr, on_proto, delimiter)) | 
|  | 459     return code, includes | 
|  | 460 | 
|  | 461 | 
|  | 462 # Auxiliary functions | 
|  | 463 | 
|  | 464 | 
|  | 465 def get_should_keep_attribute_alive(interface, attribute): | 
|  | 466     return ( | 
|  | 467         'KeepAttributeAliveForGC' in attribute.extended_attributes or | 
|  | 468         # Basically, for readonly or replaceable attributes, we have to | 
|  | 469         # guarantee that JS wrappers don't get garbage-collected prematually | 
|  | 470         # when their lifetime is strongly tied to their owner. | 
|  | 471         ((is_wrapper_type(attribute.data_type) and | 
|  | 472           (is_read_only(attribute) or | 
|  | 473            'Replaceable' in attribute.extended_attributes)) and | 
|  | 474         # However, there are a couple of exceptions. | 
|  | 475         not( | 
|  | 476             # Node lifetime is managed by object grouping. | 
|  | 477             inherits_interface(interface, 'Node') or | 
|  | 478             is_dom_node_type(attribute.data_type) or | 
|  | 479             # To avoid adding a reference to itself. | 
|  | 480             # FIXME: Introduce [DoNotKeepAttributeAliveForGC] and remove | 
|  | 481             # this hack of depending on the attribute name. | 
|  | 482             attribute.name == 'self' or | 
|  | 483             # FIXME: Remove these hard-coded hacks. | 
|  | 484             attribute.data_type in ['EventTarget', 'SerializedScriptValue', 'Win
     dow'] or | 
|  | 485             'SVG' in attribute.data_type or | 
|  | 486             'HTML' in attribute.data_type))) | 
|  | 487 | 
|  | 488 | 
|  | 489 def get_attribute_function_call_expression(interface, attribute, is_setter=False
     , setter_native_value_expression=None): | 
|  | 490     """ | 
|  | 491     @return function_call_expression, includes | 
|  | 492     """ | 
|  | 493     # GetterExpression / SetterExpression in perl | 
|  | 494     includes = [] | 
|  | 495     arguments = [] | 
|  | 496     interface_name = interface.name | 
|  | 497     cpp_class_name = implemented_as_cpp_name(interface) | 
|  | 498     content_attribute_name, additional_includes = get_content_attribute_name(int
     erface_name, attribute) | 
|  | 499     includes += additional_includes | 
|  | 500 | 
|  | 501     function_name = '' | 
|  | 502     if is_setter: | 
|  | 503         if content_attribute_name: | 
|  | 504             if attribute.data_type == 'boolean': | 
|  | 505                 function_name = 'setBooleanAttribute' | 
|  | 506             elif attribute.data_type == 'long': | 
|  | 507                 function_name = 'setIntegralAttribute' | 
|  | 508             elif attribute.data_type == 'unsigned long': | 
|  | 509                 function_name = 'setUnsignedIntegralAttribute' | 
|  | 510             else: | 
|  | 511                 function_name = 'setAttribute' | 
|  | 512         else: | 
|  | 513             function_name = 'set' + capitalize(implemented_as_cpp_name(attribute
     )) | 
|  | 514     else: | 
|  | 515         if content_attribute_name: | 
|  | 516             if 'URL' in attribute.extended_attributes: | 
|  | 517                 function_name = 'getURLAttribute' | 
|  | 518             elif attribute.data_type == 'boolean': | 
|  | 519                 function_name = 'fastHasAttribute' | 
|  | 520             elif attribute.data_type == 'long': | 
|  | 521                 function_name = 'getIntegralAttribute' | 
|  | 522             elif attribute.data_type == 'unsigned long': | 
|  | 523                 function_name = 'getUnsignedIntegralAttribute' | 
|  | 524             elif content_attribute_name == 'WebCore::HTMLNames::idAttr': | 
|  | 525                 function_name = 'getIdAttribute' | 
|  | 526                 content_attribute_name = '' | 
|  | 527             elif content_attribute_name == 'WebCore::HTMLNames::nameAttr': | 
|  | 528                 function_name = 'getNameAttribute' | 
|  | 529                 content_attribute_name = '' | 
|  | 530             elif content_attribute_name == 'WebCore::HTMLNames::classAttr': | 
|  | 531                 function_name = 'getClassAttribute' | 
|  | 532                 content_attribute_name = '' | 
|  | 533             elif is_svg_animated_type(attribute.data_type): | 
|  | 534                 # We cannot use fast attributes for animated SVG types. | 
|  | 535                 function_name = 'getAttribute' | 
|  | 536             else: | 
|  | 537                 function_name = 'fastGetAttribute' | 
|  | 538         else: | 
|  | 539             function_name = uncapitalize(implemented_as_cpp_name(attribute)) | 
|  | 540 #                 print '[[]]', function_name | 
|  | 541     if content_attribute_name: | 
|  | 542         arguments.append(content_attribute_name) | 
|  | 543 | 
|  | 544     implemented_by = attribute.extended_attributes.get('ImplementedBy') | 
|  | 545     if implemented_by: | 
|  | 546         implemented_by_cpp_name = implemented_as_from_implemented_by(implemented
     _by) | 
|  | 547         includes += header_files_for_interface(implemented_by, implemented_by_cp
     p_name) | 
|  | 548         if not attribute.is_static: | 
|  | 549             arguments = ['imp'] + arguments | 
|  | 550         function_name = '%s::%s' % (implemented_by_cpp_name, function_name) | 
|  | 551     elif attribute.is_static: | 
|  | 552         function_name = '%s::%s' % (cpp_class_name, function_name) | 
|  | 553     else: | 
|  | 554         function_name = 'imp->%s' % function_name | 
|  | 555 | 
|  | 556     if is_setter: | 
|  | 557         arguments.append(setter_native_value_expression) | 
|  | 558         if setter_use_exception(attribute): | 
|  | 559             arguments.append('es') | 
|  | 560         call_with = attribute.extended_attributes.get('SetterCallWith') or attri
     bute.extended_attributes.get('CallWith') | 
|  | 561     else: | 
|  | 562         if attribute.is_nullable: | 
|  | 563             arguments.append('isNull') | 
|  | 564         if getter_use_exception(attribute): | 
|  | 565             arguments.append('es') | 
|  | 566         call_with = attribute.extended_attributes.get('CallWith') | 
|  | 567 | 
|  | 568     call_with_arguments, call_with_parameter, call_with_includes = get_call_with
     _parameter(call_with) | 
|  | 569     includes += call_with_includes | 
|  | 570     arguments = call_with_arguments + arguments | 
|  | 571 | 
|  | 572     function_call_expression = '%s(%s)' % (function_name, ', '.join(arguments)) | 
|  | 573     return function_call_expression, call_with_parameter, includes | 
|  | 574 | 
|  | 575 | 
|  | 576 def get_custom_element_invocation_scope_parameter(interface_or_attribute_or_func
     tion): | 
|  | 577 #     print '[[]]', interface_or_attribute_or_function.extended_attributes | 
|  | 578     custom_element_invocation_scope = has_extended_attribute(interface_or_attrib
     ute_or_function, ['DeliverCustomElementCallbacks', 'Reflect']) | 
|  | 579     parameter = { | 
|  | 580         'custom_element_invocation_scope': custom_element_invocation_scope, | 
|  | 581     } | 
|  | 582     if custom_element_invocation_scope: | 
|  | 583         includes = ['core/dom/CustomElementCallbackDispatcher.h'] | 
|  | 584     else: | 
|  | 585         includes = [] | 
|  | 586     return parameter, includes | 
|  | 587 | 
|  | 588 | 
|  | 589 def has_extended_attribute(item, extended_attribute_list): | 
|  | 590     # FIXME: useful function, use widely | 
|  | 591     return any([extended_attribute in item.extended_attributes | 
|  | 592                 for extended_attribute in extended_attribute_list]) | 
|  | 593 | 
|  | 594 | 
|  | 595 def getter_use_exception(attribute): | 
|  | 596     return has_extended_attribute(attribute, ['GetterRaisesException', 'RaisesEx
     ception']) | 
|  | 597 | 
|  | 598 | 
|  | 599 def setter_use_exception(attribute): | 
|  | 600     return has_extended_attribute(attribute, ['SetterRaisesException', 'RaisesEx
     ception']) | 
|  | 601 | 
|  | 602 | 
|  | 603 def namespace_for_attribute_name(interface_name, attribute_name): | 
|  | 604     if (interface_name.startswith('SVG') and | 
|  | 605         attribute_name not in SVG_ATTRIBUTES_IN_HTML): | 
|  | 606         return 'SVGNames' | 
|  | 607     return 'HTMLNames' | 
|  | 608 | 
|  | 609 | 
|  | 610 def get_content_attribute_name(interface_name, attribute): | 
|  | 611     if 'Reflect' not in attribute.extended_attributes: | 
|  | 612         return None, [] | 
|  | 613     default_content_attribute_name = implemented_as_cpp_name(attribute).lower() | 
|  | 614     content_attribute_name = attribute.extended_attributes['Reflect'] or default
     _content_attribute_name | 
|  | 615     namespace = namespace_for_attribute_name(interface_name, content_attribute_n
     ame) | 
|  | 616     scoped_name = 'WebCore::%s::%sAttr' % (namespace, content_attribute_name) | 
|  | 617     includes = [namespace + '.h'] | 
|  | 618     return scoped_name, includes | 
| OLD | NEW | 
|---|