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

Unified Diff: sdk/lib/html/scripts/systemhtml.py

Issue 11363130: Cleaning up dart:html generation after interface/implementation merge. Removing most of the interfa… (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Incorporating review feedback, cleaning up comments Created 8 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 | « sdk/lib/html/scripts/htmleventgenerator.py ('k') | sdk/lib/html/scripts/systemnative.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sdk/lib/html/scripts/systemhtml.py
diff --git a/sdk/lib/html/scripts/systemhtml.py b/sdk/lib/html/scripts/systemhtml.py
index 480d50e27367aea5edd86b5f74e4869f495dea20..acc227c2b6c2cc7382e6ebce15b6c489409edccc 100644
--- a/sdk/lib/html/scripts/systemhtml.py
+++ b/sdk/lib/html/scripts/systemhtml.py
@@ -47,27 +47,6 @@ _js_custom_members = set([
# constructor creation.
_static_classes = set(['Url'])
-# Types that are accessible cross-frame in a limited fashion.
-# In these cases, the base type (e.g., Window) provides restricted access
-# while the subtype (e.g., LocalWindow) provides full access to the
-# corresponding objects if there are from the same frame.
-_secure_base_types = {
- 'LocalWindow': 'Window',
- 'LocalLocation': 'Location',
- 'LocalHistory': 'History',
-}
-
-def SecureOutputType(generator, type_name, is_dart_type=False):
- if is_dart_type:
- dart_name = type_name
- else:
- dart_name = generator._DartType(type_name)
- # We only need to secure Window. Only local History and Location are returned
- # in generated code.
- if dart_name == 'LocalWindow':
- return _secure_base_types[dart_name]
- return dart_name
-
# Information for generating element constructors.
#
# TODO(sra): maybe remove all the argument complexity and use cascades.
@@ -213,6 +192,7 @@ class HtmlDartInterfaceGenerator(object):
self._database = options.database
self._template_loader = options.templates
self._type_registry = options.type_registry
+ self._options = options
self._library_emitter = library_emitter
self._event_generator = event_generator
self._interface = interface
@@ -240,32 +220,6 @@ class HtmlDartInterfaceGenerator(object):
def GenerateInterface(self):
interface_name = self._interface_type_info.interface_name()
- # TODO: this is just tossing the interface, need to skip it completely.
- interface_emitter = emitter.Emitter()
-
- template_file = 'interface_%s.darttemplate' % interface_name
- interface_template = (self._template_loader.TryLoad(template_file) or
- self._template_loader.Load('interface.darttemplate'))
-
- implements = []
- for parent in self._interface.parents:
- parent_type_info = self._type_registry.TypeInfo(parent.type.id)
- implements.append(parent_type_info.interface_name())
-
- if self._interface_type_info.list_item_type():
- item_type_info = self._type_registry.TypeInfo(
- self._interface_type_info.list_item_type())
- implements.append('List<%s>' % item_type_info.dart_type())
-
- if interface_name in _secure_base_types:
- implements.append(_secure_base_types[interface_name])
-
- comment = ' extends'
- implements_str = ''
- if implements:
- implements_str += ' implements ' + ', '.join(implements)
- comment = ','
-
factory_provider = None
if interface_name in interface_factories:
factory_provider = interface_factories[interface_name]
@@ -301,14 +255,6 @@ class HtmlDartInterfaceGenerator(object):
else:
factory_provider = info.factory_provider_name
- # TODO(vsm): Add appropriate package / namespace syntax.
- (self._type_comment_emitter,
- self._members_emitter,
- self._top_level_emitter) = interface_emitter.Emit(
- interface_template + '$!TOP_LEVEL',
- ID='_I%s' % interface_name,
- EXTENDS=implements_str)
-
implementation_emitter = self._ImplementationEmitter()
base_type_info = None
@@ -332,8 +278,9 @@ class HtmlDartInterfaceGenerator(object):
if parent_type_info != base_type_info:
implements.append(parent_type_info.interface_name())
- if interface_name in _secure_base_types:
- implements.append(_secure_base_types[interface_name])
+ secure_base_name = self._backend.SecureBaseName(interface_name)
+ if secure_base_name:
+ implements.append(secure_base_name)
implements_str = ''
if implements:
@@ -348,222 +295,26 @@ class HtmlDartInterfaceGenerator(object):
NATIVESPEC=self._backend.NativeSpec())
self._backend.StartInterface(self._implementation_members_emitter)
- for constructor_info in constructors:
- constructor_info.GenerateFactoryInvocation(
- self._DartType, self._members_emitter, factory_provider)
-
self._backend.AddConstructors(constructors, factory_provider,
self._interface_type_info.implementation_name(),
base_class)
- typed_array_type = None
- for interface in self._database.Hierarchy(self._interface):
- type_info = self._type_registry.TypeInfo(interface.id)
- if type_info.is_typed_array():
- typed_array_type = type_info.list_item_type()
- break
- if typed_array_type:
- self._members_emitter.Emit(
- '\n'
- ' factory $CTOR(int length) =>\n'
- ' $FACTORY.create$(CTOR)(length);\n'
- '\n'
- ' factory $CTOR.fromList(List<$TYPE> list) =>\n'
- ' $FACTORY.create$(CTOR)_fromList(list);\n'
- '\n'
- ' factory $CTOR.fromBuffer(ArrayBuffer buffer, [int byteOffset, int length]) => \n'
- ' $FACTORY.create$(CTOR)_fromBuffer(buffer, byteOffset, length);\n',
- CTOR=self._interface.id,
- TYPE=self._DartType(typed_array_type),
- FACTORY=factory_provider)
-
- events_interface = self._event_generator.ProcessInterface(
+ events_class_name = self._event_generator.ProcessInterface(
self._interface, interface_name,
self._backend.CustomJSMembers(),
- interface_emitter, implementation_emitter)
- if events_interface:
- self._EmitEventGetter(events_interface, events_interface)
+ implementation_emitter)
+ if events_class_name:
+ self._backend.EmitEventGetter(events_class_name)
- old_backend = self._backend
- if not self._backend.ImplementsMergedMembers():
- self._backend = HtmlGeneratorDummyBackend()
merged_interface = self._interface_type_info.merged_interface()
if merged_interface:
- self.AddMembers(self._database.GetInterface(merged_interface))
- self._backend = old_backend
+ self._backend.AddMembers(self._database.GetInterface(merged_interface),
+ not self._backend.ImplementsMergedMembers())
- self.AddMembers(self._interface)
- if merged_interface and not self._backend.ImplementsMergedMembers():
- self.AddMembers(self._database.GetInterface(merged_interface), True)
-
- self.AddSecondaryMembers(self._interface)
+ self._backend.AddMembers(self._interface)
+ self._backend.AddSecondaryMembers(self._interface)
self._backend.FinishInterface()
- def AddMembers(self, interface, declare_only=False):
- for const in sorted(interface.constants, ConstantOutputOrder):
- self.AddConstant(const)
-
- for attr in sorted(interface.attributes, ConstantOutputOrder):
- if attr.type.id != 'EventListener':
- self.AddAttribute(attr, False, declare_only)
-
- # The implementation should define an indexer if the interface directly
- # extends List.
- element_type = None
- requires_indexer = False
- if self._interface_type_info.list_item_type():
- self.AddIndexer(self._interface_type_info.list_item_type())
- else:
- for parent in self._database.Hierarchy(self._interface):
- if parent == self._interface:
- continue
- parent_type_info = self._type_registry.TypeInfo(parent.id)
- if parent_type_info.list_item_type():
- self.AmendIndexer(parent_type_info.list_item_type())
- break
-
- # Group overloaded operations by id
- operationsById = {}
- for operation in interface.operations:
- if operation.id not in operationsById:
- operationsById[operation.id] = []
- operationsById[operation.id].append(operation)
-
- # Generate operations
- for id in sorted(operationsById.keys()):
- operations = operationsById[id]
- info = AnalyzeOperation(interface, operations)
- self.AddOperation(info, False, declare_only)
-
- def AddSecondaryMembers(self, interface):
- # With multiple inheritance, attributes and operations of non-first
- # interfaces need to be added. Sometimes the attribute or operation is
- # 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.
- secondary_parents = self._TransitiveSecondaryParents(interface)
- for parent_interface in sorted(secondary_parents):
- if isinstance(parent_interface, str): # IsDartCollectionType(parent_interface)
- continue
- for attr in sorted(parent_interface.attributes, ConstantOutputOrder):
- if not FindMatchingAttribute(interface, attr):
- self.AddSecondaryAttribute(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 = AnalyzeOperation(interface, operations)
- self.AddSecondaryOperation(parent_interface, info)
-
- def AddIndexer(self, element_type):
- self._backend.AddIndexer(element_type)
-
- def AmendIndexer(self, element_type):
- self._backend.AmendIndexer(element_type)
-
- def AddAttribute(self, attribute, is_secondary=False, declare_only=False):
- dom_name = DartDomNameOfAttribute(attribute)
- html_name = self._renamer.RenameMember(
- self._interface.id, attribute, dom_name, 'get:')
- if not html_name or self._IsPrivate(html_name):
- return
-
-
- html_setter_name = self._renamer.RenameMember(
- self._interface.id, attribute, dom_name, 'set:')
- read_only = (attribute.is_read_only or 'Replaceable' in attribute.ext_attrs
- or not html_setter_name)
-
- # We don't yet handle inconsistent renames of the getter and setter yet.
- assert(not html_setter_name or html_name == html_setter_name)
-
- if not is_secondary:
- self._members_emitter.Emit('\n /** @domName $DOMINTERFACE.$DOMNAME */',
- DOMINTERFACE=attribute.doc_js_interface_name,
- DOMNAME=dom_name)
- if read_only:
- template = '\n $TYPE get $NAME;\n'
- else:
- template = '\n $TYPE $NAME;\n'
-
- self._members_emitter.Emit(template,
- NAME=html_name,
- TYPE=SecureOutputType(self, attribute.type.id))
-
- if declare_only:
- self._backend.DeclareAttribute(attribute,
- SecureOutputType(self, attribute.type.id), html_name, read_only)
- else:
- self._backend.AddAttribute(attribute, html_name, read_only)
-
- def AddSecondaryAttribute(self, interface, attribute):
- self._backend.SecondaryContext(interface)
- self.AddAttribute(attribute, True)
-
- def AddOperation(self, info, skip_declaration=False, declare_only=False):
- """
- Arguments:
- operations - contains the overloads, one or more operations with the same
- name.
- """
- # FIXME: When we pass in operations[0] below, we're assuming all
- # overloaded operations have the same security attributes. This
- # is currently true, but we should consider filtering earlier or
- # merging the relevant data into info itself.
- html_name = self._renamer.RenameMember(self._interface.id,
- info.operations[0],
- info.name)
- if not html_name:
- if info.name == 'item':
- # FIXME: item should be renamed to operator[], not removed.
- self._backend.AddOperation(info, '_item')
- return
-
- if not self._IsPrivate(html_name) and not skip_declaration:
- self._members_emitter.Emit('\n /** @domName $DOMINTERFACE.$DOMNAME */',
- DOMINTERFACE=info.overloads[0].doc_js_interface_name,
- DOMNAME=info.name)
-
- if info.IsStatic():
- # FIXME: provide a type.
- self._members_emitter.Emit(
- '\n'
- ' static final $NAME = $IMPL_CLASS_NAME.$NAME;\n',
- IMPL_CLASS_NAME=self._interface_type_info.implementation_name(),
- NAME=html_name)
- else:
- self._members_emitter.Emit(
- '\n'
- ' $TYPE $NAME($PARAMS);\n',
- TYPE=SecureOutputType(self, info.type_name),
- NAME=html_name,
- PARAMS=info.ParametersDeclaration(self._DartType))
- if declare_only:
- self._backend.DeclareOperation(info,
- SecureOutputType(self, info.type_name), html_name)
- else:
- self._backend.AddOperation(info, html_name)
-
- def AddSecondaryOperation(self, interface, info):
- self._backend.SecondaryContext(interface)
- self.AddOperation(info)
-
- def AddConstant(self, constant):
- type = TypeOrNothing(self._DartType(constant.type.id), constant.type.id)
- self._members_emitter.Emit('\n static const $TYPE$NAME = $VALUE;\n',
- NAME=constant.id,
- TYPE=type,
- VALUE=constant.value)
-
- self._backend.AddConstant(constant)
-
def _ImplementationEmitter(self):
basename = self._interface_type_info.implementation_name()
if (self._interface_type_info.merged_into() and
@@ -572,67 +323,9 @@ class HtmlDartInterfaceGenerator(object):
return emitter.Emitter()
return self._library_emitter.FileEmitter(basename)
- def _EmitEventGetter(self, events_interface, events_class):
- self._members_emitter.Emit(
- '\n /**'
- '\n * @domName EventTarget.addEventListener, '
- 'EventTarget.removeEventListener, EventTarget.dispatchEvent'
- '\n */'
- '\n $TYPE get on;\n',
- TYPE=events_interface)
-
- self._implementation_members_emitter.Emit(
- '\n /**'
- '\n * @domName EventTarget.addEventListener, '
- 'EventTarget.removeEventListener, EventTarget.dispatchEvent'
- '\n */'
- '\n $TYPE get on =>\n new $TYPE(this);\n',
- TYPE=events_class)
-
- 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:
- parent_name = parent.type.id
- if parent_name == 'EventTarget':
- # Currently EventTarget is implemented as a mixin, not a proper
- # super interface---ignore its members.
- continue
- if IsDartCollectionType(parent_name):
- result.append(parent_name)
- continue
- if self._database.HasInterface(parent_name):
- parent_interface = self._database.GetInterface(parent_name)
- result.append(parent_interface)
- walk(parent_interface.parents)
-
- result = []
- if interface.parents:
- parent = interface.parents[0]
- if IsPureInterface(parent.type.id):
- walk(interface.parents)
- else:
- walk(interface.parents[1:])
- return result
-
def _DartType(self, type_name):
return self._type_registry.DartType(type_name)
- def _IsPrivate(self, name):
- return name.startswith('_')
-
-
-class HtmlGeneratorDummyBackend(object):
- def AddAttribute(self, attribute, html_name, read_only):
- pass
-
- def AddOperation(self, info, html_name):
- pass
-
# ------------------------------------------------------------------------------
@@ -732,7 +425,7 @@ class Dart2JSBackend(HtmlDartGenerator):
self._members_emitter.Emit(
'\n'
' $TYPE operator[](int index) => JS("$TYPE", "#[#]", this, index);\n',
- TYPE=self._NarrowOutputType(element_type))
+ TYPE=self.SecureOutputType(element_type))
if 'CustomIndexedSetter' in self._interface.ext_attrs:
self._members_emitter.Emit(
@@ -762,7 +455,7 @@ class Dart2JSBackend(HtmlDartGenerator):
{'DEFINE_CONTAINS': not has_contains})
self._members_emitter.Emit(template, E=self._DartType(element_type))
- def AddAttribute(self, attribute, html_name, read_only):
+ def EmitAttribute(self, attribute, html_name, read_only):
if self._HasCustomImplementation(attribute.id):
return
@@ -793,7 +486,7 @@ class Dart2JSBackend(HtmlDartGenerator):
' // final $TYPE $NAME;\n',
SUPER=super_attribute_interface,
NAME=DartDomNameOfAttribute(attribute),
- TYPE=self._NarrowOutputType(attribute.type.id))
+ TYPE=self.SecureOutputType(attribute.type.id))
return
self._members_emitter.Emit('\n // Shadowing definition.')
self._AddAttributeUsingProperties(attribute, html_name, read_only)
@@ -806,7 +499,7 @@ class Dart2JSBackend(HtmlDartGenerator):
self._AddAttributeUsingProperties(attribute, html_name, read_only)
return
- output_type = self._NarrowOutputType(attribute.type.id)
+ output_type = self.SecureOutputType(attribute.type.id)
input_type = self._NarrowInputType(attribute.type.id)
self.EmitAttributeDocumentation(attribute)
if not read_only:
@@ -832,7 +525,7 @@ class Dart2JSBackend(HtmlDartGenerator):
'\n $TYPE $NAME;'
'\n',
NAME=DartDomNameOfAttribute(attribute),
- TYPE=self._NarrowOutputType(attribute.type.id))
+ TYPE=self.SecureOutputType(attribute.type.id))
def _AddRenamingGetter(self, attr, html_name):
self.EmitAttributeDocumentation(attr)
@@ -840,7 +533,7 @@ class Dart2JSBackend(HtmlDartGenerator):
conversion = self._OutputConversion(attr.type.id, attr.id)
if conversion:
return self._AddConvertingGetter(attr, html_name, conversion)
- return_type = self._NarrowOutputType(attr.type.id)
+ return_type = self.SecureOutputType(attr.type.id)
self._members_emitter.Emit(
# TODO(sra): Use metadata to provide native name.
'\n $TYPE get $HTML_NAME => JS("$TYPE", "#.$NAME", this);'
@@ -897,7 +590,7 @@ class Dart2JSBackend(HtmlDartGenerator):
def AmendIndexer(self, element_type):
pass
- def AddOperation(self, info, html_name):
+ def EmitOperation(self, info, html_name):
"""
Arguments:
info: An OperationInfo object.
@@ -918,7 +611,7 @@ class Dart2JSBackend(HtmlDartGenerator):
def _AddDirectNativeOperation(self, info, html_name):
# Do we need a native body?
if html_name != info.declared_name:
- return_type = self._NarrowOutputType(info.type_name)
+ return_type = self.SecureOutputType(info.type_name)
operation_emitter = self._members_emitter.Emit('$!SCOPE',
MODIFIERS='static ' if info.IsStatic() else '',
@@ -936,7 +629,7 @@ class Dart2JSBackend(HtmlDartGenerator):
'\n'
' $MODIFIERS$TYPE $NAME($PARAMS) native;\n',
MODIFIERS='static ' if info.IsStatic() else '',
- TYPE=self._NarrowOutputType(info.type_name),
+ TYPE=self.SecureOutputType(info.type_name),
NAME=info.name,
PARAMS=info.ParametersDeclaration(self._NarrowInputType))
@@ -1083,7 +776,7 @@ class Dart2JSBackend(HtmlDartGenerator):
self._members_emitter.Emit(
'\n'
' $TYPE $NAME($PARAMS);\n',
- TYPE=self._NarrowOutputType(info.type_name),
+ TYPE=self.SecureOutputType(info.type_name),
NAME=info.name,
PARAMS=info.ParametersDeclaration(self._NarrowInputType))
@@ -1129,9 +822,6 @@ class Dart2JSBackend(HtmlDartGenerator):
def _NarrowInputType(self, type_name):
return self._NarrowToImplementationType(type_name)
- def _NarrowOutputType(self, type_name):
- return SecureOutputType(self, type_name)
-
def _FindShadowedAttribute(self, attr):
"""Returns (attribute, superinterface) or (None, None)."""
def FindInParent(interface):
« no previous file with comments | « sdk/lib/html/scripts/htmleventgenerator.py ('k') | sdk/lib/html/scripts/systemnative.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698