Chromium Code Reviews| Index: Source/bindings/scripts/v8_interface.py |
| diff --git a/Source/bindings/scripts/v8_interface.py b/Source/bindings/scripts/v8_interface.py |
| index 9cb32a59af27c5984346bf23bf7c82a820cc6830..50ec590121f175f13ab09dd88e9a36af81877a68 100644 |
| --- a/Source/bindings/scripts/v8_interface.py |
| +++ b/Source/bindings/scripts/v8_interface.py |
| @@ -77,9 +77,22 @@ def interface_context(interface): |
| includes.update(INTERFACE_CPP_INCLUDES) |
| header_includes = set(INTERFACE_H_INCLUDES) |
| - parent_interface = interface.parent |
| - if parent_interface: |
| - header_includes.update(v8_types.includes_for_interface(parent_interface)) |
| + if interface.is_partial: |
| + # A partial interface definition cannot specify that the interface |
| + # inherits from another interface. Inheritance must be specified on |
| + # the original interface definition. |
| + parent_interface = None |
| + is_document = False |
| + is_event_target = False |
| + # partial interface needs the definition of its original interface. |
| + includes.add('bindings/core/v8/V8%s.h' % interface.name) |
| + else: |
| + parent_interface = interface.parent |
| + if parent_interface: |
| + header_includes.update(v8_types.includes_for_interface(parent_interface)) |
| + is_document = inherits_interface(interface.name, 'Document') |
| + is_event_target = inherits_interface(interface.name, 'EventTarget') |
| + |
| extended_attributes = interface.extended_attributes |
| # [ActiveDOMObject] |
| @@ -95,7 +108,11 @@ def interface_context(interface): |
| # [Iterable] |
| iterator_method = None |
| - if 'Iterable' in extended_attributes: |
| + # FIXME: support Iterable in partial interfaces. However, we don't |
| + # need to support iterator overloads between interface and |
| + # partial interface definitions. |
| + # http://heycam.github.io/webidl/#idl-overloading |
| + if 'Iterable' in extended_attributes and not interface.is_partial: |
| iterator_operation = IdlOperation(interface.idl_name) |
| iterator_operation.name = 'iterator' |
| iterator_operation.idl_type = IdlType('Iterator') |
| @@ -142,9 +159,14 @@ def interface_context(interface): |
| wrapper_class_id = ('NodeClassId' if inherits_interface(interface.name, 'Node') else 'ObjectClassId') |
| + v8_class_name = v8_utilities.v8_class_name(interface) |
| + cpp_class_name = cpp_name(interface) |
| + |
| context = { |
| + 'actual_cpp_class': cpp_class_name + 'Partial' if interface.is_partial else cpp_class_name, |
| + 'actual_v8_class': v8_class_name + 'Partial' if interface.is_partial else v8_class_name, |
|
haraken
2014/10/16 04:24:08
"actual_" wouldn't be a good name...
I don't have
tasak
2014/10/17 07:38:18
actual_ => _or_partial
|
| 'conditional_string': conditional_string(interface), # [Conditional] |
| - 'cpp_class': cpp_name(interface), |
| + 'cpp_class': cpp_class_name, |
| 'gc_type': this_gc_type, |
| # FIXME: Remove 'EventTarget' special handling, http://crbug.com/383699 |
| 'has_access_check_callbacks': (is_check_security and |
| @@ -153,15 +175,18 @@ def interface_context(interface): |
| 'has_custom_legacy_call_as_function': has_extended_attribute_value(interface, 'Custom', 'LegacyCallAsFunction'), # [Custom=LegacyCallAsFunction] |
| 'has_custom_to_v8': has_extended_attribute_value(interface, 'Custom', 'ToV8'), # [Custom=ToV8] |
| 'has_custom_wrap': has_extended_attribute_value(interface, 'Custom', 'Wrap'), # [Custom=Wrap] |
| + 'has_partial_interface': len(interface.partial_interfaces) > 0, |
| 'has_visit_dom_wrapper': has_visit_dom_wrapper, |
| 'header_includes': header_includes, |
| 'interface_name': interface.name, |
| 'is_active_dom_object': is_active_dom_object, |
| 'is_check_security': is_check_security, |
| 'is_dependent_lifetime': is_dependent_lifetime, |
| - 'is_event_target': inherits_interface(interface.name, 'EventTarget'), |
| + 'is_document': is_document, |
| + 'is_event_target': is_event_target, |
| 'is_exception': interface.is_exception, |
| 'is_node': inherits_interface(interface.name, 'Node'), |
| + 'is_partial': interface.is_partial, |
| 'is_script_wrappable': is_script_wrappable, |
| 'iterator_method': iterator_method, |
| 'lifetime': 'Dependent' |
| @@ -177,7 +202,7 @@ def interface_context(interface): |
| 'reachable_node_function': reachable_node_function, |
| 'runtime_enabled_function': runtime_enabled_function_name(interface), # [RuntimeEnabled] |
| 'set_wrapper_reference_to_list': set_wrapper_reference_to_list, |
| - 'v8_class': v8_utilities.v8_class_name(interface), |
| + 'v8_class': v8_class_name, |
| 'wrapper_class_id': wrapper_class_id, |
| } |
| @@ -189,7 +214,7 @@ def interface_context(interface): |
| # Handle named constructors separately |
| if constructor.name == 'Constructor'] |
| if len(constructors) > 1: |
| - context['constructor_overloads'] = overloads_context(constructors) |
| + context['constructor_overloads'] = overloads_context(interface, constructors) |
| # [CustomConstructor] |
| custom_constructors = [{ # Only needed for computing interface length |
| @@ -198,7 +223,19 @@ def interface_context(interface): |
| } for constructor in interface.custom_constructors] |
| # [EventConstructor] |
| - has_event_constructor = 'EventConstructor' in extended_attributes |
| + has_event_constructor = 'EventConstructor' in interface.extended_attributes |
| + # [NamedConstructor] |
| + named_constructor = named_constructor_context(interface) |
| + |
| + if constructors or custom_constructors or has_event_constructor or named_constructor: |
| + if interface.is_partial: |
| + raise Exception('[Constructor] and [NamedConstructor] MUST NOT be' |
| + ' specified on partial interface definitions:' |
| + '%s' % interface.name) |
| + |
| + includes.add('bindings/core/v8/V8ObjectConstructor.h') |
| + includes.add('core/frame/LocalDOMWindow.h') |
| + |
| any_type_attributes = [attribute for attribute in interface.attributes |
| if attribute.idl_type.name == 'Any'] |
| if has_event_constructor: |
| @@ -206,14 +243,6 @@ def interface_context(interface): |
| if any_type_attributes: |
| includes.add('bindings/core/v8/SerializedScriptValue.h') |
| - # [NamedConstructor] |
| - named_constructor = named_constructor_context(interface) |
| - |
| - if (constructors or custom_constructors or has_event_constructor or |
| - named_constructor): |
| - includes.add('bindings/core/v8/V8ObjectConstructor.h') |
| - includes.add('core/frame/LocalDOMWindow.h') |
| - |
| context.update({ |
| 'any_type_attributes': any_type_attributes, |
| 'constructors': constructors, |
| @@ -221,7 +250,8 @@ def interface_context(interface): |
| 'has_event_constructor': has_event_constructor, |
| 'interface_length': |
| interface_length(interface, constructors + custom_constructors), |
| - 'is_constructor_raises_exception': extended_attributes.get('RaisesException') == 'Constructor', # [RaisesException=Constructor] |
| + 'is_constructor_raises_exception': |
| + interface.extended_attributes.get('RaisesException') == 'Constructor', # [RaisesException=Constructor] |
| 'named_constructor': named_constructor, |
| }) |
| @@ -271,10 +301,21 @@ def interface_context(interface): |
| }) |
| # Methods |
| - methods = [v8_methods.method_context(interface, method) |
| - for method in interface.operations |
| - if method.name] # Skip anonymous special operations (methods) |
| - compute_method_overloads_context(methods) |
| + methods = [] |
| + if interface.original_interface: |
| + methods.extend([v8_methods.method_context(interface, operation, is_visible=False) |
| + for operation in interface.original_interface.operations |
| + if operation.name]) |
| + methods.extend([v8_methods.method_context(interface, method) |
| + for method in interface.operations |
| + if method.name]) # Skip anonymous special operations (methods) |
| + if interface.partial_interfaces: |
| + assert len(interface.partial_interfaces) == len(set(interface.partial_interfaces)) |
| + for partial_interface in interface.partial_interfaces: |
| + methods.extend([v8_methods.method_context(interface, operation, is_visible=False) |
| + for operation in partial_interface.operations |
| + if operation.name]) |
| + compute_method_overloads_context(interface, methods) |
| # Stringifier |
| if interface.stringifier: |
| @@ -300,11 +341,18 @@ def interface_context(interface): |
| if 'overloads' in method: |
| overloads = method['overloads'] |
| + if not overloads['visible']: |
| + continue |
| + # original interface will register instead of partial interface. |
| + if overloads['has_partial_overloads'] and interface.is_partial: |
| + continue |
| per_context_enabled_function = overloads['per_context_enabled_function_all'] |
| conditionally_exposed_function = overloads['exposed_test_all'] |
| runtime_enabled_function = overloads['runtime_enabled_function_all'] |
| has_custom_registration = overloads['has_custom_registration_all'] |
| else: |
| + if not method['visible']: |
| + continue |
| per_context_enabled_function = method['per_context_enabled_function'] |
| conditionally_exposed_function = method['exposed_test'] |
| runtime_enabled_function = method['runtime_enabled_function'] |
| @@ -379,16 +427,16 @@ def constant_context(constant): |
| # Overloads |
| ################################################################################ |
| -def compute_method_overloads_context(methods): |
| +def compute_method_overloads_context(interface, methods): |
| # Regular methods |
| - compute_method_overloads_context_by_type([method for method in methods |
| - if not method['is_static']]) |
| + compute_method_overloads_context_by_type( |
| + interface, [method for method in methods if not method['is_static']]) |
| # Static methods |
| - compute_method_overloads_context_by_type([method for method in methods |
| - if method['is_static']]) |
| + compute_method_overloads_context_by_type( |
| + interface, [method for method in methods if method['is_static']]) |
| -def compute_method_overloads_context_by_type(methods): |
| +def compute_method_overloads_context_by_type(interface, methods): |
| """Computes |method.overload*| template values. |
| Called separately for static and non-static (regular) methods, |
| @@ -402,7 +450,7 @@ def compute_method_overloads_context_by_type(methods): |
| for name, overloads in method_overloads_by_name(methods): |
| # Resolution function is generated after last overloaded function; |
| # package necessary information into |method.overloads| for that method. |
| - overloads[-1]['overloads'] = overloads_context(overloads) |
| + overloads[-1]['overloads'] = overloads_context(interface, overloads) |
| overloads[-1]['overloads']['name'] = name |
| @@ -420,7 +468,7 @@ def method_overloads_by_name(methods): |
| return sort_and_groupby(overloaded_methods, itemgetter('name')) |
| -def overloads_context(overloads): |
| +def overloads_context(interface, overloads): |
| """Returns |overloads| template values for a single name. |
| Sets |method.overload_index| in place for |method| in |overloads| |
| @@ -466,6 +514,14 @@ def overloads_context(overloads): |
| raise ValueError('Overloads of %s have conflicting Promise/non-Promise types' |
| % (name)) |
| + overloads_visibles = set([method.get('visible', True) for method in overloads]) |
| + if len(overloads_visibles) > 1: |
| + overloads_visible = True |
| + has_partial_overloads = True |
| + else: |
| + overloads_visible = overloads_visibles.pop() |
| + has_partial_overloads = False |
|
haraken
2014/10/16 04:24:08
Discussed offline and I understood what this code
tasak
2014/10/17 07:38:18
Done.
|
| + |
| return { |
| 'deprecate_all_as': common_value(overloads, 'deprecate_as'), # [DeprecateAs] |
| 'exposed_test_all': common_value(overloads, 'exposed_test'), # [Exposed] |
| @@ -483,6 +539,8 @@ def overloads_context(overloads): |
| # sequence of possible lengths, otherwise invalid length means |
| # "not enough arguments". |
| if lengths[-1] - lengths[0] != len(lengths) - 1 else None, |
| + 'visible': overloads_visible, |
| + 'has_partial_overloads': has_partial_overloads, |
| } |