18abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)# Copyright (C) 2013 Google Inc. All rights reserved.
2323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)# coding=utf-8
38abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)#
48abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)# Redistribution and use in source and binary forms, with or without
58abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)# modification, are permitted provided that the following conditions are
68abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)# met:
78abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)#
88abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)#     * Redistributions of source code must retain the above copyright
98abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)# notice, this list of conditions and the following disclaimer.
108abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)#     * Redistributions in binary form must reproduce the above
118abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)# copyright notice, this list of conditions and the following disclaimer
128abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)# in the documentation and/or other materials provided with the
138abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)# distribution.
148abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)#     * Neither the name of Google Inc. nor the names of its
158abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)# contributors may be used to endorse or promote products derived from
168abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)# this software without specific prior written permission.
178abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)#
188abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
198abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
208abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
218abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
228abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
238abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
248abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
258abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
268abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
278abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
288abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
298abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)
309bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)"""Generate template values for an interface.
319bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)
32d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)Design doc: http://www.chromium.org/developers/design-documents/idl-compiler
339bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)"""
348abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)
35d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)from collections import defaultdict
36323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)import itertools
37323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)from operator import itemgetter
38d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
39197021e6b966cfb06891637935ef33fff06433d1Ben Murdochimport idl_definitions
40197021e6b966cfb06891637935ef33fff06433d1Ben Murdochfrom idl_definitions import IdlOperation
41d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)import idl_types
42d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)from idl_types import IdlType, inherits_interface
438abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)import v8_attributes
44f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)from v8_globals import includes
45f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)import v8_methods
4651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)import v8_types
476f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdochfrom v8_types import cpp_ptr_type, cpp_template_type
48f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)import v8_utilities
497242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccifrom v8_utilities import (capitalize, conditional_string, cpp_name, gc_type,
507242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                          has_extended_attribute_value, runtime_enabled_function_name,
517242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                          extended_attribute_value_as_list)
528abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)
538abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)
54d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)INTERFACE_H_INCLUDES = frozenset([
55e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    'bindings/core/v8/ScriptWrappable.h',
56197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    'bindings/core/v8/V8Binding.h',
57197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    'bindings/core/v8/V8DOMWrapper.h',
58197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    'bindings/core/v8/WrapperTypeInfo.h',
5910f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    'platform/heap/Handle.h',
608abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)])
61d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)INTERFACE_CPP_INCLUDES = frozenset([
62197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    'bindings/core/v8/ExceptionState.h',
63197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    'bindings/core/v8/V8DOMConfiguration.h',
64197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    'bindings/core/v8/V8HiddenValue.h',
65197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    'bindings/core/v8/V8ObjectConstructor.h',
668abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    'core/dom/ContextFeatures.h',
678abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    'core/dom/Document.h',
6876c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    'platform/RuntimeEnabledFeatures.h',
691e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    'platform/TraceEvent.h',
70d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    'wtf/GetPtr.h',
7109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    'wtf/RefPtr.h',
728abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)])
738abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)
748abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)
75197021e6b966cfb06891637935ef33fff06433d1Ben Murdochdef interface_context(interface):
76f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    includes.clear()
77f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    includes.update(INTERFACE_CPP_INCLUDES)
78d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    header_includes = set(INTERFACE_H_INCLUDES)
79a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
80a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    parent_interface = interface.parent
81a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    if parent_interface:
82d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        header_includes.update(v8_types.includes_for_interface(parent_interface))
8351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    extended_attributes = interface.extended_attributes
848abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)
8509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    is_audio_buffer = inherits_interface(interface.name, 'AudioBuffer')
8609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if is_audio_buffer:
8709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        includes.add('modules/webaudio/AudioBuffer.h')
8809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
8909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    is_document = inherits_interface(interface.name, 'Document')
9009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if is_document:
91197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        includes.update(['bindings/core/v8/ScriptController.h',
92e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)                         'bindings/core/v8/WindowProxy.h',
93d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                         'core/frame/LocalFrame.h'])
9409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
9507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    # [ActiveDOMObject]
9607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    is_active_dom_object = 'ActiveDOMObject' in extended_attributes
9707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
98a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    # [CheckSecurity]
9951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    is_check_security = 'CheckSecurity' in extended_attributes
10051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if is_check_security:
101197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        includes.add('bindings/core/v8/BindingSecurity.h')
102a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
10307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    # [DependentLifetime]
10407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    is_dependent_lifetime = 'DependentLifetime' in extended_attributes
10507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
1067242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    # [Iterable]
1077242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    iterator_method = None
1087242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if 'Iterable' in extended_attributes:
1097242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        iterator_operation = IdlOperation(interface.idl_name)
1107242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        iterator_operation.name = 'iterator'
1117242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        iterator_operation.idl_type = IdlType('Iterator')
1127242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        iterator_operation.extended_attributes['RaisesException'] = None
1137242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        iterator_operation.extended_attributes['CallWith'] = 'ScriptState'
1147242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        iterator_method = v8_methods.method_context(interface,
1157242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                                                    iterator_operation)
1167242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
117a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    # [MeasureAs]
118a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    is_measure_as = 'MeasureAs' in extended_attributes
119a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    if is_measure_as:
120a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        includes.add('core/frame/UseCounter.h')
121a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
12209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    # [SetWrapperReferenceFrom]
12309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    reachable_node_function = extended_attributes.get('SetWrapperReferenceFrom')
12409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if reachable_node_function:
125197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        includes.update(['bindings/core/v8/V8GCController.h',
12609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                         'core/dom/Element.h'])
12709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
12809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    # [SetWrapperReferenceTo]
12909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    set_wrapper_reference_to_list = [{
13009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        'name': argument.name,
131d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        # FIXME: properly should be:
132197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        # 'cpp_type': argument.idl_type.cpp_type_args(raw_type=True),
133d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        # (if type is non-wrapper type like NodeFilter, normally RefPtr)
134d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        # Raw pointers faster though, and NodeFilter hacky anyway.
135d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        'cpp_type': argument.idl_type.implemented_as + '*',
13609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        'idl_type': argument.idl_type,
137d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        'v8_type': v8_types.v8_type(argument.idl_type.name),
13809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    } for argument in extended_attributes.get('SetWrapperReferenceTo', [])]
13909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    for set_wrapper_reference_to in set_wrapper_reference_to_list:
140d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        set_wrapper_reference_to['idl_type'].add_includes_for_type()
141a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
1427242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    # [NotScriptWrappable]
1437242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    is_script_wrappable = 'NotScriptWrappable' not in extended_attributes
1447242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
145a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    # [SpecialWrapFor]
146a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    if 'SpecialWrapFor' in extended_attributes:
1477242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        special_wrap_for = extended_attribute_value_as_list(interface, 'SpecialWrapFor')
148a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    else:
149a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        special_wrap_for = []
150a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    for special_wrap_interface in special_wrap_for:
151d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        v8_types.add_includes_for_interface(special_wrap_interface)
152a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
15307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    # [Custom=Wrap], [SetWrapperReferenceFrom]
15407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    has_visit_dom_wrapper = (
15507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        has_extended_attribute_value(interface, 'Custom', 'VisitDOMWrapper') or
15607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        reachable_node_function or
15707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        set_wrapper_reference_to_list)
15807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
1596f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    this_gc_type = gc_type(interface)
1606f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch
1617242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    wrapper_class_id = ('NodeClassId' if inherits_interface(interface.name, 'Node') else 'ObjectClassId')
1627242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
163197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    context = {
16451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        'conditional_string': conditional_string(interface),  # [Conditional]
165a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        'cpp_class': cpp_name(interface),
1666f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch        'gc_type': this_gc_type,
1679e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        # FIXME: Remove 'EventTarget' special handling, http://crbug.com/383699
1689e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        'has_access_check_callbacks': (is_check_security and
1699e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)                                       interface.name != 'Window' and
1709e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)                                       interface.name != 'EventTarget'),
171a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        'has_custom_legacy_call_as_function': has_extended_attribute_value(interface, 'Custom', 'LegacyCallAsFunction'),  # [Custom=LegacyCallAsFunction]
172a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        'has_custom_to_v8': has_extended_attribute_value(interface, 'Custom', 'ToV8'),  # [Custom=ToV8]
173a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        'has_custom_wrap': has_extended_attribute_value(interface, 'Custom', 'Wrap'),  # [Custom=Wrap]
17407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        'has_visit_dom_wrapper': has_visit_dom_wrapper,
175a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        'header_includes': header_includes,
176f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        'interface_name': interface.name,
17707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        'is_active_dom_object': is_active_dom_object,
17809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        'is_audio_buffer': is_audio_buffer,
17951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        'is_check_security': is_check_security,
18007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        'is_dependent_lifetime': is_dependent_lifetime,
18109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        'is_document': is_document,
18209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        'is_event_target': inherits_interface(interface.name, 'EventTarget'),
18309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        'is_exception': interface.is_exception,
18409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        'is_node': inherits_interface(interface.name, 'Node'),
1857242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        'is_script_wrappable': is_script_wrappable,
1867242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        'iterator_method': iterator_method,
1877242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        'lifetime': 'Dependent'
1887242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            if (has_visit_dom_wrapper or
1897242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                is_active_dom_object or
1907242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                is_dependent_lifetime)
1917242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            else 'Independent',
192a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        'measure_as': v8_utilities.measure_as(interface),  # [MeasureAs]
193a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        'parent_interface': parent_interface,
1946f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch        'pass_cpp_type': cpp_template_type(
1956f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch            cpp_ptr_type('PassRefPtr', 'RawPtr', this_gc_type),
1966f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch            cpp_name(interface)),
19709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        'reachable_node_function': reachable_node_function,
198a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        'runtime_enabled_function': runtime_enabled_function_name(interface),  # [RuntimeEnabled]
19909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        'set_wrapper_reference_to_list': set_wrapper_reference_to_list,
200a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        'special_wrap_for': special_wrap_for,
201a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        'v8_class': v8_utilities.v8_class_name(interface),
2027242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        'wrapper_class_id': wrapper_class_id,
203f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    }
204f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)
20509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    # Constructors
206197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    constructors = [constructor_context(interface, constructor)
20709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                    for constructor in interface.constructors
20809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                    # FIXME: shouldn't put named constructors with constructors
20909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                    # (currently needed for Perl compatibility)
21009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                    # Handle named constructors separately
21109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                    if constructor.name == 'Constructor']
212d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    if len(constructors) > 1:
213197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        context['constructor_overloads'] = overloads_context(constructors)
21409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
21509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    # [CustomConstructor]
21609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    custom_constructors = [{  # Only needed for computing interface length
21709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        'number_of_required_arguments':
21809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            number_of_required_arguments(constructor),
21909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    } for constructor in interface.custom_constructors]
22009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
22109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    # [EventConstructor]
22209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    has_event_constructor = 'EventConstructor' in extended_attributes
22309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    any_type_attributes = [attribute for attribute in interface.attributes
224d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                           if attribute.idl_type.name == 'Any']
22509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if has_event_constructor:
226197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        includes.add('bindings/core/v8/Dictionary.h')
22709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        if any_type_attributes:
228197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            includes.add('bindings/core/v8/SerializedScriptValue.h')
22909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
23009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    # [NamedConstructor]
231197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    named_constructor = named_constructor_context(interface)
23209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
23309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (constructors or custom_constructors or has_event_constructor or
23409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        named_constructor):
235197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        includes.add('bindings/core/v8/V8ObjectConstructor.h')
23676c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        includes.add('core/frame/LocalDOMWindow.h')
23709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
238197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    context.update({
23909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        'any_type_attributes': any_type_attributes,
24009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        'constructors': constructors,
24109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        'has_custom_constructor': bool(custom_constructors),
24209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        'has_event_constructor': has_event_constructor,
24309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        'interface_length':
24409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            interface_length(interface, constructors + custom_constructors),
24509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        'is_constructor_raises_exception': extended_attributes.get('RaisesException') == 'Constructor',  # [RaisesException=Constructor]
24609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        'named_constructor': named_constructor,
24709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    })
24809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
2497242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    constants = [constant_context(constant) for constant in interface.constants]
2507242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
2517242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    special_getter_constants = []
2527242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    runtime_enabled_constants = []
2537242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    constant_configuration_constants = []
2547242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
2557242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    for constant in constants:
2567242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        if constant['measure_as'] or constant['deprecate_as']:
2577242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            special_getter_constants.append(constant)
2587242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            continue
2597242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        if constant['runtime_enabled_function']:
2607242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            runtime_enabled_constants.append(constant)
2617242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            continue
2627242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        constant_configuration_constants.append(constant)
2637242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
26409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    # Constants
265197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    context.update({
2667242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        'constant_configuration_constants': constant_configuration_constants,
2677242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        'constants': constants,
26851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        'do_not_check_constants': 'DoNotCheckConstants' in extended_attributes,
2697242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        'has_constant_configuration': any(
2707242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            not constant['runtime_enabled_function']
2717242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            for constant in constants),
2727242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        'runtime_enabled_constants': runtime_enabled_constants,
2737242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        'special_getter_constants': special_getter_constants,
274f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    })
275f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)
27609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    # Attributes
277197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    attributes = [v8_attributes.attribute_context(interface, attribute)
278f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)                  for attribute in interface.attributes]
279197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    context.update({
280f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        'attributes': attributes,
281c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        'has_accessors': any(attribute['is_expose_js_accessors'] and attribute['should_be_exposed_to_script'] for attribute in attributes),
28209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        'has_attribute_configuration': any(
28309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)             not (attribute['is_expose_js_accessors'] or
28409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                  attribute['is_static'] or
28509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                  attribute['runtime_enabled_function'] or
28609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                  attribute['per_context_enabled_function'])
287c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)             and attribute['should_be_exposed_to_script']
28809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)             for attribute in attributes),
289e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        'has_conditional_attributes': any(attribute['per_context_enabled_function'] or attribute['exposed_test'] for attribute in attributes),
29051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        'has_constructor_attributes': any(attribute['constructor_type'] for attribute in attributes),
291f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        'has_replaceable_attributes': any(attribute['is_replaceable'] for attribute in attributes),
292f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    })
293f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)
29409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    # Methods
295197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    methods = [v8_methods.method_context(interface, method)
29609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)               for method in interface.operations
29709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)               if method.name]  # Skip anonymous special operations (methods)
298197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    compute_method_overloads_context(methods)
299197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
300197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    # Stringifier
301197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if interface.stringifier:
302197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        stringifier = interface.stringifier
303e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        method = IdlOperation(interface.idl_name)
304197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        method.name = 'toString'
305197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        method.idl_type = IdlType('DOMString')
306197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        method.extended_attributes.update(stringifier.extended_attributes)
307197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        if stringifier.attribute:
308197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            method.extended_attributes['ImplementedAs'] = stringifier.attribute.name
309197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        elif stringifier.operation:
310197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            method.extended_attributes['ImplementedAs'] = stringifier.operation.name
311197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        methods.append(v8_methods.method_context(interface, method))
3125d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)
313e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    conditionally_enabled_methods = []
3145d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    custom_registration_methods = []
3155d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    method_configuration_methods = []
3165d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)
31751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    for method in methods:
3185d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        # Skip all but one method in each set of overloaded methods.
3195d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        if 'overload_index' in method and 'overloads' not in method:
3205d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            continue
3215d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)
3225d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        if 'overloads' in method:
3235d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            overloads = method['overloads']
3245d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            per_context_enabled_function = overloads['per_context_enabled_function_all']
325e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)            conditionally_exposed_function = overloads['exposed_test_all']
3265d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            runtime_enabled_function = overloads['runtime_enabled_function_all']
3275d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            has_custom_registration = overloads['has_custom_registration_all']
3285d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        else:
3295d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            per_context_enabled_function = method['per_context_enabled_function']
330e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)            conditionally_exposed_function = method['exposed_test']
3315d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            runtime_enabled_function = method['runtime_enabled_function']
3325d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            has_custom_registration = method['has_custom_registration']
3335d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)
334e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        if per_context_enabled_function or conditionally_exposed_function:
335e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)            conditionally_enabled_methods.append(method)
3365d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            continue
3375d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        if runtime_enabled_function or has_custom_registration:
3385d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            custom_registration_methods.append(method)
3395d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            continue
340c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        if method['should_be_exposed_to_script']:
341c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            method_configuration_methods.append(method)
34251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
3435d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    for method in methods:
344f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        # The value of the Function object’s “length” property is a Number
345f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        # determined as follows:
346f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        # 1. Let S be the effective overload set for regular operations (if the
347f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        # operation is a regular operation) or for static operations (if the
348f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        # operation is a static operation) with identifier id on interface I and
349f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        # with argument count 0.
350f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        # 2. Return the length of the shortest argument list of the entries in S.
351f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        # FIXME: This calculation doesn't take into account whether runtime
352f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        # enabled overloads are actually enabled, so length may be incorrect.
353f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        # E.g., [RuntimeEnabled=Foo] void f(); void f(long x);
354f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        # should have length 1 if Foo is not enabled, but length 0 if it is.
355f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        method['length'] = (method['overloads']['minarg'] if 'overloads' in method else
356f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)                            method['number_of_required_arguments'])
357f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
358197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    context.update({
359e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        'conditionally_enabled_methods': conditionally_enabled_methods,
3605d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        'custom_registration_methods': custom_registration_methods,
36151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        'has_origin_safe_method_setter': any(
36251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            method['is_check_security_for_frame'] and not method['is_read_only']
36351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            for method in methods),
364e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        'has_private_script': any(attribute['is_implemented_in_private_script'] for attribute in attributes) or
365e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)            any(method['is_implemented_in_private_script'] for method in methods),
3665d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        'method_configuration_methods': method_configuration_methods,
36751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        'methods': methods,
36851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    })
369f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)
370197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    context.update({
37109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        'indexed_property_getter': indexed_property_getter(interface),
37209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        'indexed_property_setter': indexed_property_setter(interface),
37309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        'indexed_property_deleter': indexed_property_deleter(interface),
37409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        'is_override_builtins': 'OverrideBuiltins' in extended_attributes,
37509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        'named_property_getter': named_property_getter(interface),
37609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        'named_property_setter': named_property_setter(interface),
37709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        'named_property_deleter': named_property_deleter(interface),
37809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    })
37909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
380197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return context
3818abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)
3828abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)
383f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)# [DeprecateAs], [Reflect], [RuntimeEnabled]
384197021e6b966cfb06891637935ef33fff06433d1Ben Murdochdef constant_context(constant):
38509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    extended_attributes = constant.extended_attributes
38609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return {
387a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        'cpp_class': extended_attributes.get('PartialInterfaceImplementedAs'),
3887242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        'deprecate_as': v8_utilities.deprecate_as(constant),  # [DeprecateAs]
389197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        'idl_type': constant.idl_type.name,
3907242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        'measure_as': v8_utilities.measure_as(constant),  # [MeasureAs]
3918abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        'name': constant.name,
3928abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        # FIXME: use 'reflected_name' as correct 'name'
39309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        'reflected_name': extended_attributes.get('Reflect', constant.name),
394a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        'runtime_enabled_function': runtime_enabled_function_name(constant),
3957242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        'value': constant.value,
3968abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    }
39751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
39851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
39909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)################################################################################
40009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)# Overloads
40109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)################################################################################
40209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
403197021e6b966cfb06891637935ef33fff06433d1Ben Murdochdef compute_method_overloads_context(methods):
4046f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    # Regular methods
405197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    compute_method_overloads_context_by_type([method for method in methods
406197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch                                              if not method['is_static']])
4076f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    # Static methods
408197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    compute_method_overloads_context_by_type([method for method in methods
409197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch                                              if method['is_static']])
4106f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch
4116f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch
412197021e6b966cfb06891637935ef33fff06433d1Ben Murdochdef compute_method_overloads_context_by_type(methods):
413197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    """Computes |method.overload*| template values.
4146f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch
4156f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    Called separately for static and non-static (regular) methods,
4166f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    as these are overloaded separately.
417d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    Modifies |method| in place for |method| in |methods|.
4186f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    Doesn't change the |methods| list itself (only the values, i.e. individual
4196f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    methods), so ok to treat these separately.
4206f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    """
421d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # Add overload information only to overloaded methods, so template code can
422d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # easily verify if a function is overloaded
423d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    for name, overloads in method_overloads_by_name(methods):
424d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        # Resolution function is generated after last overloaded function;
425d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        # package necessary information into |method.overloads| for that method.
426197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        overloads[-1]['overloads'] = overloads_context(overloads)
427d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        overloads[-1]['overloads']['name'] = name
428d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
429d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
430d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)def method_overloads_by_name(methods):
431d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    """Returns generator of overloaded methods by name: [name, [method]]"""
43251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    # Filter to only methods that are actually overloaded
433323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    method_counts = Counter(method['name'] for method in methods)
434323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    overloaded_method_names = set(name
435323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)                                  for name, count in method_counts.iteritems()
436323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)                                  if count > 1)
437323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    overloaded_methods = [method for method in methods
438323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)                          if method['name'] in overloaded_method_names]
439323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
440323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    # Group by name (generally will be defined together, but not necessarily)
441d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    return sort_and_groupby(overloaded_methods, itemgetter('name'))
44251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
443323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
444197021e6b966cfb06891637935ef33fff06433d1Ben Murdochdef overloads_context(overloads):
445d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    """Returns |overloads| template values for a single name.
446d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
447d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    Sets |method.overload_index| in place for |method| in |overloads|
448d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    and returns dict of overall overload template values.
449d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    """
450d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    assert len(overloads) > 1  # only apply to overloaded names
451d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    for index, method in enumerate(overloads, 1):
452d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        method['overload_index'] = index
453d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
454d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    effective_overloads_by_length = effective_overload_set_by_length(overloads)
455d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    lengths = [length for length, _ in effective_overloads_by_length]
4565d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    name = overloads[0].get('name', '<constructor>')
457d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
458f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    # Check and fail if all overloads with the shortest acceptable arguments
459f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    # list are runtime enabled, since we would otherwise set 'length' on the
460f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    # function object to an incorrect value when none of those overloads were
461f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    # actually enabled at runtime. The exception is if all overloads are
462f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    # controlled by the same runtime enabled feature, in which case there would
463f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    # be no function object at all if it is not enabled.
464f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    shortest_overloads = effective_overloads_by_length[0][1]
465f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    if (all(method.get('runtime_enabled_function')
466f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)            for method, _, _ in shortest_overloads) and
467f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        not common_value(overloads, 'runtime_enabled_function')):
4685d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        raise ValueError('Function.length of %s depends on runtime enabled features' % name)
4695d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)
4705d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    # Check and fail if overloads disagree on any of the extended attributes
4715d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    # that affect how the method should be registered.
4725d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    # Skip the check for overloaded constructors, since they don't support any
4735d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    # of the extended attributes in question.
4745d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    if not overloads[0].get('is_constructor'):
4755d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        overload_extended_attributes = [
4765d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            method['custom_registration_extended_attributes']
4775d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            for method in overloads]
4785d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        for extended_attribute in v8_methods.CUSTOM_REGISTRATION_EXTENDED_ATTRIBUTES:
4795d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            if common_key(overload_extended_attributes, extended_attribute) is None:
4805d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)                raise ValueError('Overloads of %s have conflicting extended attribute %s'
4815d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)                                 % (name, extended_attribute))
482f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
4837242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    # Check and fail if overloads disagree about whether the return type
4847242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    # is a Promise or not.
4857242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    promise_overload_count = sum(1 for method in overloads if method.get('idl_type') == 'Promise')
4867242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if promise_overload_count not in (0, len(overloads)):
4877242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        raise ValueError('Overloads of %s have conflicting Promise/non-Promise types'
4887242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                         % (name))
4897242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
490d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    return {
491d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        'deprecate_all_as': common_value(overloads, 'deprecate_as'),  # [DeprecateAs]
492e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        'exposed_test_all': common_value(overloads, 'exposed_test'),  # [Exposed]
493e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        'has_custom_registration_all': common_value(overloads, 'has_custom_registration'),
494d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        'length_tests_methods': length_tests_methods(effective_overloads_by_length),
495d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        # 1. Let maxarg be the length of the longest type list of the
496d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        # entries in S.
497d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        'maxarg': lengths[-1],
498d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        'measure_all_as': common_value(overloads, 'measure_as'),  # [MeasureAs]
499e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        'minarg': lengths[0],
5005d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        'per_context_enabled_function_all': common_value(overloads, 'per_context_enabled_function'),  # [PerContextEnabled]
5015d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        'runtime_enabled_function_all': common_value(overloads, 'runtime_enabled_function'),  # [RuntimeEnabled]
502d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        'valid_arities': lengths
503d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            # Only need to report valid arities if there is a gap in the
504d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            # sequence of possible lengths, otherwise invalid length means
505d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            # "not enough arguments".
506d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            if lengths[-1] - lengths[0] != len(lengths) - 1 else None,
507d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    }
50851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
50951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
510323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)def effective_overload_set(F):
511323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    """Returns the effective overload set of an overloaded function.
512323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
513323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    An effective overload set is the set of overloaded functions + signatures
514323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    (type list of arguments, with optional and variadic arguments included or
515323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    not), and is used in the overload resolution algorithm.
516323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
517323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    For example, given input [f1(optional long x), f2(DOMString s)], the output
518323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    is informally [f1(), f1(long), f2(DOMString)], and formally
519323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    [(f1, [], []), (f1, [long], [optional]), (f2, [DOMString], [required])].
520323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
521323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    Currently the optionality list is a list of |is_optional| booleans (True
522323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    means optional, False means required); to support variadics this needs to
523323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    be tri-valued as required, optional, or variadic.
524323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
525323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    Formally:
526323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    An effective overload set represents the allowable invocations for a
527323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    particular operation, constructor (specified with [Constructor] or
528323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    [NamedConstructor]), legacy caller or callback function.
529323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
530323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    An additional argument N (argument count) is needed when overloading
531323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    variadics, but we don't use that currently.
532323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
533323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    Spec: http://heycam.github.io/webidl/#dfn-effective-overload-set
534323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
535323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    Formally the input and output lists are sets, but methods are stored
536323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    internally as dicts, which can't be stored in a set because they are not
537323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    hashable, so we use lists instead.
538323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
539323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    Arguments:
540323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        F: list of overloads for a given callable name.
541323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
542323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    Returns:
543323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        S: list of tuples of the form (callable, type list, optionality list).
544323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    """
545323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    # Code closely follows the algorithm in the spec, for clarity and
546323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    # correctness, and hence is not very Pythonic.
547323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
548323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    # 1. Initialize S to ∅.
549323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    # (We use a list because we can't use a set, as noted above.)
550323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    S = []
551323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
552323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    # 2. Let F be a set with elements as follows, according to the kind of
553323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    # effective overload set:
554323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    # (Passed as argument, nothing to do.)
555323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
556323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    # 3. & 4. (maxarg, m) are only needed for variadics, not used.
557323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
558323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    # 5. For each operation, extended attribute or callback function X in F:
559323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    for X in F:  # X is the "callable", F is the overloads.
560323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        arguments = X['arguments']
561323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        # 1. Let n be the number of arguments X is declared to take.
562323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        n = len(arguments)
563323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        # 2. Let t0..n−1 be a list of types, where ti is the type of X’s
564323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        # argument at index i.
565323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        # (“type list”)
566323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        t = tuple(argument['idl_type_object'] for argument in arguments)
567323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        # 3. Let o0..n−1 be a list of optionality values, where oi is “variadic”
568323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        # if X’s argument at index i is a final, variadic argument, “optional”
569323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        # if the argument is optional, and “required” otherwise.
570323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        # (“optionality list”)
571323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        # (We’re just using a boolean for optional vs. required.)
572323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        o = tuple(argument['is_optional'] for argument in arguments)
573323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        # 4. Add to S the tuple <X, t0..n−1, o0..n−1>.
574323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        S.append((X, t, o))
575323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        # 5. If X is declared to be variadic, then:
576323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        # (Not used, so not implemented.)
577323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        # 6. Initialize i to n−1.
578323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        i = n - 1
579323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        # 7. While i ≥ 0:
580323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        # Spec bug (fencepost error); should be “While i > 0:”
581323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        # https://www.w3.org/Bugs/Public/show_bug.cgi?id=25590
582323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        while i > 0:
583323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)            # 1. If argument i of X is not optional, then break this loop.
584323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)            if not o[i]:
585323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)                break
586323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)            # 2. Otherwise, add to S the tuple <X, t0..i−1, o0..i−1>.
587323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)            S.append((X, t[:i], o[:i]))
588323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)            # 3. Set i to i−1.
589323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)            i = i - 1
590323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        # 8. If n > 0 and all arguments of X are optional, then add to S the
591323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        # tuple <X, (), ()> (where “()” represents the empty list).
592323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        if n > 0 and all(oi for oi in o):
593323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)            S.append((X, [], []))
594323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    # 6. The effective overload set is S.
595323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    return S
596323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
597323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
598323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)def effective_overload_set_by_length(overloads):
599323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    def type_list_length(entry):
600323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        # Entries in the effective overload set are 3-tuples:
601323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        # (callable, type list, optionality list)
602323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        return len(entry[1])
603323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
604323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    effective_overloads = effective_overload_set(overloads)
605d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    return list(sort_and_groupby(effective_overloads, type_list_length))
606323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
607323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
608323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)def distinguishing_argument_index(entries):
609323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    """Returns the distinguishing argument index for a sequence of entries.
610323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
611323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    Entries are elements of the effective overload set with the same number
612323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    of arguments (formally, same type list length), each a 3-tuple of the form
613323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    (callable, type list, optionality list).
614323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
615323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    Spec: http://heycam.github.io/webidl/#dfn-distinguishing-argument-index
616323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
617323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    If there is more than one entry in an effective overload set that has a
618323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    given type list length, then for those entries there must be an index i
619323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    such that for each pair of entries the types at index i are
620323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    distinguishable.
621323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    The lowest such index is termed the distinguishing argument index for the
622323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    entries of the effective overload set with the given type list length.
623323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    """
624d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # Only applicable “If there is more than one entry”
625d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    assert len(entries) > 1
626323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    type_lists = [tuple(idl_type.name for idl_type in entry[1])
627323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)                  for entry in entries]
628323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    type_list_length = len(type_lists[0])
629d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # Only applicable for entries that “[have] a given type list length”
630323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    assert all(len(type_list) == type_list_length for type_list in type_lists)
631d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    name = entries[0][0].get('name', 'Constructor')  # for error reporting
632323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
633323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    # The spec defines the distinguishing argument index by conditions it must
634323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    # satisfy, but does not give an algorithm.
635323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    #
636323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    # We compute the distinguishing argument index by first computing the
637323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    # minimum index where not all types are the same, and then checking that
638323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    # all types in this position are distinguishable (and the optionality lists
639323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    # up to this point are identical), since "minimum index where not all types
640323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    # are the same" is a *necessary* condition, and more direct to check than
641323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    # distinguishability.
642323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    types_by_index = (set(types) for types in zip(*type_lists))
643323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    try:
644323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        # “In addition, for each index j, where j is less than the
645323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        #  distinguishing argument index for a given type list length, the types
646323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        #  at index j in all of the entries’ type lists must be the same”
647323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        index = next(i for i, types in enumerate(types_by_index)
648323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)                     if len(types) > 1)
649323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    except StopIteration:
650323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        raise ValueError('No distinguishing index found for %s, length %s:\n'
651323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)                         'All entries have the same type list:\n'
652323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)                         '%s' % (name, type_list_length, type_lists[0]))
653323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    # Check optionality
654323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    # “and the booleans in the corresponding list indicating argument
655323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    #  optionality must be the same.”
656323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    # FIXME: spec typo: optionality value is no longer a boolean
657323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    # https://www.w3.org/Bugs/Public/show_bug.cgi?id=25628
658323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    initial_optionality_lists = set(entry[2][:index] for entry in entries)
659323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if len(initial_optionality_lists) > 1:
660323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        raise ValueError(
661323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)            'Invalid optionality lists for %s, length %s:\n'
662323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)            'Optionality lists differ below distinguishing argument index %s:\n'
663323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)            '%s'
664323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)            % (name, type_list_length, index, set(initial_optionality_lists)))
665323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
666d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # Check distinguishability
667d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # http://heycam.github.io/webidl/#dfn-distinguishable
668d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # Use names to check for distinct types, since objects are distinct
669d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # FIXME: check distinguishability more precisely, for validation
670d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    distinguishing_argument_type_names = [type_list[index]
671d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)                                          for type_list in type_lists]
672d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    if (len(set(distinguishing_argument_type_names)) !=
673d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        len(distinguishing_argument_type_names)):
674d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        raise ValueError('Types in distinguishing argument are not distinct:\n'
675d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)                         '%s' % distinguishing_argument_type_names)
676323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
677323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    return index
678323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
679323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
680d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)def length_tests_methods(effective_overloads_by_length):
681d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    """Returns sorted list of resolution tests and associated methods, by length.
682d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
683d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    This builds the main data structure for the overload resolution loop.
684d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    For a given argument length, bindings test argument at distinguishing
685d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    argument index, in order given by spec: if it is compatible with
686d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    (optionality or) type required by an overloaded method, resolve to that
687d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    method.
688d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
689d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    Returns:
690d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        [(length, [(test, method)])]
691d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    """
692d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    return [(length, list(resolution_tests_methods(effective_overloads)))
693d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            for length, effective_overloads in effective_overloads_by_length]
694d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
695d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
696d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)def resolution_tests_methods(effective_overloads):
697d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    """Yields resolution test and associated method, in resolution order, for effective overloads of a given length.
698d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
699d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    This is the heart of the resolution algorithm.
700d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    http://heycam.github.io/webidl/#dfn-overload-resolution-algorithm
70109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
702d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    Note that a given method can be listed multiple times, with different tests!
703d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    This is to handle implicit type conversion.
704d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
705d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    Returns:
706d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        [(test, method)]
707d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    """
708d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    methods = [effective_overload[0]
709d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)               for effective_overload in effective_overloads]
710d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    if len(methods) == 1:
711d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        # If only one method with a given length, no test needed
712d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        yield 'true', methods[0]
713d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        return
714d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
715d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # 6. If there is more than one entry in S, then set d to be the
716d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # distinguishing argument index for the entries of S.
717d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    index = distinguishing_argument_index(effective_overloads)
718d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # (7-9 are for handling |undefined| values for optional arguments before
719d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # the distinguishing argument (as “missing”), so you can specify only some
720d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # optional arguments. We don’t support this, so we skip these steps.)
721d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # 10. If i = d, then:
722d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # (d is the distinguishing argument index)
723d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # 1. Let V be argi.
724d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    #     Note: This is the argument that will be used to resolve which
725d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    #           overload is selected.
72651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    cpp_value = 'info[%s]' % index
727d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
728d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # Extract argument and IDL type to simplify accessing these in each loop.
729d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    arguments = [method['arguments'][index] for method in methods]
730d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    arguments_methods = zip(arguments, methods)
731d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    idl_types = [argument['idl_type_object'] for argument in arguments]
732d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    idl_types_methods = zip(idl_types, methods)
733d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
734d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # We can’t do a single loop through all methods or simply sort them, because
735d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # a method may be listed in multiple steps of the resolution algorithm, and
736d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # which test to apply differs depending on the step.
737d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    #
738d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # Instead, we need to go through all methods at each step, either finding
739d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # first match (if only one test is allowed) or filtering to matches (if
740d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # multiple tests are allowed), and generating an appropriate tests.
741d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
742d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # 2. If V is undefined, and there is an entry in S whose list of
743d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # optionality values has “optional” at index i, then remove from S all
744d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # other entries.
745d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    try:
746d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        method = next(method for argument, method in arguments_methods
747d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)                      if argument['is_optional'])
748d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        test = '%s->IsUndefined()' % cpp_value
749d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        yield test, method
750d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    except StopIteration:
751d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        pass
752d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
753d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # 3. Otherwise: if V is null or undefined, and there is an entry in S that
754d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # has one of the following types at position i of its type list,
755d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # • a nullable type
756d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    try:
757d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        method = next(method for idl_type, method in idl_types_methods
758d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)                      if idl_type.is_nullable)
759d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        test = 'isUndefinedOrNull(%s)' % cpp_value
760d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        yield test, method
761d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    except StopIteration:
762d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        pass
763d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
764d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # 4. Otherwise: if V is a platform object – but not a platform array
765d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # object – and there is an entry in S that has one of the following
766d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # types at position i of its type list,
767d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # • an interface type that V implements
768d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # (Unlike most of these tests, this can return multiple methods, since we
769d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    #  test if it implements an interface. Thus we need a for loop, not a next.)
770d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # (We distinguish wrapper types from built-in interface types.)
771d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    for idl_type, method in ((idl_type, method)
772d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)                             for idl_type, method in idl_types_methods
773d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)                             if idl_type.is_wrapper_type):
774197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        test = 'V8{idl_type}::hasInstance({cpp_value}, info.GetIsolate())'.format(idl_type=idl_type.base_type, cpp_value=cpp_value)
775d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        yield test, method
776d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
777d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # 8. Otherwise: if V is any kind of object except for a native Date object,
778d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # a native RegExp object, and there is an entry in S that has one of the
779d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # following types at position i of its type list,
780d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # • an array type
781d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # • a sequence type
782d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # ...
783d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # • a dictionary
7847242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    #
7857242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    # FIXME:
7867242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    # We don't strictly follow the algorithm here. The algorithm says "remove
7877242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    # all other entries" if there is "one entry" matching, but we yield all
7887242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    # entries to support following constructors:
7897242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    # [constructor(sequence<DOMString> arg), constructor(Dictionary arg)]
7907242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    # interface I { ... }
7917242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    # (Need to check array types before objects because an array is an object)
7927242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    for idl_type, method in idl_types_methods:
793197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        if idl_type.native_array_element_type:
794d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            # (We test for Array instead of generic Object to type-check.)
795d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            # FIXME: test for Object during resolution, then have type check for
796d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            # Array in overloaded method: http://crbug.com/262383
7977242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            yield '%s->IsArray()' % cpp_value, method
7987242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    for idl_type, method in idl_types_methods:
7997242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        if idl_type.is_dictionary or idl_type.name == 'Dictionary':
800d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            # FIXME: should be '{1}->IsObject() && !{1}->IsDate() && !{1}->IsRegExp()'.format(cpp_value)
801d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            # FIXME: the IsDate and IsRegExp checks can be skipped if we've
802d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            # already generated tests for them.
8037242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            yield '%s->IsObject()' % cpp_value, method
804d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
805d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # (Check for exact type matches before performing automatic type conversion;
806d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # only needed if distinguishing between primitive types.)
807d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    if len([idl_type.is_primitive_type for idl_type in idl_types]) > 1:
808d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        # (Only needed if match in step 11, otherwise redundant.)
809197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        if any(idl_type.is_string_type or idl_type.is_enum
810d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)               for idl_type in idl_types):
811d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            # 10. Otherwise: if V is a Number value, and there is an entry in S
812d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            # that has one of the following types at position i of its type
813d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            # list,
814d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            # • a numeric type
815d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            try:
816d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)                method = next(method for idl_type, method in idl_types_methods
817d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)                              if idl_type.is_numeric_type)
818d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)                test = '%s->IsNumber()' % cpp_value
819d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)                yield test, method
820d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            except StopIteration:
821d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)                pass
822d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
823d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # (Perform automatic type conversion, in order. If any of these match,
8245d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    # that’s the end, and no other tests are needed.) To keep this code simple,
8255d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    # we rely on the C++ compiler's dead code elimination to deal with the
8265d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    # redundancy if both cases below trigger.
827d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
828d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # 11. Otherwise: if there is an entry in S that has one of the following
829d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # types at position i of its type list,
830d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # • DOMString
831197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    # • ByteString
832197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    # • ScalarValueString [a DOMString typedef, per definition.]
833d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # • an enumeration type
834d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    try:
835d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        method = next(method for idl_type, method in idl_types_methods
836197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch                      if idl_type.is_string_type or idl_type.is_enum)
837d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        yield 'true', method
838d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    except StopIteration:
839d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        pass
840d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
841d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # 12. Otherwise: if there is an entry in S that has one of the following
842d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # types at position i of its type list,
843d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    # • a numeric type
844d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    try:
845d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        method = next(method for idl_type, method in idl_types_methods
846d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)                      if idl_type.is_numeric_type)
847d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        yield 'true', method
848d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    except StopIteration:
849d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        pass
850a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
851a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
85209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)################################################################################
853323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)# Utility functions
854323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)################################################################################
855323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
856323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)def Counter(iterable):
857323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    # Once using Python 2.7, using collections.Counter
858323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    counter = defaultdict(lambda: 0)
859323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    for item in iterable:
860323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        counter[item] += 1
861323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    return counter
862323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
863323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
8645d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)def common(dicts, f):
8655d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    """Returns common result of f across an iterable of dicts, or None.
866323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
8675d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    Call f for each dict and return its result if the same across all dicts.
868323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    """
8695d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    values = (f(d) for d in dicts)
870323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    first_value = next(values)
871323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    if all(value == first_value for value in values):
872323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        return first_value
873323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    return None
874323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
875323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
8765d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)def common_key(dicts, key):
8775d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    """Returns common presence of a key across an iterable of dicts, or None.
8785d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)
8795d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    True if all dicts have the key, False if none of the dicts have the key,
8805d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    and None if some but not all dicts have the key.
8815d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    """
8825d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    return common(dicts, lambda d: key in d)
8835d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)
8845d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)
8855d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)def common_value(dicts, key):
8865d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    """Returns common value of a key across an iterable of dicts, or None.
8875d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)
8885d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    Auxiliary function for overloads, so can consolidate an extended attribute
8895d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    that appears with the same value on all items in an overload set.
8905d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    """
8915d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    return common(dicts, lambda d: d.get(key))
8925d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)
8935d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)
894323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)def sort_and_groupby(l, key=None):
895d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    """Returns a generator of (key, list), sorting and grouping list by key."""
896323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)    l.sort(key=key)
897d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    return ((k, list(g)) for k, g in itertools.groupby(l, key))
898323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
899323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
900323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)################################################################################
90109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)# Constructors
90209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)################################################################################
90309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
90409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)# [Constructor]
905197021e6b966cfb06891637935ef33fff06433d1Ben Murdochdef constructor_context(interface, constructor):
906197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    # [RaisesException=Constructor]
907197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    is_constructor_raises_exception = \
908197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        interface.extended_attributes.get('RaisesException') == 'Constructor'
909197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
91009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return {
911197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        'arguments': [v8_methods.argument_context(interface, constructor, argument, index)
91209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                      for index, argument in enumerate(constructor.arguments)],
9136f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch        'cpp_type': cpp_template_type(
9146f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch            cpp_ptr_type('RefPtr', 'RawPtr', gc_type(interface)),
9156f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch            cpp_name(interface)),
9165d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        'cpp_value': v8_methods.cpp_value(
9175d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            interface, constructor, len(constructor.arguments)),
91809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        'has_exception_state':
919197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            is_constructor_raises_exception or
92009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            any(argument for argument in constructor.arguments
921d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                if argument.idl_type.name == 'SerializedScriptValue' or
9227242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                   argument.idl_type.v8_conversion_needs_exception_state),
923197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        'is_call_with_document':
924197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            # [ConstructorCallWith=Document]
925197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            has_extended_attribute_value(interface,
926197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch                'ConstructorCallWith', 'Document'),
927197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        'is_call_with_execution_context':
928197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            # [ConstructorCallWith=ExecutionContext]
929197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            has_extended_attribute_value(interface,
930197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch                'ConstructorCallWith', 'ExecutionContext'),
93109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        'is_constructor': True,
9326f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch        'is_named_constructor': False,
933197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        'is_raises_exception': is_constructor_raises_exception,
93409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        'number_of_required_arguments':
93509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            number_of_required_arguments(constructor),
93609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
93709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
93809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
93909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)# [NamedConstructor]
940197021e6b966cfb06891637935ef33fff06433d1Ben Murdochdef named_constructor_context(interface):
94109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    extended_attributes = interface.extended_attributes
94209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if 'NamedConstructor' not in extended_attributes:
94309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return None
94409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    # FIXME: parser should return named constructor separately;
94509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    # included in constructors (and only name stored in extended attribute)
94609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    # for Perl compatibility
9475d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    idl_constructor = interface.constructors[-1]
9485d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    assert idl_constructor.name == 'NamedConstructor'
949197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    context = constructor_context(interface, idl_constructor)
950197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    context.update({
9516f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch        'name': extended_attributes['NamedConstructor'],
9526f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch        'is_named_constructor': True,
9536f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch    })
954197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return context
95509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
95609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
95709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)def number_of_required_arguments(constructor):
95809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return len([argument for argument in constructor.arguments
95909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                if not argument.is_optional])
96009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
96109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
96209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)def interface_length(interface, constructors):
96309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    # Docs: http://heycam.github.io/webidl/#es-interface-call
96409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if 'EventConstructor' in interface.extended_attributes:
96509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return 1
96609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if not constructors:
96709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return 0
96809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return min(constructor['number_of_required_arguments']
96909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)               for constructor in constructors)
97009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
97109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
97209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)################################################################################
97309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)# Special operations (methods)
97409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)# http://heycam.github.io/webidl/#idl-special-operations
97509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)################################################################################
97609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
97709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)def property_getter(getter, cpp_arguments):
97809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    def is_null_expression(idl_type):
979d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if idl_type.is_union_type:
980e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)            notnull = ' || '.join([
981e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)                    member_argument['null_check_value']
982e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)                    for member_argument in idl_type.union_arguments])
983e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)            return '!(%s)' % notnull
984d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if idl_type.name == 'String':
98509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            return 'result.isNull()'
986d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if idl_type.is_interface_type:
98709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            return '!result'
98809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return ''
98909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
99009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    idl_type = getter.idl_type
99109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    extended_attributes = getter.extended_attributes
99209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    is_raises_exception = 'RaisesException' in extended_attributes
99309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
99409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    # FIXME: make more generic, so can use v8_methods.cpp_value
99543e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)    cpp_method_name = 'impl->%s' % cpp_name(getter)
99609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
99709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if is_raises_exception:
99809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        cpp_arguments.append('exceptionState')
999d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    union_arguments = idl_type.union_arguments
1000d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if union_arguments:
1001e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        cpp_arguments.extend([member_argument['cpp_value']
1002e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)                              for member_argument in union_arguments])
100309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
100409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    cpp_value = '%s(%s)' % (cpp_method_name, ', '.join(cpp_arguments))
100509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
100609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return {
1007d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        'cpp_type': idl_type.cpp_type,
100809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        'cpp_value': cpp_value,
100909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        'is_custom':
101009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            'Custom' in extended_attributes and
101109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            (not extended_attributes['Custom'] or
101209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)             has_extended_attribute_value(getter, 'Custom', 'PropertyGetter')),
101309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        'is_custom_property_enumerator': has_extended_attribute_value(
101409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            getter, 'Custom', 'PropertyEnumerator'),
101509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        'is_custom_property_query': has_extended_attribute_value(
101609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            getter, 'Custom', 'PropertyQuery'),
101709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        'is_enumerable': 'NotEnumerable' not in extended_attributes,
101809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        'is_null_expression': is_null_expression(idl_type),
101909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        'is_raises_exception': is_raises_exception,
102009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        'name': cpp_name(getter),
1021d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        'union_arguments': union_arguments,
102243e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)        'v8_set_return_value': idl_type.v8_set_return_value('result', extended_attributes=extended_attributes, script_wrappable='impl', release=idl_type.release),
102309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
102409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
102509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
102609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)def property_setter(setter):
102709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    idl_type = setter.arguments[1].idl_type
102809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    extended_attributes = setter.extended_attributes
102909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    is_raises_exception = 'RaisesException' in extended_attributes
103009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return {
1031f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu        'has_type_checking_interface':
1032f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu            has_extended_attribute_value(setter, 'TypeChecking', 'Interface') and
1033d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            idl_type.is_wrapper_type,
1034d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        'idl_type': idl_type.base_type,
103509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        'is_custom': 'Custom' in extended_attributes,
10367242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        'has_exception_state': (is_raises_exception or
10377242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                                idl_type.v8_conversion_needs_exception_state),
103809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        'is_raises_exception': is_raises_exception,
103909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        'name': cpp_name(setter),
1040d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        'v8_value_to_local_cpp_value': idl_type.v8_value_to_local_cpp_value(
104107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch            extended_attributes, 'v8Value', 'propertyValue'),
104209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
104309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
104409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
104509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)def property_deleter(deleter):
104609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    idl_type = deleter.idl_type
1047d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if str(idl_type) != 'boolean':
104809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        raise Exception(
104909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            'Only deleters with boolean type are allowed, but type is "%s"' %
105009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            idl_type)
105109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    extended_attributes = deleter.extended_attributes
105209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return {
105309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        'is_custom': 'Custom' in extended_attributes,
105409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        'is_raises_exception': 'RaisesException' in extended_attributes,
105509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        'name': cpp_name(deleter),
105609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
105709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
105809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
105909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)################################################################################
106009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)# Indexed properties
106109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)# http://heycam.github.io/webidl/#idl-indexed-properties
106209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)################################################################################
106309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
106409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)def indexed_property_getter(interface):
106509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    try:
106609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        # Find indexed property getter, if present; has form:
106709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        # getter TYPE [OPTIONAL_IDENTIFIER](unsigned long ARG1)
106809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        getter = next(
106909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            method
107009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            for method in interface.operations
107109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            if ('getter' in method.specials and
107209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                len(method.arguments) == 1 and
1073d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                str(method.arguments[0].idl_type) == 'unsigned long'))
107409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    except StopIteration:
107509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return None
107609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
107709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return property_getter(getter, ['index'])
107809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
107909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
108009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)def indexed_property_setter(interface):
108109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    try:
108209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        # Find indexed property setter, if present; has form:
108309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        # setter RETURN_TYPE [OPTIONAL_IDENTIFIER](unsigned long ARG1, ARG_TYPE ARG2)
108409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        setter = next(
108509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            method
108609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            for method in interface.operations
108709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            if ('setter' in method.specials and
108809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                len(method.arguments) == 2 and
1089d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                str(method.arguments[0].idl_type) == 'unsigned long'))
109009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    except StopIteration:
109109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return None
109209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
109309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return property_setter(setter)
109409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
109509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
109609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)def indexed_property_deleter(interface):
109709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    try:
109809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        # Find indexed property deleter, if present; has form:
109909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        # deleter TYPE [OPTIONAL_IDENTIFIER](unsigned long ARG)
110009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        deleter = next(
110109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            method
110209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            for method in interface.operations
110309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            if ('deleter' in method.specials and
110409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                len(method.arguments) == 1 and
1105d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                str(method.arguments[0].idl_type) == 'unsigned long'))
110609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    except StopIteration:
110709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return None
110809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
110909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return property_deleter(deleter)
111009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
111109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
111209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)################################################################################
111309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)# Named properties
111409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)# http://heycam.github.io/webidl/#idl-named-properties
111509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)################################################################################
111609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
111709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)def named_property_getter(interface):
111809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    try:
111909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        # Find named property getter, if present; has form:
112009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        # getter TYPE [OPTIONAL_IDENTIFIER](DOMString ARG1)
112109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        getter = next(
112209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            method
112309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            for method in interface.operations
112409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            if ('getter' in method.specials and
112509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                len(method.arguments) == 1 and
1126d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                str(method.arguments[0].idl_type) == 'DOMString'))
112709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    except StopIteration:
112809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return None
112909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
113009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    getter.name = getter.name or 'anonymousNamedGetter'
113109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return property_getter(getter, ['propertyName'])
113209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
113309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
113409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)def named_property_setter(interface):
113509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    try:
113609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        # Find named property setter, if present; has form:
113709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        # setter RETURN_TYPE [OPTIONAL_IDENTIFIER](DOMString ARG1, ARG_TYPE ARG2)
113809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        setter = next(
113909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            method
114009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            for method in interface.operations
114109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            if ('setter' in method.specials and
114209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                len(method.arguments) == 2 and
1143d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                str(method.arguments[0].idl_type) == 'DOMString'))
114409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    except StopIteration:
114509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return None
114609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
114709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return property_setter(setter)
114809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
114909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
115009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)def named_property_deleter(interface):
115109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    try:
115209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        # Find named property deleter, if present; has form:
115309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        # deleter TYPE [OPTIONAL_IDENTIFIER](DOMString ARG)
115409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        deleter = next(
115509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            method
115609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            for method in interface.operations
115709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            if ('deleter' in method.specials and
115809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                len(method.arguments) == 1 and
1159d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                str(method.arguments[0].idl_type) == 'DOMString'))
116009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    except StopIteration:
116109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return None
116209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
116309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return property_deleter(deleter)
1164