| 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):
|
|
|