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

Unified Diff: client/dom/scripts/dartgenerator.py

Issue 8548010: Wrapper dom changes in preparation for SVG (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: tweak Created 9 years, 1 month 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
« no previous file with comments | « client/dom/generated/wrapping_dom.js ('k') | client/dom/scripts/template_wrapping_dom.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: client/dom/scripts/dartgenerator.py
diff --git a/client/dom/scripts/dartgenerator.py b/client/dom/scripts/dartgenerator.py
index 589f41824e4ec5f616900f8583a5e1007331b776..438088729d87bf23d4bba215f46fa8942841a2ab 100755
--- a/client/dom/scripts/dartgenerator.py
+++ b/client/dom/scripts/dartgenerator.py
@@ -486,48 +486,46 @@ class DartGenerator(object):
# defined in the current interface as well as a parent. In that case we
# avoid making a duplicate definition and pray that the signatures match.
- for parent in interface.parents[1:]:
- if _IsDartCollectionType(parent.type.id):
+ for parent_interface in self._TransitiveSecondaryParents(interface):
+ if isinstance(interface, str): # _IsDartCollectionType(parent_interface)
continue
- if self._database.HasInterface(parent.type.id):
- parent_interface = self._database.GetInterface(parent.type.id)
- attributes = sorted(parent_interface.attributes,
- AttributeOutputOrder)
- for attr in attributes:
- if not self._DefinesSameAttribute(interface, attr):
- if attr.is_fc_getter:
- monkey_interface_generator.AddSecondaryGetter(
- parent_interface, attr)
- wrapping_interface_generator.AddSecondaryGetter(
- parent_interface, attr)
- frog_interface_generator.AddSecondaryGetter(
- parent_interface, attr)
- elif attr.is_fc_setter:
- monkey_interface_generator.AddSecondarySetter(
- parent_interface, attr)
- wrapping_interface_generator.AddSecondarySetter(
- parent_interface, attr)
- frog_interface_generator.AddSecondarySetter(
- parent_interface, attr)
-
- # Group overloaded operations by id
- operationsById = {}
- for operation in parent_interface.operations:
- if operation.id not in operationsById:
- operationsById[operation.id] = []
- operationsById[operation.id].append(operation)
-
- # Generate operations
- for id in sorted(operationsById.keys()):
- if not any(op.id == id for op in interface.operations):
- operations = operationsById[id]
- info = self._AnalyzeOperation(interface, operations)
- monkey_interface_generator.AddSecondaryOperation(
- parent_interface, info)
- wrapping_interface_generator.AddSecondaryOperation(
- parent_interface, info)
- frog_interface_generator.AddSecondaryOperation(
- parent_interface, info)
+ attributes = sorted(parent_interface.attributes,
+ AttributeOutputOrder)
+ for attr in attributes:
+ if not self._DefinesSameAttribute(interface, attr):
+ if attr.is_fc_getter:
+ monkey_interface_generator.AddSecondaryGetter(
+ parent_interface, attr)
+ wrapping_interface_generator.AddSecondaryGetter(
+ parent_interface, attr)
+ frog_interface_generator.AddSecondaryGetter(
+ parent_interface, attr)
+ elif attr.is_fc_setter:
+ monkey_interface_generator.AddSecondarySetter(
+ parent_interface, attr)
+ wrapping_interface_generator.AddSecondarySetter(
+ parent_interface, attr)
+ frog_interface_generator.AddSecondarySetter(
+ parent_interface, attr)
+
+ # Group overloaded operations by id
+ operationsById = {}
+ for operation in parent_interface.operations:
+ if operation.id not in operationsById:
+ operationsById[operation.id] = []
+ operationsById[operation.id].append(operation)
+
+ # Generate operations
+ for id in sorted(operationsById.keys()):
+ if not any(op.id == id for op in interface.operations):
+ operations = operationsById[id]
+ info = self._AnalyzeOperation(interface, operations)
+ monkey_interface_generator.AddSecondaryOperation(
+ parent_interface, info)
+ wrapping_interface_generator.AddSecondaryOperation(
+ parent_interface, info)
+ frog_interface_generator.AddSecondaryOperation(
+ parent_interface, info)
dart_interface_generator.FinishInterface(self._overloaded_types)
monkey_interface_generator.FinishInterface()
@@ -541,6 +539,26 @@ class DartGenerator(object):
and attr1.is_fc_setter == attr2.is_fc_setter
for attr2 in interface.attributes)
+ def _TransitiveSecondaryParents(self, interface):
+ """Returns a list of all non-primary parents.
+
+ The list contains the interface objects for interfaces defined in the
+ database, and the name for undefined interfaces.
+ """
+ def walk(parents):
+ for parent in parents:
+ if _IsDartCollectionType(parent.type.id):
+ result.append(parent.type.id)
+ continue
+ if self._database.HasInterface(parent.type.id):
+ parent_interface = self._database.GetInterface(parent.type.id)
+ result.append(parent_interface)
+ walk(parent_interface.parents)
+
+ result = []
+ walk(interface.parents[1:])
+ return result;
vsm 2011/11/18 05:42:28 Can you get duplicates from diamond inheritance?
+
def _AnalyzeOperation(self, interface, operations):
"""Makes operation calling convention decision for a set of overloads.
@@ -739,7 +757,30 @@ class DartGenerator(object):
return WrappingInterfaceGenerator(interface, super_interface_name,
dart_code, self._wrapping_js_natives,
self._wrapping_map,
- self._wrapping_externs)
+ self._wrapping_externs,
+ self._BaseDefines(interface))
+
+ def _BaseDefines(self, interface):
+ """Returns a set of names (strings) for members defined in a base class.
+ """
+ def WalkParentChain(interface):
+ if interface.parents:
+ # Only consider primary parent, secondary parents are not on the
+ # implementation class inheritance chain.
+ parent = interface.parents[0]
+ if _IsDartCollectionType(parent.type.id):
+ return
+ if self._database.HasInterface(parent.type.id):
+ parent_interface = self._database.GetInterface(parent.type.id)
+ for attr in parent_interface.attributes:
+ result.add(attr.id)
+ for op in parent_interface.operations:
+ result.add(op.id)
+ WalkParentChain(parent_interface)
+
+ result = set()
+ WalkParentChain(interface)
+ return result;
def _StartGenerateFrogImpl(self, output_dir):
@@ -1142,7 +1183,7 @@ class WrappingInterfaceGenerator(object):
"""Generates Dart and JS implementation for one DOM IDL interface."""
def __init__(self, interface, super_interface, dart_code, js_code, type_map,
- externs):
+ externs, base_members):
"""Generates Dart and JS code for the given interface.
Args:
@@ -1158,6 +1199,8 @@ class WrappingInterfaceGenerator(object):
type_map: an Emitter for the map from tokens to wrapper factory.
externs: a set of (class, property, kind) externs. kind is 'attribute' or
'operation'.
+ base_members: a set of names of members defined in a base class. This is
+ used to avoid static member 'overriding' in the generated Dart code.
"""
self._interface = interface
self._super_interface = super_interface
@@ -1165,6 +1208,7 @@ class WrappingInterfaceGenerator(object):
self._js_code = js_code
self._type_map = type_map
self._externs = externs
+ self._base_members = base_members
self._current_secondary_parent = None
@@ -1226,49 +1270,53 @@ class WrappingInterfaceGenerator(object):
def AddConstant(self, constant):
pass
- def AddGetter(self, attr):
- # We inject the interface into the static method name to make it
- # unique as required by the language. A conflict only occurs when
- # the corresponding instance method is overloaded.
+ def _MethodName(self, prefix, name):
+ method_name = prefix + name
+ if name in self._base_members: # Avoid illegal Dart 'static override'.
+ method_name = method_name + '_' + self._interface.id
+ return method_name
- # FIXME: Instead of injecting the interface name into the method,
- # suppress the method altogether when it's implemented in a base
- # class. I.e., let the JS do the virtual dispatch instead.
+ def AddGetter(self, attr):
+ # FIXME: Instead of injecting the interface name into the method when it is
+ # also implemented in the base class, suppress the method altogether if it
+ # has the same signature. I.e., let the JS do the virtual dispatch instead.
+ method_name = self._MethodName('_get_', attr.id)
self._members_emitter.Emit(
'\n'
- ' $TYPE get $NAME() { return _get__$(INTERFACE)_$(NAME)(this); }\n'
- ' static $TYPE _get__$(INTERFACE)_$(NAME)(var _this) native;\n',
- NAME=attr.id, TYPE=attr.type.id, INTERFACE=self._interface.id)
+ ' $TYPE get $NAME() { return $METHOD(this); }\n'
+ ' static $TYPE $METHOD(var _this) native;\n',
+ NAME=attr.id, TYPE=attr.type.id, METHOD=method_name)
if (self._interface.id, attr.id) not in _custom_getters:
self._js_code.Emit(
'\n'
- 'function native_$(CLASS)__get__$(INTERFACE)_$(NAME)(_this) {\n'
+ 'function native_$(CLASS)_$(METHOD)(_this) {\n'
' try {\n'
' return __dom_wrap(_this.$dom.$NAME);\n'
' } catch (e) {\n'
' throw __dom_wrap_exception(e);\n'
' }\n'
'}\n',
- CLASS=self._class_name, NAME=attr.id, INTERFACE=self._interface.id)
+ CLASS=self._class_name, NAME=attr.id, METHOD=method_name)
self._externs.add((self._interface.id, attr.id, 'attribute'))
def AddSetter(self, attr):
# FIXME: See comment on getter.
+ method_name = self._MethodName('_set_', attr.id)
self._members_emitter.Emit(
'\n'
- ' void set $NAME($TYPE value) { _set__$(INTERFACE)_$(NAME)(this, value); }\n'
- ' static void _set__$(INTERFACE)_$(NAME)(var _this, $TYPE value) native;\n',
- NAME=attr.id, TYPE=attr.type.id, INTERFACE=self._interface.id)
+ ' void set $NAME($TYPE value) { $METHOD(this, value); }\n'
+ ' static void $METHOD(var _this, $TYPE value) native;\n',
+ NAME=attr.id, TYPE=attr.type.id, METHOD=method_name)
self._js_code.Emit(
'\n'
- 'function native_$(CLASS)__set__$(INTERFACE)_$(NAME)(_this, value) {\n'
+ 'function native_$(CLASS)_$(METHOD)(_this, value) {\n'
' try {\n'
' _this.$dom.$NAME = __dom_unwrap(value);\n'
' } catch (e) {\n'
' throw __dom_wrap_exception(e);\n'
' }\n'
'}\n',
- CLASS=self._class_name, NAME=attr.id, INTERFACE=self._interface.id)
+ CLASS=self._class_name, NAME=attr.id, METHOD=method_name)
self._externs.add((self._interface.id, attr.id, 'attribute'))
def AddSecondaryGetter(self, interface, attr):
@@ -1450,7 +1498,7 @@ class WrappingInterfaceGenerator(object):
arg_names = [name for (name, _) in names_and_unwrappers]
self._native_version += 1
- native_name = '_' + info.name
+ native_name = self._MethodName('_', info.name)
if self._native_version > 1:
native_name = '%s_%s' % (native_name, self._native_version)
« no previous file with comments | « client/dom/generated/wrapping_dom.js ('k') | client/dom/scripts/template_wrapping_dom.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698