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..c4c41503cf53dd655e0cd47b29b28b3c01fbeeff 100644 |
--- a/Source/bindings/scripts/v8_interface.py |
+++ b/Source/bindings/scripts/v8_interface.py |
@@ -77,9 +77,25 @@ 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 not interface.is_partial: |
haraken
2014/10/09 04:24:00
Avoid 'if not ... else ...'. Use 'if ... else ...'
tasak
2014/10/10 07:52:22
Done.
|
+ 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') |
+ else: |
+ # 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_audio_buffer = False |
+ 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) |
+ |
extended_attributes = interface.extended_attributes |
# [ActiveDOMObject] |
@@ -95,7 +111,7 @@ def interface_context(interface): |
# [Iterable] |
iterator_method = None |
- if 'Iterable' in extended_attributes: |
+ if 'Iterable' in extended_attributes and not interface.is_partial: |
haraken
2014/10/09 04:24:00
Add a FIXME to support Iterable in partial interfa
tasak
2014/10/10 07:52:22
Done.
|
iterator_operation = IdlOperation(interface.idl_name) |
iterator_operation.name = 'iterator' |
iterator_operation.idl_type = IdlType('Iterator') |
@@ -159,7 +175,8 @@ def interface_context(interface): |
'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_script_wrappable': is_script_wrappable, |
@@ -169,6 +186,8 @@ def interface_context(interface): |
is_active_dom_object or |
is_dependent_lifetime) |
else 'Independent', |
+ 'is_partial': interface.is_partial, |
+ 'has_partial_interface': len(interface.partial_interfaces) > 0, |
'measure_as': v8_utilities.measure_as(interface), # [MeasureAs] |
'parent_interface': parent_interface, |
'pass_cpp_type': cpp_template_type( |
@@ -182,48 +201,10 @@ def interface_context(interface): |
} |
# Constructors |
- constructors = [constructor_context(interface, constructor) |
- for constructor in interface.constructors |
- # FIXME: shouldn't put named constructors with constructors |
- # (currently needed for Perl compatibility) |
- # Handle named constructors separately |
- if constructor.name == 'Constructor'] |
- if len(constructors) > 1: |
- context['constructor_overloads'] = overloads_context(constructors) |
- |
- # [CustomConstructor] |
- custom_constructors = [{ # Only needed for computing interface length |
- 'number_of_required_arguments': |
- number_of_required_arguments(constructor), |
- } for constructor in interface.custom_constructors] |
- |
- # [EventConstructor] |
- has_event_constructor = 'EventConstructor' in extended_attributes |
- any_type_attributes = [attribute for attribute in interface.attributes |
- if attribute.idl_type.name == 'Any'] |
- if has_event_constructor: |
- includes.add('bindings/core/v8/Dictionary.h') |
- 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, |
- 'has_custom_constructor': bool(custom_constructors), |
- '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] |
- 'named_constructor': named_constructor, |
- }) |
+ if not interface.is_partial: |
haraken
2014/10/09 04:24:00
Use if ... else ....
tasak
2014/10/10 07:52:22
Done.
|
+ update_interface_constructor_context(interface, context) |
+ else: |
+ update_partial_interface_constructor_context(interface, context) |
constants = [constant_context(constant) for constant in interface.constants] |
@@ -271,10 +252,27 @@ 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: |
+ for operation in interface.original_interface.operations: |
+ if not operation.name: |
+ continue |
+ method = v8_methods.method_context(interface, operation) |
+ method['visible'] = False |
+ methods.append(method) |
+ 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: |
+ for operation in partial_interface.operations: |
+ if not operation.name: |
+ continue |
+ partial_method = v8_methods.method_context(interface, operation) |
+ partial_method['visible'] = False |
+ methods.append(partial_method) |
+ compute_method_overloads_context(interface, methods) |
# Stringifier |
if interface.stringifier: |
@@ -300,11 +298,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['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'] |
@@ -359,6 +364,67 @@ def interface_context(interface): |
return context |
+def update_interface_constructor_context(interface, context): |
+ constructors = [constructor_context(interface, constructor) |
+ for constructor in interface.constructors |
+ # FIXME: shouldn't put named constructors with constructors |
+ # (currently needed for Perl compatibility) |
+ # Handle named constructors separately |
+ if constructor.name == 'Constructor'] |
+ if len(constructors) > 1: |
+ context['constructor_overloads'] = overloads_context(interface, constructors) |
+ |
+ # [CustomConstructor] |
+ custom_constructors = [{ # Only needed for computing interface length |
+ 'number_of_required_arguments': |
+ number_of_required_arguments(constructor), |
+ } for constructor in interface.custom_constructors] |
+ |
+ # [EventConstructor] |
+ has_event_constructor = 'EventConstructor' in interface.extended_attributes |
+ any_type_attributes = [attribute for attribute in interface.attributes |
+ if attribute.idl_type.name == 'Any'] |
+ if has_event_constructor: |
+ includes.add('bindings/core/v8/Dictionary.h') |
+ 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, |
+ 'has_custom_constructor': bool(custom_constructors), |
+ 'has_event_constructor': has_event_constructor, |
+ 'interface_length': |
+ interface_length(interface, constructors + custom_constructors), |
+ 'is_constructor_raises_exception': |
+ interface.extended_attributes.get('RaisesException') == 'Constructor', # [RaisesException=Constructor] |
+ 'named_constructor': named_constructor, |
+ }) |
+ |
+ |
+def update_partial_interface_constructor_context(interface, context): |
haraken
2014/10/09 04:24:00
Why can we share the code with update_interface_co
tasak
2014/10/10 07:52:22
Done.
|
+ # [Constructor], [NamedConstructor] must not be specified on partial interface |
haraken
2014/10/09 04:24:00
Can we raise an exception if this happens?
tasak
2014/10/10 07:52:22
Done.
|
+ # definitions. |
+ any_type_attributes = [attribute for attribute in interface.attributes |
+ if attribute.idl_type.name == 'Any'] |
+ context.update({ |
+ 'any_type_attributes': any_type_attributes, |
+ 'constructors': [], |
+ 'has_custom_constructor': False, |
+ 'has_event_constructor': False, |
+ 'interface_length': 0, |
+ 'is_constructor_raises_exception': False, |
+ 'named_constructor': [], |
+ }) |
+ |
+ |
# [DeprecateAs], [Reflect], [RuntimeEnabled] |
def constant_context(constant): |
extended_attributes = constant.extended_attributes |
@@ -379,16 +445,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 +468,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,12 +486,13 @@ 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| |
and returns dict of overall overload template values. |
""" |
+ # partial overloads breaks this assumption. |
assert len(overloads) > 1 # only apply to overloaded names |
for index, method in enumerate(overloads, 1): |
method['overload_index'] = index |
@@ -466,6 +533,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 |
+ partial_overloads = True |
+ else: |
+ overloads_visible = overloads_visibles.pop() |
+ partial_overloads = False |
+ |
return { |
'deprecate_all_as': common_value(overloads, 'deprecate_as'), # [DeprecateAs] |
'exposed_test_all': common_value(overloads, 'exposed_test'), # [Exposed] |
@@ -483,6 +558,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, |
+ 'partial_overloads': partial_overloads, |
} |