Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(547)

Unified Diff: Source/bindings/scripts/v8_interface.py

Issue 618373003: [bindings] partial interfaces should not violate componentization (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Fixed http/tests/serviceworker/fetch\* regression Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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,
}

Powered by Google App Engine
This is Rietveld 408576698