| 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 functions. | 
|  | 30 | 
|  | 31 FIXME: rename "parameter/parameters": | 
|  | 32 "template parameters" is easily confused with "function parameters" | 
|  | 33 Also, "parameter*s*", not "parameter". | 
|  | 34 """ | 
|  | 35 | 
|  | 36 | 
|  | 37 from code_generator_idl_reader import implemented_as_from_implemented_by | 
|  | 38 from v8_includes import * | 
|  | 39 from v8_types import * | 
|  | 40 from v8_utilities import extended_attribute_contains, generate_conditional_strin
     g, get_raises_exception, runtime_enable_function_name, implemented_as_cpp_name | 
|  | 41 from v8_values import get_js_value_to_native_statement, get_native_to_js_value_s
     tatement, get_pass_owner_expression | 
|  | 42 | 
|  | 43 from v8_utilities import ACTIVITY_LOGGING_INCLUDES, get_call_with_parameter, get
     _custom_element_invocation_scope_parameter, get_deprecation_notification_paramet
     er, get_function_mandatory_parameters, get_feature_observation_parameter, has_ac
     tivity_logging | 
|  | 44 | 
|  | 45 | 
|  | 46 def generate_functions(interface): | 
|  | 47     # FIXME: clearer with a list comprehension + nested function to handle inclu
     des | 
|  | 48     functions = [] | 
|  | 49     includes = [] | 
|  | 50     for function in interface.operations: | 
|  | 51         function_contents, function_includes = generate_function(interface, func
     tion) | 
|  | 52 #             print '[FUNC]', function_contents | 
|  | 53         functions.append(function_contents) | 
|  | 54         includes += function_includes | 
|  | 55     return functions, includes | 
|  | 56 | 
|  | 57 | 
|  | 58 def generate_function(interface, function): | 
|  | 59     includes = [] | 
|  | 60     name = function.name | 
|  | 61     cpp_class_name = implemented_as_cpp_name(interface) | 
|  | 62     is_normal_function = function.name and 'EnabledPerContext' not in function.e
     xtended_attributes | 
|  | 63     is_standard_function = get_is_standard_function(interface, function) | 
|  | 64     is_custom = has_custom_implementation(function) | 
|  | 65 | 
|  | 66     per_world_bindings = 'PerWorldBindings' in function.extended_attributes | 
|  | 67     for_main_world_suffixes = [''] | 
|  | 68     if per_world_bindings: | 
|  | 69         for_main_world_suffixes.append('ForMainWorld') | 
|  | 70 | 
|  | 71     activity_logging = set() | 
|  | 72     setter_function_call_parameter = {} | 
|  | 73     for for_main_world_suffix in for_main_world_suffixes: | 
|  | 74         if has_activity_logging(for_main_world_suffix, function.extended_attribu
     tes, 'Method'): | 
|  | 75             activity_logging.add(for_main_world_suffix) | 
|  | 76             includes += ACTIVITY_LOGGING_INCLUDES | 
|  | 77 | 
|  | 78     check_security_for_node = 'CheckSecurityForNode' in function.extended_attrib
     utes | 
|  | 79     if check_security_for_node: | 
|  | 80         includes.append('bindings/v8/BindingSecurity.h') | 
|  | 81 | 
|  | 82     method_for_main_world = '0' | 
|  | 83     if 'PerWorldBindings' in function.extended_attributes: | 
|  | 84         method_for_main_world = '%sV8Internal::%sMethodCallbackForMainWorld' % (
     implemented_as_cpp_name(interface), function.name) | 
|  | 85     mandatory_parameters = get_function_mandatory_parameters(function) | 
|  | 86 | 
|  | 87     if len(function.overloads) > 1: | 
|  | 88         name = '%s%d' % (name, function.overload_index) | 
|  | 89     is_representative = function.overload_index == 1 | 
|  | 90     conditional_runtime = '' | 
|  | 91     enable_function = '' | 
|  | 92     if 'EnabledAtRuntime' in function.extended_attributes: | 
|  | 93         # Only call Set()/SetAccessor() if this method should be enabled | 
|  | 94         enable_function = runtime_enable_function_name(function) | 
|  | 95         conditional_runtime = 'if (%s())\n        ' % enable_function | 
|  | 96     if function.extended_attributes.get('EnabledPerContext'): | 
|  | 97         # Only call Set()/SetAccessor() if this method should be enabled | 
|  | 98         enable_function = get_context_enable_function(function) | 
|  | 99         conditional_runtime = 'if (%s(impl->document()))' % enable_function | 
|  | 100 | 
|  | 101     template = 'proto' | 
|  | 102     if 'Unforgeable' in function.extended_attributes: | 
|  | 103         template = 'instance' | 
|  | 104     if function.is_static: | 
|  | 105         template = 'desc' | 
|  | 106 | 
|  | 107     setter = '%sV8Internal::%sDomainSafeFunctionSetter' % (cpp_class_name, cpp_c
     lass_name) if 'ReadOnly' not in function.extended_attributes else '0' | 
|  | 108 | 
|  | 109     signature = 'defaultSignature' | 
|  | 110     if 'DoNotCheckSignature' in function.extended_attributes or function.is_stat
     ic: | 
|  | 111         signature = 'v8::Local<v8::Signature>()' | 
|  | 112     requires_custom_signature = get_requires_custom_signature(function) | 
|  | 113     if requires_custom_signature: | 
|  | 114         signature = function.name + 'Signature' | 
|  | 115 | 
|  | 116     # FIXME: simplify: additional_property_attributes_list, ' | '.join(...) | 
|  | 117     property_attributes = 'v8::DontDelete' | 
|  | 118     if 'NotEnumerable' in function.extended_attributes: | 
|  | 119         property_attributes += ' | v8::DontEnum' | 
|  | 120     if 'ReadOnly' in function.extended_attributes: | 
|  | 121         property_attributes += ' | v8::ReadOnly' | 
|  | 122 | 
|  | 123     if property_attributes == 'v8::DontDelete': | 
|  | 124         property_attributes = '' | 
|  | 125     else: | 
|  | 126         property_attributes = ', static_cast<v8::PropertyAttribute>(%s)' % prope
     rty_attributes | 
|  | 127 | 
|  | 128     custom_signatures = [] | 
|  | 129     if requires_custom_signature: | 
|  | 130         for parameter in function.arguments: | 
|  | 131             if is_wrapper_type(parameter.data_type): | 
|  | 132                 if parameter.data_type == 'XPathNSResolver': | 
|  | 133                     # Special case for XPathNSResolver.  All other browsers acce
     pts a callable, | 
|  | 134                     # so, even though it's against IDL, accept objects here. | 
|  | 135                     custom_signatures.append('v8::Handle<v8::FunctionTemplate>()
     ') | 
|  | 136                 else: | 
|  | 137                     array_or_sequence_type = get_array_or_sequence_type(paramete
     r.data_type) | 
|  | 138 | 
|  | 139                     if array_or_sequence_type: | 
|  | 140                         if is_ref_ptr_type(array_or_sequence_type): | 
|  | 141                             includes += get_includes_for_type(array_or_sequence_
     type) | 
|  | 142                         else: | 
|  | 143                             custom_signatures.append('v8::Handle<v8::FunctionTem
     plate>()') | 
|  | 144                             continue | 
|  | 145                     else: | 
|  | 146 #                             print '[FOO]', parameter.data_type, 'AS', array_or
     _sequence_type | 
|  | 147                         includes += get_includes_for_type(parameter.data_type) | 
|  | 148                     custom_signatures.append('V8PerIsolateData::from(isolate)->r
     awTemplate(&V8%s::info, currentWorldType)' % parameter.data_type) | 
|  | 149             else: | 
|  | 150                 custom_signatures.append('v8::Handle<v8::FunctionTemplate>()') | 
|  | 151     custom_signature = ', '.join(custom_signatures) | 
|  | 152     function_call_parameters = {} | 
|  | 153     raises_exception = get_raises_exception(function) | 
|  | 154     if any(['IsIndex' in parameter.extended_attributes | 
|  | 155             for parameter in function.arguments]): | 
|  | 156         raises_exception = True | 
|  | 157     feature_observation_parameter = {} | 
|  | 158     deprecation_notification_parameter = {} | 
|  | 159     custom_element_invocation_scope_parameter = {} | 
|  | 160     parameter_check_parameters = {} | 
|  | 161 | 
|  | 162     if not is_custom and name: | 
|  | 163         if raises_exception: | 
|  | 164             includes.append('bindings/v8/ExceptionState.h') | 
|  | 165 | 
|  | 166         parameter_check_parameters, parameter_check_includes, replacements = get
     _parameter_check_parameters(interface, function) | 
|  | 167         includes += parameter_check_includes | 
|  | 168 | 
|  | 169         for for_main_world_suffix in for_main_world_suffixes: | 
|  | 170             function_call_parameter, function_call_includes = get_function_call_
     parameter(interface, function, len(function.arguments), for_main_world_suffix=fo
     r_main_world_suffix, replacements=replacements) | 
|  | 171             function_call_parameters[for_main_world_suffix] = function_call_para
     meter | 
|  | 172             includes += function_call_includes | 
|  | 173 | 
|  | 174         comment_info = 'Function "%s" (ExtAttr: "%s")' % (function.name, ' '.joi
     n(function.extended_attributes.keys())) | 
|  | 175 | 
|  | 176 #         if template == 'proto' and conditional_runtime == '' and signature == 
     'defaultSignature' and property_attributes == '': | 
|  | 177 #             raise Exception('This shouldn't happen: Class '%s' %s' % (cpp_clas
     s_name, comment_info)) | 
|  | 178 | 
|  | 179         custom_element_invocation_scope_parameter, custom_element_invocation_sco
     pe_includes = get_custom_element_invocation_scope_parameter(function) | 
|  | 180         includes += custom_element_invocation_scope_includes | 
|  | 181 | 
|  | 182         feature_observation_parameter, feature_observation_includes = get_featur
     e_observation_parameter(function) | 
|  | 183         includes += feature_observation_includes | 
|  | 184 | 
|  | 185         deprecation_notification_parameter, deprecation_notification_includes = 
     get_deprecation_notification_parameter(function) | 
|  | 186         includes += deprecation_notification_includes | 
|  | 187 | 
|  | 188     # print | 
|  | 189     # print '#'*30 | 
|  | 190     # print '[get_function_parameter] ', function.data_type, name | 
|  | 191     contents = { | 
|  | 192         'name': name, | 
|  | 193         'is_static': function.is_static, | 
|  | 194         'is_custom': is_custom, | 
|  | 195         'create_callback': is_representative and is_normal_function and is_stand
     ard_function, | 
|  | 196         'is_representative': is_representative, | 
|  | 197         'conditional_runtime': conditional_runtime, | 
|  | 198         'template': template, | 
|  | 199         'setter': setter, | 
|  | 200         'signature': signature, | 
|  | 201         'property_attributes': property_attributes, | 
|  | 202         'requires_custom_signature': requires_custom_signature, | 
|  | 203         'custom_signature': custom_signature, | 
|  | 204         'conditional_string': generate_conditional_string(function), | 
|  | 205         'mandatory_parameters': mandatory_parameters, | 
|  | 206         'length': get_function_mandatory_parameters(function, count_variadic=Tru
     e), | 
|  | 207         'parameters': parameter_check_parameters, | 
|  | 208         'function_call_parameter': function_call_parameters, | 
|  | 209         'method_for_main_world': method_for_main_world, | 
|  | 210         'is_normal_function': is_normal_function, | 
|  | 211         'is_standard_function': is_standard_function, | 
|  | 212         'is_enabled_per_context_function': function.name and 'EnabledPerContext'
      in function.extended_attributes, | 
|  | 213         'raises_exception': raises_exception, | 
|  | 214         'do_not_check_security': 'DoNotCheckSecurity' in function.extended_attri
     butes, | 
|  | 215         'for_main_world_suffixes': for_main_world_suffixes, | 
|  | 216         'cpp_name': implemented_as_cpp_name(function), | 
|  | 217         'check_security_for_node': check_security_for_node, | 
|  | 218         'enable_function': enable_function, | 
|  | 219         'activity_logging': activity_logging, | 
|  | 220     } | 
|  | 221     contents.update(feature_observation_parameter) | 
|  | 222     contents.update(deprecation_notification_parameter) | 
|  | 223     contents.update(custom_element_invocation_scope_parameter) | 
|  | 224     return contents, includes | 
|  | 225 | 
|  | 226 | 
|  | 227 def get_function_call_parameter(interface, function, number_of_parameters=None, 
     for_main_world_suffix='', replacements=None): | 
|  | 228     # return parameter for function_call macro, includes | 
|  | 229     replacements = replacements or {} | 
|  | 230     if number_of_parameters is None: | 
|  | 231         number_of_parameters = len(function.arguments) | 
|  | 232 | 
|  | 233     includes = [] | 
|  | 234     arguments = [] | 
|  | 235     cpp_class_name = implemented_as_cpp_name(interface) | 
|  | 236     implemented_by = function.extended_attributes.get('ImplementedBy') | 
|  | 237     ### TODO Similar to attribute. merge! | 
|  | 238     if implemented_by: | 
|  | 239         implemented_by_cpp_name = implemented_as_from_implemented_by(implemented
     _by) | 
|  | 240         includes += header_files_for_interface(implemented_by, implemented_by_cp
     p_name) | 
|  | 241         function_name = '%s::%s' % (implemented_by_cpp_name, implemented_as_cpp_
     name(function)) | 
|  | 242         if not function.is_static: | 
|  | 243             arguments.append('imp') | 
|  | 244     elif function.is_static: | 
|  | 245         function_name = '%s::%s' % (cpp_class_name, implemented_as_cpp_name(func
     tion)) | 
|  | 246     else: | 
|  | 247         function_name = 'imp->%s' % implemented_as_cpp_name(function) | 
|  | 248 | 
|  | 249     call_with = function.extended_attributes.get('CallWith') | 
|  | 250     call_with_arguments, call_with_parameter, call_with_includes = get_call_with
     _parameter(call_with, return_void=True, function=function) | 
|  | 251     includes += call_with_includes | 
|  | 252     arguments = call_with_arguments + arguments | 
|  | 253 | 
|  | 254     parameters = [] | 
|  | 255     for index, parameter in enumerate(function.arguments): | 
|  | 256         svg_tear_off_and_not_list = False | 
|  | 257         if index == number_of_parameters: | 
|  | 258             break | 
|  | 259         if replacements.get(parameter.name): | 
|  | 260             arguments.append(replacements.get(parameter.name)) | 
|  | 261         elif parameter.data_type == 'NodeFilter' or parameter.data_type == 'XPat
     hNSResolver': | 
|  | 262             arguments.append('%s.get()' % parameter.name) | 
|  | 263         elif get_svg_type_needing_tear_off(parameter.data_type) and not interfac
     e.name.endswith('List'): | 
|  | 264             includes.append('core/dom/ExceptionCode.h') | 
|  | 265             arguments.append('%s->propertyReference()' % parameter.name) | 
|  | 266             svg_tear_off_and_not_list = True | 
|  | 267         elif parameter.data_type == 'SVGMatrix' and interface.name == 'SVGTransf
     ormList': | 
|  | 268             arguments.append('%s.get()' % parameter.name) | 
|  | 269         else: | 
|  | 270             arguments.append(parameter.name) | 
|  | 271         parameter = { | 
|  | 272             'svg_tear_off_and_not_list': svg_tear_off_and_not_list, | 
|  | 273             'name': parameter.name, | 
|  | 274         } | 
|  | 275         parameters.append(parameter) | 
|  | 276 | 
|  | 277     if get_raises_exception(function): | 
|  | 278         arguments.append('es') | 
|  | 279 | 
|  | 280     function_call_expression = '%s(%s)' % (function_name, ', '.join(arguments)) | 
|  | 281     native_value_expression = get_pass_owner_expression(function.data_type, 'res
     ult') | 
|  | 282     function_call_statement = '' | 
|  | 283     if function.data_type == 'void': | 
|  | 284         function_call_statement = '%s;' % function_call_expression | 
|  | 285     elif extended_attribute_contains(function.extended_attributes.get('CallWith'
     ), 'ScriptState') or get_raises_exception(function): | 
|  | 286         function_call_statement = '%s result = %s;' % (get_native_type(function.
     data_type, extended_attributes=function.extended_attributes), function_call_expr
     ession) | 
|  | 287     else: | 
|  | 288         native_value_expression = function_call_expression | 
|  | 289 | 
|  | 290     extended_attribute_contains_script_state = extended_attribute_contains(call_
     with, 'ScriptState') | 
|  | 291 | 
|  | 292     script_wrappable = is_dom_node_type(interface.name) and 'imp' or 0 | 
|  | 293     return_js_value_statement = '' | 
|  | 294     return_js_value_statement, native_to_js_value_includes = get_native_to_js_va
     lue_statement(function.data_type, function.extended_attributes, native_value_exp
     ression, creation_context='args.Holder()', isolate='args.GetIsolate()', callback
     _info='args', script_wrappable=script_wrappable, for_main_world_suffix=for_main_
     world_suffix, used_as_return_value=True) | 
|  | 295     includes += native_to_js_value_includes | 
|  | 296 #         print '[----]', function.name | 
|  | 297 | 
|  | 298     svg_native_type = svg_tear_off = get_svg_type_needing_tear_off(function.data
     _type) | 
|  | 299     svg_tear_off_and_not_list = svg_tear_off and not interface.name.endswith('Li
     st') | 
|  | 300     dom_node_type = is_dom_node_type(interface.name) | 
|  | 301     if svg_tear_off_and_not_list: | 
|  | 302         includes.append('V8%s.h' % function.data_type) | 
|  | 303         includes.append('core/svg/properties/SVGPropertyTearOff.h') | 
|  | 304 | 
|  | 305     parameter = { | 
|  | 306         'statement': function_call_statement, | 
|  | 307         'raises_exception': get_raises_exception(function), | 
|  | 308         'return_js_value_statement': return_js_value_statement, | 
|  | 309         'extended_attribute_contains_script_state': extended_attribute_contains_
     script_state, | 
|  | 310         'call_with': call_with_parameter, | 
|  | 311         'parameters': parameters, | 
|  | 312         'svg_tear_off_and_not_list': svg_tear_off_and_not_list, | 
|  | 313         'svg_tear_off': svg_tear_off, | 
|  | 314         'is_dom_node_type': dom_node_type, | 
|  | 315         'for_main_world_suffix': for_main_world_suffix, | 
|  | 316         'svg_native_type': svg_native_type, | 
|  | 317         'native_value_expression': native_value_expression, | 
|  | 318     } | 
|  | 319     return parameter, includes | 
|  | 320 | 
|  | 321 | 
|  | 322 def get_function_mandatory_parameters(function, count_variadic=False): | 
|  | 323     allow_non_optional = True | 
|  | 324     for parameter in function.arguments: | 
|  | 325         if parameter.is_optional or parameter.is_variadic: | 
|  | 326             allow_non_optional = False | 
|  | 327         else: | 
|  | 328             if not allow_non_optional: | 
|  | 329                 raise Exception() | 
|  | 330     mandatory_parameters = 0 | 
|  | 331     for parameter in function.arguments: | 
|  | 332         if parameter.is_optional: | 
|  | 333             break | 
|  | 334         if parameter.is_variadic and not count_variadic: | 
|  | 335             break | 
|  | 336         mandatory_parameters += 1 | 
|  | 337 #     print '[]', function.name, mandatory_parameters | 
|  | 338     return mandatory_parameters | 
|  | 339 | 
|  | 340 | 
|  | 341 def get_parameter_check_parameters(interface, function, for_main_world_suffix=''
     ): | 
|  | 342     # GenerateParametersCheck in perl | 
|  | 343     includes = [] | 
|  | 344     parameters_check_parameter = [] | 
|  | 345     for parameter_index in range(len(function.arguments)): | 
|  | 346         parameter_check_parameter, parameter_check_includes = get_parameter_chec
     k_parameter(interface, function, parameter_index) | 
|  | 347         parameters_check_parameter.append(parameter_check_parameter) | 
|  | 348         includes += parameter_check_includes | 
|  | 349     replacements = {}  # TODO | 
|  | 350     return parameters_check_parameter, includes, replacements | 
|  | 351 | 
|  | 352 | 
|  | 353 def get_parameter_check_parameter(interface, function, parameter_index, for_main
     _world_suffix=''): | 
|  | 354     # corresponds to for loop in GenerateParametersCheck in perl | 
|  | 355     includes = ['bindings/v8/ExceptionState.h'] | 
|  | 356     parameter = function.arguments[parameter_index] | 
|  | 357     is_callback_interface = is_callback_interface_etc(parameter.data_type) | 
|  | 358     if is_callback_interface: | 
|  | 359         includes.append('V8%s.h' % parameter.data_type) | 
|  | 360     if parameter.data_type == 'SerializedScriptValue': | 
|  | 361         includes.append('bindings/v8/SerializedScriptValue.h') | 
|  | 362     is_index = 'IsIndex' in parameter.extended_attributes | 
|  | 363     if is_index: | 
|  | 364         includes.append('core/dom/ExceptionCode.h') | 
|  | 365 | 
|  | 366     native_type = get_native_type(parameter.data_type, extended_attributes=param
     eter.extended_attributes, used_to_assign_js_value=True) | 
|  | 367     native_element_type = get_native_type(parameter.data_type) | 
|  | 368     if native_element_type.endswith('>'): | 
|  | 369         native_element_type += ' ' | 
|  | 370 | 
|  | 371 #         print '[[]]', native_type | 
|  | 372     default = '' | 
|  | 373     if 'Default' in parameter.extended_attributes: | 
|  | 374         default = parameter.extended_attributes.get('Default') | 
|  | 375 | 
|  | 376     if parameter.is_optional and default == 'NullString': | 
|  | 377         js_value = 'argumentOrNull(args, %d)' % parameter_index | 
|  | 378     else: | 
|  | 379         js_value = 'args[%d]' % parameter_index | 
|  | 380 | 
|  | 381     js_to_native_statement, js_value_to_native_includes = get_js_value_to_native
     _statement(parameter.data_type, parameter.extended_attributes, js_value, paramet
     er.name, 'args.GetIsolate()') | 
|  | 382     includes += js_value_to_native_includes | 
|  | 383 | 
|  | 384     enum_values = get_enum_values(parameter.data_type) | 
|  | 385     enum_validation_terms = ['string == "%s"' % enum_value for enum_value in enu
     m_values] | 
|  | 386     enum_validation_expression = ' || '.join(enum_validation_terms) | 
|  | 387 | 
|  | 388     # Optional arguments without [Default=...] should generate an early call wit
     h fewer arguments. | 
|  | 389     # Optional arguments with [Optional=...] should not generate the early call. | 
|  | 390     # Optional Dictionary arguments always considered to have default of empty d
     ictionary. | 
|  | 391     early_call = parameter.is_optional and 'Default' not in parameter.extended_a
     ttributes and native_type != 'Dictionary' and not is_callback_interface | 
|  | 392     early_call_multi_line = False | 
|  | 393     early_call_statements = {} | 
|  | 394     if early_call: | 
|  | 395         # TODO | 
|  | 396         early_call_statements, early_call_includes = get_function_call_parameter
     (interface, function, parameter_index, for_main_world_suffix=for_main_world_suff
     ix) | 
|  | 397         includes += early_call_includes | 
|  | 398         early_call_multi_line = len([c for c in early_call_statements if c == '\
     n']) > 1 | 
|  | 399 | 
|  | 400     parameter_check_parameter = { | 
|  | 401         'index': parameter_index, | 
|  | 402         'name': parameter.name, | 
|  | 403         'type': parameter.data_type, | 
|  | 404         'early_call': early_call, | 
|  | 405         'early_call_statement_parameter': early_call_statements, | 
|  | 406         'early_call_multi_line': early_call_multi_line, | 
|  | 407         'is_callback_interface': is_callback_interface, | 
|  | 408         'is_optional': parameter.is_optional, | 
|  | 409         'is_variadic': parameter.is_variadic, | 
|  | 410         'is_index': is_index, | 
|  | 411         'is_wrapper_type': is_wrapper_type(parameter.data_type), | 
|  | 412         'clamp': parameter.extended_attributes.get('Clamp'), | 
|  | 413         'strict_type_checking': parameter.extended_attributes.get('StrictTypeChe
     cking'), | 
|  | 414         'enforce_range': 'EnforceRange' in parameter.extended_attributes, | 
|  | 415         'js_to_native_statement': js_to_native_statement, | 
|  | 416         'native_type': native_type, | 
|  | 417         'native_element_type': native_element_type, | 
|  | 418         'enum_validation_expression': enum_validation_expression, | 
|  | 419         'is_enum_type': is_enum_type(parameter.data_type), | 
|  | 420     } | 
|  | 421     return parameter_check_parameter, includes | 
| OLD | NEW | 
|---|