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

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

Issue 9845043: Rename client/{dom,html} to lib/{dom,html} . (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 9 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
« no previous file with comments | « client/dom/scripts/systemfrog.py ('k') | client/dom/scripts/systeminterface.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: client/dom/scripts/systemhtml.py
===================================================================
--- client/dom/scripts/systemhtml.py (revision 5796)
+++ client/dom/scripts/systemhtml.py (working copy)
@@ -1,1782 +0,0 @@
-#!/usr/bin/python
-# Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-"""This module provides shared functionality for the system to generate
-Dart:html APIs from the IDL database."""
-
-from systemfrog import *
-from systeminterface import *
-
-# Members from the standard dom that should not be exposed publicly in dart:html
-# but need to be exposed internally to implement dart:html on top of a standard
-# browser.
-_private_html_members = set([
- 'Element.clientLeft',
- 'Element.clientTop',
- 'Element.clientWidth',
- 'Element.clientHeight',
- 'Element.offsetLeft',
- 'Element.offsetTop',
- 'Element.offsetWidth',
- 'Element.offsetHeight',
- 'Element.scrollLeft',
- 'Element.scrollTop',
- 'Element.scrollWidth',
- 'Element.scrollHeight',
- 'Element.childElementCount',
- 'Element.firstElementChild',
- 'Element.hasAttribute',
- 'Element.getAttribute',
- 'Element.removeAttribute',
- 'Element.setAttribute',
- 'Element.className',
- 'Element.children',
- 'Element.querySelectorAll',
- 'NodeSelector.querySelectorAll',
- 'Document.querySelectorAll',
- 'DocumentFragment.querySelectorAll',
- 'Element.getBoundingClientRect',
- 'Element.getClientRects',
- 'Node.appendChild',
- 'Node.removeChild',
- 'Node.replaceChild',
- 'Node.attributes',
- 'Node.childNodes',
- 'Document.createElement',
- 'Document.createElementNS',
- 'Document.createEvent',
- 'Document.createTextNode',
- 'Document.createTouchList',
- 'Window.getComputedStyle',
- 'EventTarget.removeEventListener',
- 'EventTarget.addEventListener',
- 'EventTarget.dispatchEvent',
- 'Event.initEvent',
- 'MouseEvent.initMouseEvent',
-])
-
-# Members from the standard dom that exist in the dart:html library with
-# identical functionality but with cleaner names.
-_html_library_renames = {
- 'Document.defaultView': 'window',
- 'DocumentFragment.querySelector': 'query',
- 'NodeSelector.querySelector': 'query',
- 'Element.querySelector': 'query',
- 'Element.webkitMatchesSelector' : 'matchesSelector',
- 'Element.scrollIntoViewIfNeeded': 'scrollIntoView',
- 'Document.querySelector': 'query',
- 'Node.cloneNode': 'clone',
- 'Node.nextSibling': 'nextNode',
- 'Node.ownerDocument': 'document',
- 'Node.parentNode': 'parent',
- 'Node.previousSibling': 'previousNode',
- 'Node.textContent': 'text',
- 'SVGElement.className': '_svgClassName',
- 'SVGAnimatedString.className': '_svgClassName',
- 'SVGStylable.className': '_svgClassName',
-}
-
-#TODO(jacobr): inject annotations into the interfaces based on this table and
-# on _html_library_renames.
-_injected_doc_fragments = {
- 'Element.query': ' /** @domName querySelector, Document.getElementById */',
-}
-# Members and classes from the dom that should be removed completelly from
-# dart:html. These could be expressed in the IDL instead but expressing this
-# as a simple table instead is more concise.
-# Syntax is: ClassName.(get\.|set\.)?MemberName
-# Using get: and set: is optional and should only be used when a getter needs
-# to be suppressed but not the setter, etc.
-# TODO(jacobr): cleanup and augment this list.
-_html_library_remove = set([
- 'Window.get:document', # Removed as we have a custom implementation.
- 'NodeList.item',
- "Attr.*",
-# "BarProp.*",
-# "BarInfo.*",
-# "Blob.webkitSlice",
-# "CDATASection.*",
-# "Comment.*",
-# "DOMImplementation.*",
- "Document.get:documentElement",
- "Document.get:forms",
-# "Document.get:selectedStylesheetSet",
-# "Document.set:selectedStylesheetSet",
-# "Document.get:preferredStylesheetSet",
- "Document.get:links",
- "Document.getElementsByTagName",
- "Document.set:domain",
- "Document.get:implementation",
- "Document.createAttributeNS",
- "Document.get:inputEncoding",
- "Document.getElementById",
- "Document.getElementsByClassName",
- "Document.get:height",
- "Document.get:width",
- "Element.getElementsByClassName",
- "Element.getElementsByTagNameNS",
- "Element.getElementsByTagName",
- "Document.get:compatMode",
- "Document.importNode",
- "Document.evaluate",
- "Document.get:images",
- "Document.querySelector",
- "Document.createExpression",
- "Document.getOverrideStyle",
- "Document.xmlStandalone",
- "Document.createComment",
- "Document.adoptNode",
- "Document.get:characterSet",
- "Document.createAttribute",
- "Document.querySelectorAll",
- "Document.get:URL",
- "Document.createEntityReference",
- "Document.get:documentURI",
- "Document.set:documentURI",
- "Document.createNodeIterator",
- "Document.createProcessingInstruction",
- "Document.get:doctype",
- "Document.getElementsByName",
- "Document.createTreeWalker",
- "Document.location",
- "Document.createNSResolver",
- "Document.get:xmlEncoding",
- "Document.get:defaultCharset",
- "Document.get:applets",
- "Document.getSelection",
- "Document.xmlVersion",
- "Document.get:anchors",
- "Document.getElementsByTagNameNS",
- "DocumentType.*",
- "Element.hasAttributeNS",
- "Element.getAttributeNS",
- "Element.setAttributeNode",
- "Element.getAttributeNode",
- "Element.removeAttributeNode",
- "Element.removeAttributeNS",
- "Element.setAttributeNodeNS",
- "Element.getAttributeNodeNS",
- "Element.setAttributeNS",
- "BodyElement.text",
- "AnchorElement.text",
- "OptionElement.text",
- "ScriptElement.text",
- "TitleElement.text",
-# "EventSource.get:url",
-# TODO(jacobr): should these be removed?
- "Document.close",
- "Document.hasFocus",
-
- "Document.vlinkColor",
- "Document.captureEvents",
- "Document.releaseEvents",
- "Document.get:compatMode",
- "Document.designMode",
- "Document.dir",
- "Document.all",
- "Document.write",
- "Document.fgColor",
- "Document.bgColor",
- "Document.get:plugins",
- "Document.alinkColor",
- "Document.get:embeds",
- "Document.open",
- "Document.clear",
- "Document.get:scripts",
- "Document.writeln",
- "Document.linkColor",
- "Element.get:itemRef",
- "Element.outerText",
- "Element.accessKey",
- "Element.get:itemType",
- "Element.innerText",
- "Element.set:outerHTML",
- "Element.itemScope",
- "Element.itemValue",
- "Element.itemId",
- "Element.get:itemProp",
- 'Element.scrollIntoView',
- 'Element.get:classList',
- "EmbedElement.getSVGDocument",
- "FormElement.get:elements",
- "HTMLFrameElement.*",
- "HTMLFrameSetElement.*",
- "HtmlElement.version",
- "HtmlElement.manifest",
- "Document.version",
- "Document.manifest",
-# "IFrameElement.getSVGDocument", #TODO(jacobr): should this be removed
- "InputElement.dirName",
- "HTMLIsIndexElement.*",
- "ObjectElement.getSVGDocument",
- "HTMLOptionsCollection.*",
- "HTMLPropertiesCollection.*",
- "SelectElement.remove",
- "TextAreaElement.dirName",
- "NamedNodeMap.*",
- "Node.isEqualNode",
- "Node.get:TEXT_NODE",
- "Node.hasAttributes",
- "Node.get:DOCUMENT_TYPE_NODE",
- "Node.get:DOCUMENT_POSITION_FOLLOWING",
- "Node.lookupNamespaceURI",
- "Node.get:ELEMENT_NODE",
- "Node.get:namespaceURI",
- "Node.get:DOCUMENT_FRAGMENT_NODE",
- "Node.get:localName",
- "Node.dispatchEvent",
- "Node.isDefaultNamespace",
- "Node.compareDocumentPosition",
- "Node.get:baseURI",
- "Node.isSameNode",
- "Node.get:DOCUMENT_POSITION_DISCONNECTED",
- "Node.get:DOCUMENT_NODE",
- "Node.get:DOCUMENT_POSITION_CONTAINS",
- "Node.get:COMMENT_NODE",
- "Node.get:ENTITY_REFERENCE_NODE",
- "Node.isSupported",
- "Node.get:firstChild",
- "Node.get:DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC",
- "Node.get:lastChild",
- "Node.get:NOTATION_NODE",
- "Node.normalize",
- "Node.get:parentElement",
- "Node.get:ATTRIBUTE_NODE",
- "Node.get:ENTITY_NODE",
- "Node.get:DOCUMENT_POSITION_CONTAINED_BY",
- "Node.get:prefix",
- "Node.set:prefix",
- "Node.get:DOCUMENT_POSITION_PRECEDING",
- "Node.get:nodeType",
- "Node.removeEventListener",
- "Node.get:nodeValue",
- "Node.set:nodeValue",
- "Node.get:CDATA_SECTION_NODE",
- "Node.get:nodeName",
- "Node.addEventListener",
- "Node.lookupPrefix",
- "Node.get:PROCESSING_INSTRUCTION_NODE",
- "Notification.dispatchEvent",
- "Notification.addEventListener",
- "Notification.removeEventListener"])
-
-# Events without onEventName attributes in the IDL we want to support.
-# We can automatically extract most event event names by checking for
-# onEventName methods in the IDL but some events aren't listed so we need
-# to manually add them here so that they are easy for users to find.
-_html_manual_events = {
- 'Element': ['touchleave', 'webkitTransitionEnd'],
- 'Window': ['DOMContentLoaded']
-}
-
-# These event names must be camel case when attaching event listeners
-# using addEventListener even though the onEventName properties in the DOM for
-# them are not camel case.
-_on_attribute_to_event_name_mapping = {
- 'webkitanimationend': 'webkitAnimationEnd',
- 'webkitanimationiteration': 'webkitAnimationIteration',
- 'webkitanimationstart': 'webkitAnimationStart',
- 'webkitspeechchange': 'webkitSpeechChange',
- 'webkittransitionend': 'webkitTransitionEnd',
-}
-
-# Mapping from raw event names to the pretty camelCase event names exposed as
-# properties in dart:html. If the DOM exposes a new event name, you will need
-# to add the lower case to camel case conversion for that event name here.
-_html_event_names = {
- 'DOMContentLoaded': 'contentLoaded',
- 'touchleave': 'touchLeave',
- 'abort': 'abort',
- 'beforecopy': 'beforeCopy',
- 'beforecut': 'beforeCut',
- 'beforepaste': 'beforePaste',
- 'beforeunload': 'beforeUnload',
- 'blur': 'blur',
- 'cached': 'cached',
- 'canplay': 'canPlay',
- 'canplaythrough': 'canPlayThrough',
- 'change': 'change',
- 'checking': 'checking',
- 'click': 'click',
- 'close': 'close',
- 'contextmenu': 'contextMenu',
- 'copy': 'copy',
- 'cut': 'cut',
- 'dblclick': 'doubleClick',
- 'devicemotion': 'deviceMotion',
- 'deviceorientation': 'deviceOrientation',
- 'display': 'display',
- 'downloading': 'downloading',
- 'drag': 'drag',
- 'dragend': 'dragEnd',
- 'dragenter': 'dragEnter',
- 'dragleave': 'dragLeave',
- 'dragover': 'dragOver',
- 'dragstart': 'dragStart',
- 'drop': 'drop',
- 'durationchange': 'durationChange',
- 'emptied': 'emptied',
- 'ended': 'ended',
- 'error': 'error',
- 'focus': 'focus',
- 'hashchange': 'hashChange',
- 'input': 'input',
- 'invalid': 'invalid',
- 'keydown': 'keyDown',
- 'keypress': 'keyPress',
- 'keyup': 'keyUp',
- 'load': 'load',
- 'loadeddata': 'loadedData',
- 'loadedmetadata': 'loadedMetadata',
- 'loadend': 'loadEnd',
- 'loadstart': 'loadStart',
- 'message': 'message',
- 'mousedown': 'mouseDown',
- 'mousemove': 'mouseMove',
- 'mouseout': 'mouseOut',
- 'mouseover': 'mouseOver',
- 'mouseup': 'mouseUp',
- 'mousewheel': 'mouseWheel',
- 'noupdate': 'noUpdate',
- 'obsolete': 'obsolete',
- 'offline': 'offline',
- 'online': 'online',
- 'open': 'open',
- 'pagehide': 'pageHide',
- 'pageshow': 'pageShow',
- 'paste': 'paste',
- 'pause': 'pause',
- 'play': 'play',
- 'playing': 'playing',
- 'popstate': 'popState',
- 'progress': 'progress',
- 'ratechange': 'rateChange',
- 'readystatechange': 'readyStateChange',
- 'reset': 'reset',
- 'resize': 'resize',
- 'scroll': 'scroll',
- 'search': 'search',
- 'seeked': 'seeked',
- 'seeking': 'seeking',
- 'select': 'select',
- 'selectionchange': 'selectionChange',
- 'selectstart': 'selectStart',
- 'show': 'show',
- 'stalled': 'stalled',
- 'storage': 'storage',
- 'submit': 'submit',
- 'suspend': 'suspend',
- 'timeupdate': 'timeUpdate',
- 'touchcancel': 'touchCancel',
- 'touchend': 'touchEnd',
- 'touchmove': 'touchMove',
- 'touchstart': 'touchStart',
- 'unload': 'unload',
- 'updateready': 'updateReady',
- 'volumechange': 'volumeChange',
- 'waiting': 'waiting',
- 'webkitAnimationEnd': 'animationEnd',
- 'webkitAnimationIteration': 'animationIteration',
- 'webkitAnimationStart': 'animationStart',
- 'webkitfullscreenchange': 'fullscreenChange',
- 'webkitfullscreenerror': 'fullscreenError',
- 'webkitSpeechChange': 'speechChange',
- 'webkitTransitionEnd': 'transitionEnd'
-}
-
-# These classes require an explicit declaration for the "on" method even though
-# they don't declare any unique events, because the concrete class hierarchy
-# doesn't match the interface hierarchy.
-_html_explicit_event_classes = set(['DocumentFragment'])
-
-def _OnAttributeToEventName(on_method):
- event_name = on_method.id[2:]
- if event_name in _on_attribute_to_event_name_mapping:
- return _on_attribute_to_event_name_mapping[event_name]
- else:
- return event_name
-
-def _DomToHtmlEvents(interface_id, events):
- event_names = set(map(_OnAttributeToEventName, events))
- if interface_id in _html_manual_events:
- for manual_event_name in _html_manual_events[interface_id]:
- event_names.add(manual_event_name)
-
- return sorted(event_names, key=lambda name: _html_event_names[name])
-
-# ------------------------------------------------------------------------------
-class HtmlSystemShared(object):
-
- def __init__(self, database, generator):
- self._event_classes = set()
- self._seen_event_names = {}
- self._database = database
- self._generator = generator
-
- def _AllowInHtmlLibrary(self, interface, member, member_prefix):
- return not self._Matches(interface, member, member_prefix,
- _html_library_remove)
-
- def _Matches(self, interface, member, member_prefix, candidates):
- for interface_name in self._AllAncestorInterfaces(interface):
- if (DartType(interface_name) + '.' + member in candidates or
- DartType(interface_name) + '.' + member_prefix + member in candidates):
- return True
- return False
-
- def MaybeReturnDocument(self, return_type):
- """
- To make it appear that there are not a distinct Document and
- HTMLHtmlElement (document.documentElement) objects we always use
- documentElement instead of the regular document object so must not
- allow a regular document to leak out.
- """
- # TODO(jacobr): any method that returns a Node could also theoretically
- # really return a Document but there are alot of methods that return nodes
- # and they all appear to be safe. Consider the alternate strategy of
- # whitelisting just the known safe methods that return Nodes.
- return (DartType(return_type) == 'EventTarget' or
- DartType(return_type) == 'Document')
-
- def _AllAncestorInterfaces(self, interface):
- interfaces = ([interface.id] +
- self._generator._AllImplementedInterfaces(interface))
- return interfaces
-
- def RenameInHtmlLibrary(self, interface, member, member_prefix=''):
- """
- Returns the name of the member in the HTML library or None if the member is
- suppressed in the HTML library
- """
- if not self._AllowInHtmlLibrary(interface, member, member_prefix):
- return None
-
- for interface_name in self._AllAncestorInterfaces(interface):
- name = interface_name + '.' + member
- if name in _html_library_renames:
- return _html_library_renames[name]
- name = interface.id + '.' + member_prefix + member
- if name in _html_library_renames:
- return _html_library_renames[name]
-
- if self._PrivateInHtmlLibrary(interface, member, member_prefix):
- return '_' + member
-
- # No rename required
- return member
-
- def _PrivateInHtmlLibrary(self, interface, member, member_prefix):
- return self._Matches(interface, member, member_prefix,
- _private_html_members)
-
- # TODO(jacobr): this already exists
- def _TraverseParents(self, interface, callback):
- for parent in interface.parents:
- parent_id = parent.type.id
- if self._database.HasInterface(parent_id):
- parent_interface = self._database.GetInterface(parent_id)
- callback(parent_interface)
- self._TraverseParents(parent_interface, callback)
-
- # TODO(jacobr): this isn't quite right....
- def GetParentsEventsClasses(self, interface):
- # Ugly hack as we don't specify that Document and DocumentFragment inherit
- # from Element in our IDL.
- if interface.id == 'Document' or interface.id == 'DocumentFragment':
- return ['ElementEvents']
-
- interfaces_with_events = set()
- def visit(parent):
- if parent.id in self._event_classes:
- interfaces_with_events.add(parent)
-
- self._TraverseParents(interface, visit)
- if len(interfaces_with_events) == 0:
- return ['Events']
- else:
- names = []
- for interface in interfaces_with_events:
- names.append(interface.id + 'Events')
- return names
-
- def GetParentEventsClass(self, interface):
- parent_event_classes = self.GetParentsEventsClasses(interface)
- if len(parent_event_classes) != 1:
- raise Exception('Only one parent event class allowed ' + interface.id)
- return parent_event_classes[0]
-
- def _ImplClassName(self, type_name):
- return '_' + type_name + 'Impl'
-
- # This returns two values: the first is whether or not an "on" property should
- # be generated for the interface, and the second is the event attributes to
- # generate if it should.
- def GetEventAttributes(self, interface):
- events = set([attr for attr in interface.attributes
- if self._generator._IsEventAttribute(interface, attr)])
-
- if events or interface.id in _html_explicit_event_classes:
- return True, events
- else:
- return False, None
-
- def IsPrivate(self, name):
- return name.startswith('_')
-
-class HtmlSystem(System):
-
- def __init__(self, templates, database, emitters, output_dir, generator):
- super(HtmlSystem, self).__init__(
- templates, database, emitters, output_dir)
- self._shared = HtmlSystemShared(database, generator)
-
-class HtmlInterfacesSystem(HtmlSystem):
-
- def __init__(self, templates, database, emitters, output_dir, generator):
- super(HtmlInterfacesSystem, self).__init__(
- templates, database, emitters, output_dir, generator)
- self._dart_interface_file_paths = []
-
- def InterfaceGenerator(self,
- interface,
- common_prefix,
- super_interface_name,
- source_filter):
- """."""
- interface_name = interface.id
- dart_interface_file_path = self._FilePathForDartInterface(interface_name)
-
- self._dart_interface_file_paths.append(dart_interface_file_path)
-
- dart_interface_code = self._emitters.FileEmitter(dart_interface_file_path)
-
- template_file = 'interface_%s.darttemplate' % interface_name
- template = self._templates.TryLoad(template_file)
- if not template:
- template = self._templates.Load('interface.darttemplate')
-
- return HtmlDartInterfaceGenerator(
- interface, dart_interface_code,
- template,
- common_prefix, super_interface_name,
- source_filter, self, self._shared)
-
- def ProcessCallback(self, interface, info):
- """Generates a typedef for the callback interface."""
- interface_name = interface.id
- file_path = self._FilePathForDartInterface(interface_name)
- self._ProcessCallback(interface, info, file_path)
-
- def GenerateLibraries(self, lib_dir):
- pass
-
-
- def _FilePathForDartInterface(self, interface_name):
- """Returns the file path of the Dart interface definition."""
- # TODO(jmesserly): is this the right path
- return os.path.join(self._output_dir, 'html', 'interface',
- '%s.dart' % interface_name)
-
-# ------------------------------------------------------------------------------
-
-# TODO(jmesserly): inheritance is probably not the right way to factor this long
-# term, but it makes merging better for now.
-class HtmlDartInterfaceGenerator(DartInterfaceGenerator):
- """Generates Dart Interface definition for one DOM IDL interface."""
-
- def __init__(self, interface, emitter, template,
- common_prefix, super_interface, source_filter, system, shared):
- super(HtmlDartInterfaceGenerator, self).__init__(interface,
- emitter, template, common_prefix, super_interface, source_filter)
- self._system = system
- self._shared = shared
-
- def StartInterface(self):
- typename = self._interface.id
-
- extends = []
- suppressed_extends = []
-
- for parent in self._interface.parents:
- # TODO(vsm): Remove source_filter.
- if MatchSourceFilter(self._source_filter, parent):
- # Parent is a DOM type.
- extends.append(DartType(parent.type.id))
- elif '<' in parent.type.id:
- # Parent is a Dart collection type.
- # TODO(vsm): Make this check more robust.
- extends.append(DartType(parent.type.id))
- else:
- suppressed_extends.append('%s.%s' %
- (self._common_prefix, DartType(parent.type.id)))
-
- comment = ' extends'
- extends_str = ''
- if extends:
- extends_str += ' extends ' + ', '.join(extends)
- comment = ','
- if suppressed_extends:
- extends_str += ' /*%s %s */' % (comment, ', '.join(suppressed_extends))
-
- factory_provider = None
- constructor_info = AnalyzeConstructor(self._interface)
- if constructor_info:
- factory_provider = '_' + typename + 'FactoryProvider';
-
- if typename in interface_factories:
- factory_provider = interface_factories[typename]
-
- if factory_provider:
- extends_str += ' default ' + factory_provider
-
- # TODO(vsm): Add appropriate package / namespace syntax.
- (self._members_emitter,
- self._top_level_emitter) = self._emitter.Emit(
- self._template + '$!TOP_LEVEL',
- ID=typename,
- EXTENDS=extends_str)
-
- if constructor_info:
- self._members_emitter.Emit(
- '\n'
- ' $CTOR($PARAMS);\n',
- CTOR=typename,
- PARAMS=constructor_info.ParametersInterfaceDeclaration());
-
- element_type = MaybeTypedArrayElementType(self._interface)
- if element_type:
- self._members_emitter.Emit(
- '\n'
- ' $CTOR(int length);\n'
- '\n'
- ' $CTOR.fromList(List<$TYPE> list);\n'
- '\n'
- ' $CTOR.fromBuffer(ArrayBuffer buffer);\n',
- CTOR=self._interface.id,
- TYPE=DartType(element_type))
-
- emit_events, events = self._shared.GetEventAttributes(self._interface)
- if not emit_events:
- return
- elif events:
- self.AddEventAttributes(events)
- else:
- self._EmitEventGetter(self._shared.GetParentEventsClass(self._interface))
-
- def AddAttribute(self, getter, setter):
- html_getter_name = self._shared.RenameInHtmlLibrary(
- self._interface, DartDomNameOfAttribute(getter), 'get:')
- html_setter_name = self._shared.RenameInHtmlLibrary(
- self._interface, DartDomNameOfAttribute(getter), 'set:')
-
- if not html_getter_name or self._shared.IsPrivate(html_getter_name):
- getter = None
- if not html_setter_name or self._shared.IsPrivate(html_setter_name):
- setter = None
- if not getter and not setter:
- return
-
- # We don't yet handle inconsistent renames of the getter and setter yet.
- if html_getter_name and html_setter_name:
- assert html_getter_name == html_setter_name
- if (getter and setter and
- DartType(getter.type.id) == DartType(setter.type.id)):
- self._members_emitter.Emit('\n $TYPE $NAME;\n',
- NAME=html_getter_name,
- TYPE=DartType(getter.type.id));
- return
- if getter and not setter:
- self._members_emitter.Emit('\n final $TYPE $NAME;\n',
- NAME=html_getter_name,
- TYPE=DartType(getter.type.id));
- return
- raise Exception('Unexpected getter/setter combination %s %s' %
- (getter, setter))
-
- def AddOperation(self, info):
- """
- Arguments:
- operations - contains the overloads, one or more operations with the same
- name.
- """
- html_name = self._shared.RenameInHtmlLibrary(self._interface, info.name)
- if html_name and not self._shared.IsPrivate(html_name):
- self._members_emitter.Emit('\n'
- ' $TYPE $NAME($PARAMS);\n',
- TYPE=info.type_name,
- NAME=html_name,
- PARAMS=info.ParametersInterfaceDeclaration())
-
- def FinishInterface(self):
- pass
-
- def AddConstant(self, constant):
- self._EmitConstant(self._members_emitter, constant)
-
- def AddEventAttributes(self, event_attrs):
- event_attrs = _DomToHtmlEvents(self._interface.id, event_attrs)
- self._shared._event_classes.add(self._interface.id)
- events_interface = self._interface.id + 'Events'
- self._EmitEventGetter(events_interface)
-
- events_members = self._emitter.Emit(
- '\ninterface $INTERFACE extends $PARENTS {\n$!MEMBERS}\n',
- INTERFACE=events_interface,
- PARENTS=', '.join(
- self._shared.GetParentsEventsClasses(self._interface)))
-
- for event_name in event_attrs:
- if event_name in _html_event_names:
- events_members.Emit('\n EventListenerList get $NAME();\n',
- NAME=_html_event_names[event_name])
- else:
- raise Exception('No known html even name for event: ' + event_name)
-
- def _EmitEventGetter(self, events_interface):
- self._members_emitter.Emit('\n $TYPE get on();\n',
- TYPE=events_interface)
-
-# ------------------------------------------------------------------------------
-
-# TODO(jmesserly): inheritance is probably not the right way to factor this long
-# term, but it makes merging better for now.
-class HtmlFrogClassGenerator(FrogInterfaceGenerator):
- """Generates a Frog class for the dart:html library from a DOM IDL
- interface.
- """
-
- def __init__(self, system, interface, template, super_interface, dart_code,
- shared):
- super(HtmlFrogClassGenerator, self).__init__(
- system, interface, template, super_interface, dart_code)
- self._shared = shared
-
- def _ImplClassName(self, type_name):
- return self._shared._ImplClassName(type_name)
-
- def StartInterface(self):
- interface = self._interface
- interface_name = interface.id
-
- self._class_name = self._ImplClassName(interface_name)
-
- base = None
- if interface.parents:
- supertype = interface.parents[0].type.id
- if IsDartCollectionType(supertype):
- # List methods are injected in AddIndexer.
- pass
- else:
- base = self._ImplClassName(supertype)
-
- native_spec = MakeNativeSpec(interface.javascript_binding_name)
-
- extends = ' extends ' + base if base else ''
-
- # TODO: Include all implemented interfaces, including other Lists.
- implements = [interface_name]
- element_type = MaybeTypedArrayElementType(self._interface)
- if element_type:
- implements.append('List<%s>' % DartType(element_type))
-
- self._members_emitter = self._dart_code.Emit(
- self._template,
- #class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
- #$!MEMBERS
- #}
- CLASSNAME=self._class_name,
- EXTENDS=extends,
- IMPLEMENTS=' implements ' + ', '.join(implements),
- NATIVESPEC=' native "' + native_spec + '"')
-
- if element_type:
- self.AddTypedArrayConstructors(element_type)
-
- # Emit a factory provider class for the constructor.
- constructor_info = AnalyzeConstructor(interface)
- if constructor_info:
- self._EmitFactoryProvider(interface_name, constructor_info)
-
- emit_events, events = self._shared.GetEventAttributes(self._interface)
- if not emit_events:
- return
- elif events:
- self.AddEventAttributes(events)
- else:
- parent_events_class = self._shared.GetParentEventsClass(self._interface)
- self._EmitEventGetter('_' + parent_events_class + 'Impl')
-
- def _EmitFactoryProvider(self, interface_name, constructor_info):
- template_file = 'factoryprovider_%s.darttemplate' % interface_name
- template = self._system._templates.TryLoad(template_file)
- if not template:
- template = self._system._templates.Load('factoryprovider.darttemplate')
-
- factory_provider = '_' + interface_name + 'FactoryProvider'
- emitter = self._system._ImplFileEmitter(factory_provider)
- emitter.Emit(
- template,
- FACTORYPROVIDER=factory_provider,
- CONSTRUCTOR=interface_name,
- PARAMETERS=constructor_info.ParametersImplementationDeclaration(),
- NAMED_CONSTRUCTOR=constructor_info.name or interface_name,
- ARGUMENTS=constructor_info.ParametersAsArgumentList())
-
- def AddIndexer(self, element_type):
- """Adds all the methods required to complete implementation of List."""
- # We would like to simply inherit the implementation of everything except
- # get length(), [], and maybe []=. It is possible to extend from a base
- # array implementation class only when there is no other implementation
- # inheritance. There might be no implementation inheritance other than
- # DOMBaseWrapper for many classes, but there might be some where the
- # array-ness is introduced by a non-root interface:
- #
- # interface Y extends X, List<T> ...
- #
- # In the non-root case we have to choose between:
- #
- # class YImpl extends XImpl { add List<T> methods; }
- #
- # and
- #
- # class YImpl extends ListBase<T> { copies of transitive XImpl methods; }
- #
- self._members_emitter.Emit(
- '\n'
- ' $TYPE operator[](int index) native "return this[index];";\n',
- TYPE=self._NarrowOutputType(element_type))
-
- if 'CustomIndexedSetter' in self._interface.ext_attrs:
- self._members_emitter.Emit(
- '\n'
- ' void operator[]=(int index, $TYPE value) native "this[index] = value";\n',
- TYPE=self._NarrowInputType(element_type))
- else:
- # The HTML library implementation of NodeList has a custom indexed setter
- # implementation that uses the parent node the NodeList is associated
- # with if one is available.
- if self._interface.id != 'NodeList':
- self._members_emitter.Emit(
- '\n'
- ' void operator[]=(int index, $TYPE value) {\n'
- ' throw new UnsupportedOperationException("Cannot assign element of immutable List.");\n'
- ' }\n',
- TYPE=self._NarrowInputType(element_type))
-
- # TODO(sra): Use separate mixins for mutable implementations of List<T>.
- # TODO(sra): Use separate mixins for typed array implementations of List<T>.
- if self._interface.id != 'NodeList':
- template_file = 'immutable_list_mixin.darttemplate'
- template = self._system._templates.Load(template_file)
- self._members_emitter.Emit(template, E=DartType(element_type))
-
- def AddAttribute(self, getter, setter):
-
- html_getter_name = self._shared.RenameInHtmlLibrary(
- self._interface, DartDomNameOfAttribute(getter), 'get:')
- html_setter_name = self._shared.RenameInHtmlLibrary(
- self._interface, DartDomNameOfAttribute(getter), 'set:')
-
- if not html_getter_name:
- getter = None
- if not html_setter_name:
- setter = None
-
- if not getter and not setter:
- return
-
- if ((getter and (html_getter_name != getter.id or
- self._shared.MaybeReturnDocument(getter.type.id))) or
- (setter and (html_setter_name != setter.id or
- self._shared.MaybeReturnDocument(setter.type.id))) or
- self._interface.id == 'Document'):
- if getter:
- self._AddRenamingGetter(getter, html_getter_name)
- if setter:
- self._AddRenamingSetter(setter, html_setter_name)
- return
-
- # If the (getter, setter) pair is shadowing, we can't generate a shadowing
- # field (Issue 1633).
- (super_getter, super_getter_interface) = self._FindShadowedAttribute(getter)
- (super_setter, super_setter_interface) = self._FindShadowedAttribute(setter)
- if super_getter or super_setter:
- if getter and not setter and super_getter and not super_setter:
- if DartType(getter.type.id) == DartType(super_getter.type.id):
- # Compatible getter, use the superclass property. This works because
- # JavaScript will do its own dynamic dispatch.
- output_type = getter and self._NarrowOutputType(getter.type.id)
- self._members_emitter.Emit(
- '\n'
- ' // Use implementation from $SUPER.\n'
- ' // final $TYPE $NAME;\n',
- SUPER=super_getter_interface.id,
- NAME=DartDomNameOfAttribute(getter),
- TYPE=output_type)
- return
-
- self._members_emitter.Emit('\n // Shadowing definition.')
- self._AddAttributeUsingProperties(getter, setter)
- return
-
- output_type = getter and self._NarrowOutputType(getter.type.id)
- input_type = setter and self._NarrowInputType(setter.type.id)
- if getter and setter and input_type == output_type:
- self._members_emitter.Emit(
- '\n $TYPE $NAME;\n',
- NAME=DartDomNameOfAttribute(getter),
- TYPE=output_type)
- return
- if getter and not setter:
- self._members_emitter.Emit(
- '\n final $TYPE $NAME;\n',
- NAME=DartDomNameOfAttribute(getter),
- TYPE=output_type)
- return
- self._AddAttributeUsingProperties(getter, setter)
-
- def _AddAttributeUsingProperties(self, getter, setter):
- if getter:
- self._AddGetter(getter)
- if setter:
- self._AddSetter(setter)
-
- def _AddGetter(self, attr):
- self._AddRenamingGetter(attr, DartDomNameOfAttribute(attr))
-
- def _AddSetter(self, attr):
- self._AddRenamingSetter(attr, DartDomNameOfAttribute(attr))
-
- def _AddRenamingGetter(self, attr, html_name):
- return_type = self._NarrowOutputType(attr.type.id)
- if self._shared.MaybeReturnDocument(attr.type.id):
- self._members_emitter.Emit(
- '\n $TYPE get $(HTML_NAME)() => '
- '_FixHtmlDocumentReference(_$(HTML_NAME));\n',
- HTML_NAME=html_name,
- TYPE=return_type)
- html_name = '_' + html_name
- # For correctness this needs to be the return type of the native helper
- # method due to the fact that the real HTMLDocument object is not typed
- # as a document. TODO(jacobr): we could simplify this.
- return_type = '_EventTargetImpl'
-
- self._members_emitter.Emit(
- '\n $TYPE get $(HTML_NAME)() native "return $(THIS).$NAME;";\n',
- HTML_NAME=html_name,
- NAME=attr.id,
- TYPE=return_type,
- THIS='this.parentNode' if self._interface.id == 'Document' else 'this')
-
- def _AddRenamingSetter(self, attr, html_name):
- self._members_emitter.Emit(
- '\n void set $HTML_NAME($TYPE value)'
- ' native "$(THIS).$NAME = value;";\n',
- HTML_NAME=html_name,
- NAME=attr.id,
- TYPE=self._NarrowInputType(attr.type.id),
- THIS='this.parentNode' if self._interface.id == 'Document' else 'this')
-
- def AddOperation(self, info):
- """
- Arguments:
- info: An OperationInfo object.
- """
- html_name = self._shared.RenameInHtmlLibrary(self._interface, info.name)
- if not html_name:
- return
-
- maybe_return_document = self._shared.MaybeReturnDocument(info.type_name)
-
- # Do we need a native body?
- if (self._interface.id == 'Document' or # Need alternate 'this'
- html_name != info.name or # renamed operation
- maybe_return_document): # need to wrap value
- # For example: use window.document instead of his.parentNode.
- return_type = self._NarrowOutputType(info.type_name)
-
- operation_emitter = self._members_emitter.Emit('$!SCOPE',
- THIS=('this.parentNode' if self._interface.id == 'Document'
- else 'this'),
- TYPE=return_type,
- HTML_NAME=html_name,
- NAME=info.name,
- RETURN='' if return_type == 'void' else 'return ',
- PARAMNAMES=info.ParametersAsArgumentList(),
- PARAMS=info.ParametersImplementationDeclaration(
- lambda type_name: self._NarrowInputType(type_name)))
-
- if maybe_return_document:
- assert len(info.overloads) == 1
- operation_emitter.Emit(
- '\n'
- ' $TYPE $(HTML_NAME)($PARAMS) => '
- '_FixHtmlDocumentReference(_$(HTML_NAME)($PARAMNAMES));\n'
- '\n'
- ' _EventTargetImpl _$(HTML_NAME)($PARAMS)'
- ' native "return $(THIS).$NAME($PARAMNAMES);";\n')
- else:
- operation_emitter.Emit(
- '\n'
- ' $TYPE $(HTML_NAME)($PARAMS)'
- ' native "$(RETURN)$(THIS).$NAME($PARAMNAMES);";\n')
- else:
- self._members_emitter.Emit(
- '\n'
- ' $TYPE $NAME($PARAMS) native;\n',
- TYPE=self._NarrowOutputType(info.type_name),
- NAME=info.name,
- PARAMS=info.ParametersImplementationDeclaration(
- lambda type_name: self._NarrowInputType(type_name)))
-
- def AddEventAttributes(self, event_attrs):
- event_attrs = _DomToHtmlEvents(self._interface.id, event_attrs)
- events_class = '_' + self._interface.id + 'EventsImpl'
- events_interface = self._interface.id + 'Events'
- self._EmitEventGetter(events_class)
-
- self._shared._event_classes.add(self._interface.id)
-
- parent_event_class = self._shared.GetParentEventsClass(self._interface)
-
- # TODO(jacobr): specify the type of _ptr as EventTarget
- events_members = self._dart_code.Emit(
- '\n'
- 'class $CLASSNAME extends $SUPER implements $INTERFACE {\n'
- ' $CLASSNAME(_ptr) : super(_ptr);\n'
- '$!MEMBERS}\n',
- CLASSNAME=events_class,
- INTERFACE=events_interface,
- SUPER='_' + parent_event_class + 'Impl')
-
- for event_name in event_attrs:
- if event_name in _html_event_names:
- events_members.Emit(
- "\n"
- " EventListenerList get $NAME() => _get('$RAWNAME');\n",
- RAWNAME=event_name,
- NAME=_html_event_names[event_name])
- else:
- raise Exception('No known html even name for event: ' + event_name)
-
- def _EmitEventGetter(self, events_class):
- self._members_emitter.Emit(
- '\n $TYPE get on() =>\n new $TYPE($EVENTTARGET);\n',
- TYPE=events_class,
- EVENTTARGET='_jsDocument' if self._interface.id == 'Document'
- else 'this')
-
-# ------------------------------------------------------------------------------
-
-class HtmlFrogSystem(HtmlSystem):
-
- def __init__(self, templates, database, emitters, output_dir, generator):
- super(HtmlFrogSystem, self).__init__(
- templates, database, emitters, output_dir, generator)
- self._dart_frog_file_paths = []
-
-
- def InterfaceGenerator(self,
- interface,
- common_prefix,
- super_interface_name,
- source_filter):
- """."""
- template_file = 'impl_%s.darttemplate' % interface.id
- template = self._templates.TryLoad(template_file)
- if not template:
- template = self._templates.Load('frog_impl.darttemplate')
-
- dart_code = self._ImplFileEmitter(interface.id)
- return HtmlFrogClassGenerator(self, interface, template,
- super_interface_name, dart_code, self._shared)
-
- def GenerateLibraries(self, lib_dir):
- self._GenerateLibFile(
- 'html_frog.darttemplate',
- os.path.join(lib_dir, 'html_frog.dart'),
- (self._interface_system._dart_interface_file_paths +
- self._interface_system._dart_callback_file_paths +
- self._dart_frog_file_paths))
-
- def Finish(self):
- pass
-
- def _ImplFileEmitter(self, name):
- """Returns the file emitter of the Frog implementation file."""
- # TODO(jmesserly): is this the right path
- path = os.path.join(self._output_dir, 'html', 'frog', '%s.dart' % name)
- self._dart_frog_file_paths.append(path)
- return self._emitters.FileEmitter(path)
-
-# -----------------------------------------------------------------------------
-
-class HtmlDartiumSystem(HtmlSystem):
-
- def __init__(self, templates, database, emitters, output_dir, generator):
- """Prepared for generating wrapping implementation.
-
- - Creates emitter for Dart code.
- """
- super(HtmlDartiumSystem, self).__init__(
- templates, database, emitters, output_dir, generator)
- self._shared = HtmlSystemShared(database, generator)
- self._dart_dartium_file_paths = []
- self._wrap_cases = []
-
- def InterfaceGenerator(self,
- interface,
- common_prefix,
- super_interface_name,
- source_filter):
- """."""
- template_file = 'impl_%s.darttemplate' % interface.id
- template = self._templates.TryLoad(template_file)
- # TODO(jacobr): change this name as it is confusing.
- if not template:
- template = self._templates.Load('frog_impl.darttemplate')
-
- dart_code = self._ImplFileEmitter(interface.id)
- return HtmlDartiumInterfaceGenerator(self, interface, template,
- super_interface_name, dart_code, self._BaseDefines(interface),
- self._shared)
-
- def _ImplFileEmitter(self, name):
- """Returns the file emitter of the Dartium implementation file."""
- path = os.path.join(self._output_dir, 'html', 'dartium', '%s.dart' % name)
- self._dart_dartium_file_paths.append(path)
- return self._emitters.FileEmitter(path);
-
- def ProcessCallback(self, interface, info):
- pass
-
- def GenerateLibraries(self, lib_dir):
- # Library generated for implementation.
- self._GenerateLibFile(
- 'html_dartium.darttemplate',
- os.path.join(lib_dir, 'html_dartium.dart'),
- (self._interface_system._dart_interface_file_paths +
- self._interface_system._dart_callback_file_paths +
- self._dart_dartium_file_paths
- ),
- WRAPCASES='\n'.join(self._wrap_cases))
-
- def Finish(self):
- pass
-
-# ------------------------------------------------------------------------------
-
-# TODO(jacobr): there is far too much duplicated code between these bindings
-# and the Frog bindings. A larger scale refactoring needs to be performed to
-# reduce the duplicated logic.
-class HtmlDartiumInterfaceGenerator(object):
- """Generates a wrapper based implementation fo the HTML library that works
- on Dartium. This is not intended to be the final solution for implementing
- dart:html on Dartium. Eventually we should generate direct wrapperless
- dart:html bindings that work on dartium."""
-
- def __init__(self, system, interface, template, super_interface, dart_code,
- base_members, shared):
- """Generates Dart wrapper code for the given interface.
-
- Args:
- system: system that is executing this generator.
- template: template that output is generated into.
- interface: an IDLInterface instance. It is assumed that all types have
- been converted to Dart types (e.g. int, String), unless they are in
- the same package as the interface.
- super_interface: A string or None, the name of the common interface that
- this interface implements, if any.
- dart_code: an Emitter for the file containing the Dart implementation
- class.
- 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.
- shared: functionaly shared across all Html generators.
- """
- self._system = system
- self._interface = interface
- self._super_interface = super_interface
- self._dart_code = dart_code
- self._base_members = base_members
- self._current_secondary_parent = None
- self._shared = shared
- self._template = template
-
- def DomObjectName(self):
- return '_documentPtr' if self._interface.id == 'Document' else '_ptr'
-
- # TODO(jacobr): these 3 methods are duplicated.
- def _NarrowToImplementationType(self, type_name):
- # TODO(sra): Move into the 'system' and cache the result.
- if type_name == 'EventListener':
- # Callbacks are typedef functions so don't have a class.
- return type_name
- if self._system._database.HasInterface(type_name):
- interface = self._system._database.GetInterface(type_name)
- if RecognizeCallback(interface):
- # Callbacks are typedef functions so don't have a class.
- return type_name
- else:
- return self._ImplClassName(type_name)
- return type_name
-
- def _NarrowInputType(self, type_name):
- return self._NarrowToImplementationType(type_name)
-
- def _NarrowOutputType(self, type_name):
- return self._NarrowToImplementationType(type_name)
-
- def StartInterface(self):
-
- interface = self._interface
- interface_name = interface.id
- self._class_name = self._ImplClassName(interface_name)
-
- base = None
- if interface.parents:
- supertype = interface.parents[0].type.id
- if not IsDartListType(supertype):
- base = self._ImplClassName(supertype)
- if IsDartCollectionType(supertype):
- # List methods are injected in AddIndexer.
- pass
- else:
- base = self._ImplClassName(supertype)
-
- # TODO(jacobr): this is fragile. There isn't a guarantee that dart:dom
- # will continue to exactly match the IDL names.
- dom_name = interface.javascript_binding_name
- # We hard code the cases for these classes
- if dom_name != 'HTMLHtmlElement' and dom_name != 'Document':
- self._system._wrap_cases.append(
- ' case "%s": return new %s._wrap(domObject);' %
- (dom_name, self._class_name))
-
- extends = ' extends ' + base if base else ' extends _DOMTypeBase'
-
- # TODO: Include all implemented interfaces, including other Lists.
- implements = [interface_name]
- element_type = MaybeTypedArrayElementType(self._interface)
- if element_type:
- implements.append('List<' + DartType(element_type) + '>')
- implements_str = ', '.join(implements)
-
- (self._members_emitter,
- self._top_level_emitter) = self._dart_code.Emit(
- self._template + '$!TOP_LEVEL',
- #class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
- #$!MEMBERS
- #}
- NATIVESPEC='', # hack to make reusing the same templates work.
- CLASSNAME=self._class_name,
- EXTENDS=extends,
- IMPLEMENTS=' implements ' + implements_str)
-
- # Document requires a custom wrapper.
- if dom_name != 'Document':
- self._members_emitter.Emit(
- ' $(CLASSNAME)._wrap(ptr) : super._wrap(ptr);\n',
- CLASSNAME=self._class_name)
-
- # Emit a factory provider class for the constructor.
- constructor_info = AnalyzeConstructor(interface)
- if constructor_info:
- self._EmitFactoryProvider(interface_name, constructor_info)
-
- emit_events, events = self._shared.GetEventAttributes(self._interface)
- if not emit_events:
- return
- elif events:
- self.AddEventAttributes(events)
- else:
- parent_events_class = self._shared.GetParentEventsClass(self._interface)
- self._EmitEventGetter('_' + parent_events_class + 'Impl')
-
- def _EmitFactoryProvider(self, interface_name, constructor_info):
- template_file = 'factoryprovider_%s.darttemplate' % interface_name
- template = self._system._templates.TryLoad(template_file)
- if not template:
- template = self._system._templates.Load('factoryprovider.darttemplate')
-
- factory_provider = '_' + interface_name + 'FactoryProvider'
- emitter = self._system._ImplFileEmitter(factory_provider)
- emitter.Emit(
- template,
- FACTORYPROVIDER=factory_provider,
- CONSTRUCTOR=interface_name,
- PARAMETERS=constructor_info.ParametersImplementationDeclaration(),
- NAMED_CONSTRUCTOR=constructor_info.name or interface_name,
- ARGUMENTS=self._UnwrappedParameters(constructor_info,
- len(constructor_info.arg_infos)))
-
- def _UnwrappedParameters(self, operation_info, length):
- """Returns string for an argument list that unwraps first |length|
- parameters."""
- def UnwrapArgInfo(arg_info):
- (name, type, value) = arg_info
- # TODO(sra): Type dependent unwrapping.
- return '_unwrap(%s)' % name
-
- return ', '.join(map(UnwrapArgInfo, operation_info.arg_infos[:length]))
-
- def _BaseClassName(self, interface):
- if not interface.parents:
- return '_DOMTypeBase'
-
- supertype = DartType(interface.parents[0].type.id)
-
- if IsDartListType(supertype) or IsDartCollectionType(supertype):
- return 'DOMWrapperBase'
-
- if supertype == 'EventTarget':
- # Most implementors of EventTarget specify the EventListener operations
- # again. If the operations are not specified, try to inherit from the
- # EventTarget implementation.
- #
- # Applies to MessagePort.
- if not [op for op in interface.operations if op.id == 'addEventListener']:
- return self._ImplClassName(supertype)
- return 'DOMWrapperBase'
-
- return self._ImplClassName(supertype)
-
- def _ImplClassName(self, type_name):
- return self._shared._ImplClassName(type_name)
-
- def FinishInterface(self):
- """."""
- pass
-
- def AddConstant(self, constant):
- # Constants are already defined on the interface.
- pass
-
- 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
-
- def AddAttribute(self, getter, setter):
- dom_name = DartDomNameOfAttribute(getter or setter)
- html_getter_name = self._shared.RenameInHtmlLibrary(
- self._interface, dom_name, 'get:')
- html_setter_name = self._shared.RenameInHtmlLibrary(
- self._interface, dom_name, 'set:')
-
- if getter and html_getter_name:
- self._AddGetter(getter, html_getter_name)
- if setter and html_setter_name:
- self._AddSetter(setter, html_setter_name)
-
- def _AddGetter(self, attr, html_name):
- if self._shared.MaybeReturnDocument(attr.type.id):
- self._members_emitter.Emit(
- '\n'
- ' $TYPE get $(HTML_NAME)() => '
- '_FixHtmlDocumentReference(_wrap($(THIS).$DOM_NAME));\n',
- HTML_NAME=html_name,
- DOM_NAME=DartDomNameOfAttribute(attr),
- TYPE=DartType(attr.type.id),
- THIS=self.DomObjectName())
- else:
- self._members_emitter.Emit(
- '\n'
- ' $TYPE get $(HTML_NAME)() => _wrap($(THIS).$DOM_NAME);\n',
- HTML_NAME=html_name,
- DOM_NAME=DartDomNameOfAttribute(attr),
- TYPE=DartType(attr.type.id),
- THIS=self.DomObjectName())
-
- def _AddSetter(self, attr, html_name):
- self._members_emitter.Emit(
- '\n'
- ' void set $(HTML_NAME)($TYPE value) { '
- '$(THIS).$DOM_NAME = _unwrap(value); }\n',
- HTML_NAME=html_name,
- DOM_NAME=DartDomNameOfAttribute(attr),
- TYPE=DartType(attr.type.id),
- THIS=self.DomObjectName())
-
- def AddSecondaryAttribute(self, interface, getter, setter):
- self._SecondaryContext(interface)
- self.AddAttribute(getter, setter)
-
- def AddSecondaryOperation(self, interface, info):
- self._SecondaryContext(interface)
- self.AddOperation(info)
-
- def AddEventAttributes(self, event_attrs):
- event_attrs = _DomToHtmlEvents(self._interface.id, event_attrs)
- events_class = '_' + self._interface.id + 'EventsImpl'
- events_interface = self._interface.id + 'Events'
- self._EmitEventGetter(events_class)
-
- self._shared._event_classes.add(self._interface.id)
-
- parent_event_class = self._shared.GetParentEventsClass(self._interface)
-
- # TODO(jacobr): specify the type of _ptr as EventTarget
- events_members = self._dart_code.Emit(
- '\n'
- 'class $CLASSNAME extends $SUPER implements $INTERFACE {\n'
- ' $CLASSNAME(_ptr) : super(_ptr);\n'
- '$!MEMBERS}\n',
- CLASSNAME=events_class,
- INTERFACE=events_interface,
- SUPER='_' + parent_event_class + 'Impl')
-
- for event_name in event_attrs:
- if event_name in _html_event_names:
- events_members.Emit(
- "\n"
- " EventListenerList get $NAME() => _get('$RAWNAME');\n",
- RAWNAME=event_name,
- NAME=_html_event_names[event_name])
- else:
- raise Exception('No known html even name for event: ' + event_name)
-
- def _EmitEventGetter(self, events_class):
- self._members_emitter.Emit(
- '\n'
- ' $TYPE get on() {\n'
- ' if (_on == null) _on = new $TYPE($EVENTTARGET);\n'
- ' return _on;\n'
- ' }\n',
- TYPE=events_class,
- EVENTTARGET='_wrappedDocumentPtr' if self._interface.id == 'Document'
- else 'this')
-
- def _SecondaryContext(self, interface):
- if interface is not self._current_secondary_parent:
- self._current_secondary_parent = interface
- self._members_emitter.Emit('\n // From $WHERE\n', WHERE=interface.id)
-
- # TODO(jacobr): change this to more directly match the frog version.
- def AddIndexer(self, element_type):
- """Adds all the methods required to complete implementation of List."""
- # We would like to simply inherit the implementation of everything except
- # get length(), [], and maybe []=. It is possible to extend from a base
- # array implementation class only when there is no other implementation
- # inheritance. There might be no implementation inheritance other than
- # DOMBaseWrapper for many classes, but there might be some where the
- # array-ness is introduced by a non-root interface:
- #
- # interface Y extends X, List<T> ...
- #
- # In the non-root case we have to choose between:
- #
- # class YImpl extends XImpl { add List<T> methods; }
- #
- # and
- #
- # class YImpl extends ListBase<T> { copies of transitive XImpl methods; }
- #
- if self._HasNativeIndexGetter(self._interface):
- self._EmitNativeIndexGetter(self._interface, element_type)
- else:
- self._members_emitter.Emit(
- '\n'
- ' $TYPE operator[](int index) => _wrap($(THIS)[index]);\n'
- '\n',
- THIS=self.DomObjectName(),
- TYPE=DartType(element_type))
-
- if self._HasNativeIndexSetter(self._interface):
- self._EmitNativeIndexSetter(self._interface, element_type)
- else:
- # The HTML library implementation of NodeList has a custom indexed setter
- # implementation that uses the parent node the NodeList is associated
- # with if one is available.
- if self._interface.id != 'NodeList':
- self._members_emitter.Emit(
- '\n'
- ' void operator[]=(int index, $TYPE value) {\n'
- ' throw new UnsupportedOperationException("Cannot assign element of immutable List.");\n'
- ' }\n',
- TYPE=DartType(element_type))
-
- # The list interface for this class is manually generated.
- if self._interface.id == 'NodeList':
- return
-
- self._members_emitter.Emit(
- '\n'
- ' void add($TYPE value) {\n'
- ' throw new UnsupportedOperationException("Cannot add to immutable List.");\n'
- ' }\n'
- '\n'
- ' void addLast($TYPE value) {\n'
- ' throw new UnsupportedOperationException("Cannot add to immutable List.");\n'
- ' }\n'
- '\n'
- ' void addAll(Collection<$TYPE> collection) {\n'
- ' throw new UnsupportedOperationException("Cannot add to immutable List.");\n'
- ' }\n'
- '\n'
- ' void sort(int compare($TYPE a, $TYPE b)) {\n'
- ' throw new UnsupportedOperationException("Cannot sort immutable List.");\n'
- ' }\n'
- '\n'
- ' void copyFrom(List<Object> src, int srcStart, '
- 'int dstStart, int count) {\n'
- ' throw new UnsupportedOperationException("This object is immutable.");\n'
- ' }\n'
- '\n'
- ' int indexOf($TYPE element, [int start = 0]) {\n'
- ' return _Lists.indexOf(this, element, start, this.length);\n'
- ' }\n'
- '\n'
- ' int lastIndexOf($TYPE element, [int start = null]) {\n'
- ' if (start === null) start = length - 1;\n'
- ' return _Lists.lastIndexOf(this, element, start);\n'
- ' }\n'
- '\n'
- ' int clear() {\n'
- ' throw new UnsupportedOperationException("Cannot clear immutable List.");\n'
- ' }\n'
- '\n'
- ' $TYPE removeLast() {\n'
- ' throw new UnsupportedOperationException("Cannot removeLast on immutable List.");\n'
- ' }\n'
- '\n'
- ' $TYPE last() {\n'
- ' return this[length - 1];\n'
- ' }\n'
- '\n'
- ' void forEach(void f($TYPE element)) {\n'
- ' _Collections.forEach(this, f);\n'
- ' }\n'
- '\n'
- ' Collection map(f($TYPE element)) {\n'
- ' return _Collections.map(this, [], f);\n'
- ' }\n'
- '\n'
- ' Collection<$TYPE> filter(bool f($TYPE element)) {\n'
- ' return _Collections.filter(this, new List<$TYPE>(), f);\n'
- ' }\n'
- '\n'
- ' bool every(bool f($TYPE element)) {\n'
- ' return _Collections.every(this, f);\n'
- ' }\n'
- '\n'
- ' bool some(bool f($TYPE element)) {\n'
- ' return _Collections.some(this, f);\n'
- ' }\n'
- '\n'
- ' void setRange(int start, int length, List<$TYPE> from, [int startFrom]) {\n'
- ' throw new UnsupportedOperationException("Cannot setRange on immutable List.");\n'
- ' }\n'
- '\n'
- ' void removeRange(int start, int length) {\n'
- ' throw new UnsupportedOperationException("Cannot removeRange on immutable List.");\n'
- ' }\n'
- '\n'
- ' void insertRange(int start, int length, [$TYPE initialValue]) {\n'
- ' throw new UnsupportedOperationException("Cannot insertRange on immutable List.");\n'
- ' }\n'
- '\n'
- ' List<$TYPE> getRange(int start, int length) {\n'
- ' throw new NotImplementedException();\n'
- ' }\n'
- '\n'
- ' bool isEmpty() {\n'
- ' return length == 0;\n'
- ' }\n'
- '\n'
- ' Iterator<$TYPE> iterator() {\n'
- ' return new _FixedSizeListIterator<$TYPE>(this);\n'
- ' }\n',
- TYPE=DartType(element_type))
-
- def _HasNativeIndexGetter(self, interface):
- return ('HasIndexGetter' in interface.ext_attrs or
- 'HasNumericIndexGetter' in interface.ext_attrs)
-
- def _EmitNativeIndexGetter(self, interface, element_type):
- method_name = '_index'
- self._members_emitter.Emit(
- '\n $TYPE operator[](int index) => _wrap($(THIS)[index]);\n',
- TYPE=DartType(element_type),
- THIS=self.DomObjectName(),
- METHOD=method_name)
-
- def _HasNativeIndexSetter(self, interface):
- return 'HasCustomIndexSetter' in interface.ext_attrs
-
- def _EmitNativeIndexSetter(self, interface, element_type):
- method_name = '_set_index'
- self._members_emitter.Emit(
- '\n'
- ' void operator[]=(int index, $TYPE value) {\n'
- ' return $(THIS)[index] = _unwrap(value);\n'
- ' }\n',
- THIS=self.DomObjectName(),
- TYPE=DartType(element_type),
- METHOD=method_name)
-
- def AddOperation(self, info):
- """
- Arguments:
- info: An OperationInfo object.
- """
- html_name = self._shared.RenameInHtmlLibrary(self._interface, info.name)
-
- if not html_name:
- return
-
- body = self._members_emitter.Emit(
- '\n'
- ' $TYPE $HTML_NAME($PARAMS) {\n'
- '$!BODY'
- ' }\n',
- TYPE=info.type_name,
- HTML_NAME=html_name,
- PARAMS=info.ParametersImplementationDeclaration())
-
- # Process in order of ascending number of arguments to ensure missing
- # optional arguments are processed early.
- overloads = sorted(info.overloads,
- key=lambda overload: len(overload.arguments))
- self._native_version = 0
- fallthrough = self.GenerateDispatch(body, info, ' ', 0, overloads)
- if fallthrough:
- body.Emit(' throw "Incorrect number or type of arguments";\n');
-
- def GenerateSingleOperation(self, emitter, info, indent, operation):
- """Generates a call to a single operation.
-
- Arguments:
- emitter: an Emitter for the body of a block of code.
- info: the compound information about the operation and its overloads.
- indent: an indentation string for generated code.
- operation: the IDLOperation to call.
- """
- argument_expressions = self._UnwrappedParameters(
- info,
- len(operation.arguments)) # Just the parameters this far.
-
- if info.type_name != 'void':
- # We could place the logic for handling Document directly in _wrap
- # but we chose to place it here so that bugs in the wrapper and
- # wrapperless implementations are more consistent.
- if self._shared.MaybeReturnDocument(info.type_name):
- emitter.Emit('$(INDENT)return _FixHtmlDocumentReference('
- '_wrap($(THIS).$NAME($ARGS)));\n',
- INDENT=indent,
- THIS=self.DomObjectName(),
- NAME=info.name,
- ARGS=argument_expressions)
- else:
- emitter.Emit('$(INDENT)return _wrap($(THIS).$NAME($ARGS));\n',
- INDENT=indent,
- THIS=self.DomObjectName(),
- NAME=info.name,
- ARGS=argument_expressions)
- else:
- emitter.Emit('$(INDENT)$(THIS).$NAME($ARGS);\n'
- '$(INDENT)return;\n',
- INDENT=indent,
- THIS=self.DomObjectName(),
- NAME=info.name,
- ARGS=argument_expressions)
-
- def GenerateDispatch(self, emitter, info, indent, position, overloads):
- """Generates a dispatch to one of the overloads.
-
- Arguments:
- emitter: an Emitter for the body of a block of code.
- info: the compound information about the operation and its overloads.
- indent: an indentation string for generated code.
- position: the index of the parameter to dispatch on.
- overloads: a list of the remaining IDLOperations to dispatch.
-
- Returns True if the dispatch can fall through on failure, False if the code
- always dispatches.
- """
-
- def NullCheck(name):
- return '%s === null' % name
-
- def TypeCheck(name, type):
- return '%s is %s' % (name, type)
-
- if position == len(info.arg_infos):
- if len(overloads) > 1:
- raise Exception('Duplicate operations ' + str(overloads))
- operation = overloads[0]
- self.GenerateSingleOperation(emitter, info, indent, operation)
- return False
-
- # FIXME: Consider a simpler dispatch that iterates over the
- # overloads and generates an overload specific check. Revisit
- # when we move to named optional arguments.
-
- # Partition the overloads to divide and conquer on the dispatch.
- positive = []
- negative = []
- first_overload = overloads[0]
- (param_name, param_type, param_default) = info.arg_infos[position]
-
- if position < len(first_overload.arguments):
- # FIXME: This will not work if the second overload has a more
- # precise type than the first. E.g.,
- # void foo(Node x);
- # void foo(Element x);
- type = DartType(first_overload.arguments[position].type.id)
- test = TypeCheck(param_name, type)
- pred = lambda op: (len(op.arguments) > position and
- DartType(op.arguments[position].type.id) == type)
- else:
- type = None
- test = NullCheck(param_name)
- pred = lambda op: position >= len(op.arguments)
-
- for overload in overloads:
- if pred(overload):
- positive.append(overload)
- else:
- negative.append(overload)
-
- if positive and negative:
- (true_code, false_code) = emitter.Emit(
- '$(INDENT)if ($COND) {\n'
- '$!TRUE'
- '$(INDENT)} else {\n'
- '$!FALSE'
- '$(INDENT)}\n',
- COND=test, INDENT=indent)
- fallthrough1 = self.GenerateDispatch(
- true_code, info, indent + ' ', position + 1, positive)
- fallthrough2 = self.GenerateDispatch(
- false_code, info, indent + ' ', position, negative)
- return fallthrough1 or fallthrough2
-
- if negative:
- raise Exception('Internal error, must be all positive')
-
- # All overloads require the same test. Do we bother?
-
- # If the test is the same as the method's formal parameter then checked mode
- # will have done the test already. (It could be null too but we ignore that
- # case since all the overload behave the same and we don't know which types
- # in the IDL are not nullable.)
- if type == param_type:
- return self.GenerateDispatch(
- emitter, info, indent, position + 1, positive)
-
- # Otherwise the overloads have the same type but the type is a substype of
- # the method's synthesized formal parameter. e.g we have overloads f(X) and
- # f(Y), implemented by the synthesized method f(Z) where X<Z and Y<Z. The
- # dispatch has removed f(X), leaving only f(Y), but there is no guarantee
- # that Y = Z-X, so we need to check for Y.
- true_code = emitter.Emit(
- '$(INDENT)if ($COND) {\n'
- '$!TRUE'
- '$(INDENT)}\n',
- COND=test, INDENT=indent)
- self.GenerateDispatch(
- true_code, info, indent + ' ', position + 1, positive)
- return True
« no previous file with comments | « client/dom/scripts/systemfrog.py ('k') | client/dom/scripts/systeminterface.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698