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

Side by Side Diff: lib/dom/scripts/systemhtml.py

Issue 9732019: dart:html perf optimization based on runing Dromaeo benchmarks (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fixes Created 8 years, 8 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 2 # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
3 # for details. All rights reserved. Use of this source code is governed by a 3 # for details. All rights reserved. Use of this source code is governed by a
4 # BSD-style license that can be found in the LICENSE file. 4 # BSD-style license that can be found in the LICENSE file.
5 5
6 """This module provides shared functionality for the system to generate 6 """This module provides shared functionality for the system to generate
7 Dart:html APIs from the IDL database.""" 7 Dart:html APIs from the IDL database."""
8 8
9 from systemfrog import * 9 from systemfrog import *
10 from systeminterface import * 10 from systeminterface import *
11 11
12 # Members from the standard dom that should not be exposed publicly in dart:html 12 # Members from the standard dom that should not be exposed publicly in dart:html
13 # but need to be exposed internally to implement dart:html on top of a standard 13 # but need to be exposed internally to implement dart:html on top of a standard
14 # browser. 14 # browser.
15 _private_html_members = set([ 15 _private_html_members = set([
16 'Element.clientLeft',
17 'Element.clientTop',
18 'Element.clientWidth',
19 'Element.clientHeight',
20 'Element.offsetLeft',
21 'Element.offsetTop',
22 'Element.offsetWidth',
23 'Element.offsetHeight',
24 'Element.scrollLeft',
25 'Element.scrollTop',
26 'Element.scrollWidth',
27 'Element.scrollHeight',
28 'Element.childElementCount',
29 'Element.firstElementChild',
30 'Element.hasAttribute',
31 'Element.getAttribute',
32 'Element.removeAttribute',
33 'Element.setAttribute',
34 'Element.className',
35 'Element.children',
36 'Element.querySelectorAll',
37 'NodeSelector.querySelectorAll',
38 'Document.querySelectorAll',
39 'DocumentFragment.querySelectorAll',
40 'Element.getBoundingClientRect',
41 'Element.getClientRects',
42 'Node.appendChild',
43 'Node.removeChild',
44 'Node.replaceChild',
45 'Node.attributes',
46 'Node.childNodes',
47 'Document.createElement', 16 'Document.createElement',
48 'Document.createElementNS', 17 'Document.createElementNS',
49 'Document.createEvent', 18 'Document.createEvent',
50 'Document.createTextNode', 19 'Document.createTextNode',
51 'Document.createTouchList', 20 'Document.createTouchList',
52 'Window.getComputedStyle', 21 'Document.getElementById',
53 'EventTarget.removeEventListener', 22 'Document.getElementsByClassName',
23 'Document.getElementsByName',
24 'Document.getElementsByTagName',
25 'Document.querySelectorAll',
26 'DocumentFragment.querySelectorAll',
27 'Element.childElementCount',
28 'Element.children',
29 'Element.className',
30 'Element.clientHeight',
31 'Element.clientLeft',
32 'Element.clientTop',
33 'Element.clientWidth',
34 'Element.firstElementChild',
35 'Element.getAttribute',
36 'Element.getBoundingClientRect',
37 'Element.getClientRects',
38 'Element.getElementsByClassName',
39 'Element.getElementsByTagName',
40 'Element.hasAttribute',
41 'Element.lastElementChild',
42 'Element.offsetHeight',
43 'Element.offsetLeft',
44 'Element.offsetTop',
45 'Element.offsetWidth',
46 'Element.querySelectorAll',
47 'Element.removeAttribute',
48 'Element.scrollHeight',
49 'Element.scrollLeft',
50 'Element.scrollTop',
51 'Element.scrollWidth',
52 'Element.setAttribute',
53 'Event.initEvent',
54 'EventTarget.addEventListener', 54 'EventTarget.addEventListener',
55 'EventTarget.dispatchEvent', 55 'EventTarget.dispatchEvent',
56 'Event.initEvent', 56 'EventTarget.removeEventListener',
57 'MouseEvent.initMouseEvent', 57 'MouseEvent.initMouseEvent',
58 'Node.appendChild',
59 'Node.attributes',
60 'Node.childNodes',
61 'Node.firstChild',
62 'Node.lastChild',
63 "Node.nodeType",
64 'Node.removeChild',
65 'Node.replaceChild',
66 'NodeSelector.querySelectorAll',
67 'Window.getComputedStyle',
68 ])
69
70 _manually_generated_html_members = set([
71 'Document.querySelectorAll',
72 'Document.querySelector',
58 ]) 73 ])
59 74
60 # Members from the standard dom that exist in the dart:html library with 75 # Members from the standard dom that exist in the dart:html library with
61 # identical functionality but with cleaner names. 76 # identical functionality but with cleaner names.
62 _html_library_renames = { 77 _html_library_renames = {
63 'Document.defaultView': 'window', 78 'Document.defaultView': 'window',
64 'DocumentFragment.querySelector': 'query', 79 'DocumentFragment.querySelector': 'query',
65 'NodeSelector.querySelector': 'query', 80 'NodeSelector.querySelector': 'query',
66 'Element.querySelector': 'query', 81 'Element.querySelector': 'query',
67 'Element.webkitMatchesSelector' : 'matchesSelector', 82 'Element.webkitMatchesSelector' : 'matchesSelector',
68 'Element.scrollIntoViewIfNeeded': 'scrollIntoView', 83 'Element.scrollIntoViewIfNeeded': 'scrollIntoView',
69 'Document.querySelector': 'query',
70 'Node.cloneNode': 'clone', 84 'Node.cloneNode': 'clone',
71 'Node.nextSibling': 'nextNode', 85 'Node.nextSibling': 'nextNode',
72 'Node.ownerDocument': 'document', 86 'Node.ownerDocument': 'document',
73 'Node.parentNode': 'parent', 87 'Node.parentNode': 'parent',
74 'Node.previousSibling': 'previousNode', 88 'Node.previousSibling': 'previousNode',
75 'Node.textContent': 'text', 89 'Node.textContent': 'text',
76 'SVGElement.className': '_svgClassName', 90 'SVGElement.className': '$dom_svgClassName',
77 'SVGAnimatedString.className': '_svgClassName', 91 'SVGAnimatedString.className': '$dom_svgClassName',
78 'SVGStylable.className': '_svgClassName', 92 'SVGStylable.className': '$dom_svgClassName',
79 } 93 }
80 94
81 #TODO(jacobr): inject annotations into the interfaces based on this table and 95 #TODO(jacobr): inject annotations into the interfaces based on this table and
82 # on _html_library_renames. 96 # on _html_library_renames.
83 _injected_doc_fragments = { 97 _injected_doc_fragments = {
84 'Element.query': ' /** @domName querySelector, Document.getElementById */', 98 'Element.query': ' /** @domName querySelector, Document.getElementById */',
85 } 99 }
86 # Members and classes from the dom that should be removed completelly from 100 # Members and classes from the dom that should be removed completelly from
87 # dart:html. These could be expressed in the IDL instead but expressing this 101 # dart:html. These could be expressed in the IDL instead but expressing this
88 # as a simple table instead is more concise. 102 # as a simple table instead is more concise.
89 # Syntax is: ClassName.(get\.|set\.)?MemberName 103 # Syntax is: ClassName.(get\.|set\.)?MemberName
90 # Using get: and set: is optional and should only be used when a getter needs 104 # Using get: and set: is optional and should only be used when a getter needs
91 # to be suppressed but not the setter, etc. 105 # to be suppressed but not the setter, etc.
92 # TODO(jacobr): cleanup and augment this list. 106 # TODO(jacobr): cleanup and augment this list.
93 _html_library_remove = set([ 107 _html_library_remove = set([
94 'Window.get:document', # Removed as we have a custom implementation. 108 'Window.get:document', # Removed as we have a custom implementation.
95 'NodeList.item', 109 'NodeList.item',
96 "Attr.*", 110 "Attr.*",
97 # "BarProp.*", 111 # "BarProp.*",
98 # "BarInfo.*", 112 # "BarInfo.*",
99 # "Blob.webkitSlice", 113 # "Blob.webkitSlice",
100 # "CDATASection.*", 114 # "CDATASection.*",
101 # "Comment.*", 115 # "Comment.*",
102 # "DOMImplementation.*", 116 # "DOMImplementation.*",
103 "Document.get:documentElement",
104 "Document.get:forms", 117 "Document.get:forms",
105 # "Document.get:selectedStylesheetSet", 118 # "Document.get:selectedStylesheetSet",
106 # "Document.set:selectedStylesheetSet", 119 # "Document.set:selectedStylesheetSet",
107 # "Document.get:preferredStylesheetSet", 120 # "Document.get:preferredStylesheetSet",
108 "Document.get:links", 121 "Document.get:links",
109 "Document.getElementsByTagName",
110 "Document.set:domain", 122 "Document.set:domain",
111 "Document.get:implementation", 123 "Document.get:implementation",
112 "Document.createAttributeNS", 124 "Document.createAttributeNS",
113 "Document.get:inputEncoding", 125 "Document.get:inputEncoding",
114 "Document.getElementById",
115 "Document.getElementsByClassName",
116 "Document.get:height", 126 "Document.get:height",
117 "Document.get:width", 127 "Document.get:width",
118 "Element.getElementsByClassName",
119 "Element.getElementsByTagNameNS", 128 "Element.getElementsByTagNameNS",
120 "Element.getElementsByTagName",
121 "Document.get:compatMode", 129 "Document.get:compatMode",
122 "Document.importNode", 130 "Document.importNode",
123 "Document.evaluate", 131 "Document.evaluate",
124 "Document.get:images", 132 "Document.get:images",
125 "Document.querySelector",
126 "Document.createExpression", 133 "Document.createExpression",
127 "Document.getOverrideStyle", 134 "Document.getOverrideStyle",
128 "Document.xmlStandalone", 135 "Document.xmlStandalone",
129 "Document.createComment", 136 "Document.createComment",
130 "Document.adoptNode", 137 "Document.adoptNode",
131 "Document.get:characterSet", 138 "Document.get:characterSet",
132 "Document.createAttribute", 139 "Document.createAttribute",
133 "Document.querySelectorAll",
134 "Document.get:URL", 140 "Document.get:URL",
135 "Document.createEntityReference", 141 "Document.createEntityReference",
136 "Document.get:documentURI", 142 "Document.get:documentURI",
137 "Document.set:documentURI", 143 "Document.set:documentURI",
138 "Document.createNodeIterator", 144 "Document.createNodeIterator",
139 "Document.createProcessingInstruction", 145 "Document.createProcessingInstruction",
140 "Document.get:doctype", 146 "Document.get:doctype",
141 "Document.getElementsByName",
142 "Document.createTreeWalker", 147 "Document.createTreeWalker",
143 "Document.location", 148 "Document.location",
144 "Document.createNSResolver", 149 "Document.createNSResolver",
145 "Document.get:xmlEncoding", 150 "Document.get:xmlEncoding",
146 "Document.get:defaultCharset", 151 "Document.get:defaultCharset",
147 "Document.get:applets", 152 "Document.get:applets",
148 "Document.getSelection", 153 "Document.getSelection",
149 "Document.xmlVersion", 154 "Document.xmlVersion",
150 "Document.get:anchors", 155 "Document.get:anchors",
151 "Document.getElementsByTagNameNS", 156 "Document.getElementsByTagNameNS",
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 "Node.isDefaultNamespace", 235 "Node.isDefaultNamespace",
231 "Node.compareDocumentPosition", 236 "Node.compareDocumentPosition",
232 "Node.get:baseURI", 237 "Node.get:baseURI",
233 "Node.isSameNode", 238 "Node.isSameNode",
234 "Node.get:DOCUMENT_POSITION_DISCONNECTED", 239 "Node.get:DOCUMENT_POSITION_DISCONNECTED",
235 "Node.get:DOCUMENT_NODE", 240 "Node.get:DOCUMENT_NODE",
236 "Node.get:DOCUMENT_POSITION_CONTAINS", 241 "Node.get:DOCUMENT_POSITION_CONTAINS",
237 "Node.get:COMMENT_NODE", 242 "Node.get:COMMENT_NODE",
238 "Node.get:ENTITY_REFERENCE_NODE", 243 "Node.get:ENTITY_REFERENCE_NODE",
239 "Node.isSupported", 244 "Node.isSupported",
240 "Node.get:firstChild",
241 "Node.get:DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC", 245 "Node.get:DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC",
242 "Node.get:lastChild",
243 "Node.get:NOTATION_NODE", 246 "Node.get:NOTATION_NODE",
244 "Node.normalize", 247 "Node.normalize",
245 "Node.get:parentElement", 248 "Node.get:parentElement",
246 "Node.get:ATTRIBUTE_NODE", 249 "Node.get:ATTRIBUTE_NODE",
247 "Node.get:ENTITY_NODE", 250 "Node.get:ENTITY_NODE",
248 "Node.get:DOCUMENT_POSITION_CONTAINED_BY", 251 "Node.get:DOCUMENT_POSITION_CONTAINED_BY",
249 "Node.get:prefix", 252 "Node.get:prefix",
250 "Node.set:prefix", 253 "Node.set:prefix",
251 "Node.get:DOCUMENT_POSITION_PRECEDING", 254 "Node.get:DOCUMENT_POSITION_PRECEDING",
252 "Node.get:nodeType",
253 "Node.removeEventListener", 255 "Node.removeEventListener",
254 "Node.get:nodeValue", 256 "Node.get:nodeValue",
255 "Node.set:nodeValue", 257 "Node.set:nodeValue",
256 "Node.get:CDATA_SECTION_NODE", 258 "Node.get:CDATA_SECTION_NODE",
257 "Node.get:nodeName", 259 "Node.get:nodeName",
258 "Node.addEventListener", 260 "Node.addEventListener",
259 "Node.lookupPrefix", 261 "Node.lookupPrefix",
260 "Node.get:PROCESSING_INSTRUCTION_NODE", 262 "Node.get:PROCESSING_INSTRUCTION_NODE",
261 "Notification.dispatchEvent", 263 "Notification.dispatchEvent",
262 "Notification.addEventListener", 264 "Notification.addEventListener",
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
419 return not self._Matches(interface, member, member_prefix, 421 return not self._Matches(interface, member, member_prefix,
420 _html_library_remove) 422 _html_library_remove)
421 423
422 def _Matches(self, interface, member, member_prefix, candidates): 424 def _Matches(self, interface, member, member_prefix, candidates):
423 for interface_name in self._AllAncestorInterfaces(interface): 425 for interface_name in self._AllAncestorInterfaces(interface):
424 if (DartType(interface_name) + '.' + member in candidates or 426 if (DartType(interface_name) + '.' + member in candidates or
425 DartType(interface_name) + '.' + member_prefix + member in candidates) : 427 DartType(interface_name) + '.' + member_prefix + member in candidates) :
426 return True 428 return True
427 return False 429 return False
428 430
429 def MaybeReturnDocument(self, return_type):
430 """
431 To make it appear that there are not a distinct Document and
432 HTMLHtmlElement (document.documentElement) objects we always use
433 documentElement instead of the regular document object so must not
434 allow a regular document to leak out.
435 """
436 # TODO(jacobr): any method that returns a Node could also theoretically
437 # really return a Document but there are alot of methods that return nodes
438 # and they all appear to be safe. Consider the alternate strategy of
439 # whitelisting just the known safe methods that return Nodes.
440 return (DartType(return_type) == 'EventTarget' or
441 DartType(return_type) == 'Document')
442
443 def _AllAncestorInterfaces(self, interface): 431 def _AllAncestorInterfaces(self, interface):
444 interfaces = ([interface.id] + 432 interfaces = ([interface.id] +
445 self._generator._AllImplementedInterfaces(interface)) 433 self._generator._AllImplementedInterfaces(interface))
446 return interfaces 434 return interfaces
447 435
448 def RenameInHtmlLibrary(self, interface, member, member_prefix=''): 436 def RenameInHtmlLibrary(self, interface, member, member_prefix='',
437 implementation_class=False):
449 """ 438 """
450 Returns the name of the member in the HTML library or None if the member is 439 Returns the name of the member in the HTML library or None if the member is
451 suppressed in the HTML library 440 suppressed in the HTML library
452 """ 441 """
453 if not self._AllowInHtmlLibrary(interface, member, member_prefix): 442 if not self._AllowInHtmlLibrary(interface, member, member_prefix):
454 return None 443 return None
455 444
445 target_name = member
456 for interface_name in self._AllAncestorInterfaces(interface): 446 for interface_name in self._AllAncestorInterfaces(interface):
457 name = interface_name + '.' + member 447 name = interface_name + '.' + member
458 if name in _html_library_renames: 448 if name in _html_library_renames:
459 return _html_library_renames[name] 449 target_name = _html_library_renames[name]
460 name = interface.id + '.' + member_prefix + member 450 name = interface.id + '.' + member_prefix + member
461 if name in _html_library_renames: 451 if name in _html_library_renames:
462 return _html_library_renames[name] 452 target_name = _html_library_renames[name]
463 453
464 if self._PrivateInHtmlLibrary(interface, member, member_prefix): 454 if not target_name.startswith('_'):
465 return '_' + member 455 if self._PrivateInHtmlLibrary(interface, member, member_prefix):
456 target_name = '$dom_' + target_name
457 elif implementation_class and self._ManuallyGeneratedInHtmlLibrary(
458 interface, member, member_prefix):
459 target_name = '_' + target_name
466 460
467 # No rename required 461 # No rename required
468 return member 462 return target_name
469 463
470 def _PrivateInHtmlLibrary(self, interface, member, member_prefix): 464 def _PrivateInHtmlLibrary(self, interface, member, member_prefix):
471 return self._Matches(interface, member, member_prefix, 465 return self._Matches(interface, member, member_prefix,
472 _private_html_members) 466 _private_html_members)
473 467
468 def _ManuallyGeneratedInHtmlLibrary(self, interface, member, member_prefix):
469 return self._Matches(interface, member, member_prefix,
470 _manually_generated_html_members)
471
474 # TODO(jacobr): this already exists 472 # TODO(jacobr): this already exists
475 def _TraverseParents(self, interface, callback): 473 def _TraverseParents(self, interface, callback):
476 for parent in interface.parents: 474 for parent in interface.parents:
477 parent_id = parent.type.id 475 parent_id = parent.type.id
478 if self._database.HasInterface(parent_id): 476 if self._database.HasInterface(parent_id):
479 parent_interface = self._database.GetInterface(parent_id) 477 parent_interface = self._database.GetInterface(parent_id)
480 callback(parent_interface) 478 callback(parent_interface)
481 self._TraverseParents(parent_interface, callback) 479 self._TraverseParents(parent_interface, callback)
482 480
483 # TODO(jacobr): this isn't quite right.... 481 # TODO(jacobr): this isn't quite right....
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
694 return 692 return
695 raise Exception('Unexpected getter/setter combination %s %s' % 693 raise Exception('Unexpected getter/setter combination %s %s' %
696 (getter, setter)) 694 (getter, setter))
697 695
698 def AddOperation(self, info): 696 def AddOperation(self, info):
699 """ 697 """
700 Arguments: 698 Arguments:
701 operations - contains the overloads, one or more operations with the same 699 operations - contains the overloads, one or more operations with the same
702 name. 700 name.
703 """ 701 """
704 html_name = self._shared.RenameInHtmlLibrary(self._interface, info.name) 702 html_name = self._shared.RenameInHtmlLibrary(
703 self._interface, info.name)
705 if html_name and not self._shared.IsPrivate(html_name): 704 if html_name and not self._shared.IsPrivate(html_name):
706 self._members_emitter.Emit('\n' 705 self._members_emitter.Emit('\n'
707 ' $TYPE $NAME($PARAMS);\n', 706 ' $TYPE $NAME($PARAMS);\n',
708 TYPE=info.type_name, 707 TYPE=info.type_name,
709 NAME=html_name, 708 NAME=html_name,
710 PARAMS=info.ParametersInterfaceDeclaration()) 709 PARAMS=info.ParametersInterfaceDeclaration())
711 710
712 def FinishInterface(self): 711 def FinishInterface(self):
713 pass 712 pass
714 713
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
868 # TODO(sra): Use separate mixins for mutable implementations of List<T>. 867 # TODO(sra): Use separate mixins for mutable implementations of List<T>.
869 # TODO(sra): Use separate mixins for typed array implementations of List<T>. 868 # TODO(sra): Use separate mixins for typed array implementations of List<T>.
870 if self._interface.id != 'NodeList': 869 if self._interface.id != 'NodeList':
871 template_file = 'immutable_list_mixin.darttemplate' 870 template_file = 'immutable_list_mixin.darttemplate'
872 template = self._system._templates.Load(template_file) 871 template = self._system._templates.Load(template_file)
873 self._members_emitter.Emit(template, E=DartType(element_type)) 872 self._members_emitter.Emit(template, E=DartType(element_type))
874 873
875 def AddAttribute(self, getter, setter): 874 def AddAttribute(self, getter, setter):
876 875
877 html_getter_name = self._shared.RenameInHtmlLibrary( 876 html_getter_name = self._shared.RenameInHtmlLibrary(
878 self._interface, DartDomNameOfAttribute(getter), 'get:') 877 self._interface, DartDomNameOfAttribute(getter), 'get:',
878 implementation_class=True)
879 html_setter_name = self._shared.RenameInHtmlLibrary( 879 html_setter_name = self._shared.RenameInHtmlLibrary(
880 self._interface, DartDomNameOfAttribute(getter), 'set:') 880 self._interface, DartDomNameOfAttribute(getter), 'set:',
881 implementation_class=True)
881 882
882 if not html_getter_name: 883 if not html_getter_name:
883 getter = None 884 getter = None
884 if not html_setter_name: 885 if not html_setter_name:
885 setter = None 886 setter = None
886 887
887 if not getter and not setter: 888 if not getter and not setter:
888 return 889 return
889 890
890 if ((getter and (html_getter_name != getter.id or 891 if ((getter and html_getter_name != getter.id) or
891 self._shared.MaybeReturnDocument(getter.type.id))) or 892 (setter and html_setter_name != setter.id)):
892 (setter and (html_setter_name != setter.id or
893 self._shared.MaybeReturnDocument(setter.type.id))) or
894 self._interface.id == 'Document'):
895 if getter: 893 if getter:
896 self._AddRenamingGetter(getter, html_getter_name) 894 self._AddRenamingGetter(getter, html_getter_name)
897 if setter: 895 if setter:
898 self._AddRenamingSetter(setter, html_setter_name) 896 self._AddRenamingSetter(setter, html_setter_name)
899 return 897 return
900 898
901 # If the (getter, setter) pair is shadowing, we can't generate a shadowing 899 # If the (getter, setter) pair is shadowing, we can't generate a shadowing
902 # field (Issue 1633). 900 # field (Issue 1633).
903 (super_getter, super_getter_interface) = self._FindShadowedAttribute(getter) 901 (super_getter, super_getter_interface) = self._FindShadowedAttribute(getter)
904 (super_setter, super_setter_interface) = self._FindShadowedAttribute(setter) 902 (super_setter, super_setter_interface) = self._FindShadowedAttribute(setter)
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
944 self._AddSetter(setter) 942 self._AddSetter(setter)
945 943
946 def _AddGetter(self, attr): 944 def _AddGetter(self, attr):
947 self._AddRenamingGetter(attr, DartDomNameOfAttribute(attr)) 945 self._AddRenamingGetter(attr, DartDomNameOfAttribute(attr))
948 946
949 def _AddSetter(self, attr): 947 def _AddSetter(self, attr):
950 self._AddRenamingSetter(attr, DartDomNameOfAttribute(attr)) 948 self._AddRenamingSetter(attr, DartDomNameOfAttribute(attr))
951 949
952 def _AddRenamingGetter(self, attr, html_name): 950 def _AddRenamingGetter(self, attr, html_name):
953 return_type = self._NarrowOutputType(attr.type.id) 951 return_type = self._NarrowOutputType(attr.type.id)
954 if self._shared.MaybeReturnDocument(attr.type.id):
955 self._members_emitter.Emit(
956 '\n $TYPE get $(HTML_NAME)() => '
957 '_FixHtmlDocumentReference(_$(HTML_NAME));\n',
958 HTML_NAME=html_name,
959 TYPE=return_type)
960 html_name = '_' + html_name
961 # For correctness this needs to be the return type of the native helper
962 # method due to the fact that the real HTMLDocument object is not typed
963 # as a document. TODO(jacobr): we could simplify this.
964 return_type = '_EventTargetImpl'
965
966 self._members_emitter.Emit( 952 self._members_emitter.Emit(
967 '\n $TYPE get $(HTML_NAME)() native "return $(THIS).$NAME;";\n', 953 '\n $TYPE get $(HTML_NAME)() native "return this.$NAME;";\n',
968 HTML_NAME=html_name, 954 HTML_NAME=html_name,
969 NAME=attr.id, 955 NAME=attr.id,
970 TYPE=return_type, 956 TYPE=return_type)
971 THIS='this.parentNode' if self._interface.id == 'Document' else 'this')
972 957
973 def _AddRenamingSetter(self, attr, html_name): 958 def _AddRenamingSetter(self, attr, html_name):
974 self._members_emitter.Emit( 959 self._members_emitter.Emit(
975 '\n void set $HTML_NAME($TYPE value)' 960 '\n void set $HTML_NAME($TYPE value)'
976 ' native "$(THIS).$NAME = value;";\n', 961 ' native "this.$NAME = value;";\n',
977 HTML_NAME=html_name, 962 HTML_NAME=html_name,
978 NAME=attr.id, 963 NAME=attr.id,
979 TYPE=self._NarrowInputType(attr.type.id), 964 TYPE=self._NarrowInputType(attr.type.id))
980 THIS='this.parentNode' if self._interface.id == 'Document' else 'this')
981 965
982 def AddOperation(self, info): 966 def AddOperation(self, info):
983 """ 967 """
984 Arguments: 968 Arguments:
985 info: An OperationInfo object. 969 info: An OperationInfo object.
986 """ 970 """
987 html_name = self._shared.RenameInHtmlLibrary(self._interface, info.name) 971 html_name = self._shared.RenameInHtmlLibrary(
972 self._interface, info.name, implementation_class=True)
988 if not html_name: 973 if not html_name:
989 return 974 return
990 975
991 maybe_return_document = self._shared.MaybeReturnDocument(info.type_name)
992
993 # Do we need a native body? 976 # Do we need a native body?
994 if (self._interface.id == 'Document' or # Need alternate 'this' 977 if (html_name != info.name):
995 html_name != info.name or # renamed operation
996 maybe_return_document): # need to wrap value
997 # For example: use window.document instead of his.parentNode.
998 return_type = self._NarrowOutputType(info.type_name) 978 return_type = self._NarrowOutputType(info.type_name)
999 979
1000 operation_emitter = self._members_emitter.Emit('$!SCOPE', 980 operation_emitter = self._members_emitter.Emit('$!SCOPE',
1001 THIS=('this.parentNode' if self._interface.id == 'Document'
1002 else 'this'),
1003 TYPE=return_type, 981 TYPE=return_type,
1004 HTML_NAME=html_name, 982 HTML_NAME=html_name,
1005 NAME=info.name, 983 NAME=info.name,
1006 RETURN='' if return_type == 'void' else 'return ', 984 RETURN='' if return_type == 'void' else 'return ',
1007 PARAMNAMES=info.ParametersAsArgumentList(), 985 PARAMNAMES=info.ParametersAsArgumentList(),
1008 PARAMS=info.ParametersImplementationDeclaration( 986 PARAMS=info.ParametersImplementationDeclaration(
1009 lambda type_name: self._NarrowInputType(type_name))) 987 lambda type_name: self._NarrowInputType(type_name)))
1010 988
1011 if maybe_return_document: 989 operation_emitter.Emit(
1012 assert len(info.overloads) == 1 990 '\n'
1013 operation_emitter.Emit( 991 ' $TYPE $(HTML_NAME)($PARAMS)'
1014 '\n' 992 ' native "$(RETURN)this.$NAME($PARAMNAMES);";\n')
1015 ' $TYPE $(HTML_NAME)($PARAMS) => '
1016 '_FixHtmlDocumentReference(_$(HTML_NAME)($PARAMNAMES));\n'
1017 '\n'
1018 ' _EventTargetImpl _$(HTML_NAME)($PARAMS)'
1019 ' native "return $(THIS).$NAME($PARAMNAMES);";\n')
1020 else:
1021 operation_emitter.Emit(
1022 '\n'
1023 ' $TYPE $(HTML_NAME)($PARAMS)'
1024 ' native "$(RETURN)$(THIS).$NAME($PARAMNAMES);";\n')
1025 else: 993 else:
1026 self._members_emitter.Emit( 994 self._members_emitter.Emit(
1027 '\n' 995 '\n'
1028 ' $TYPE $NAME($PARAMS) native;\n', 996 ' $TYPE $NAME($PARAMS) native;\n',
1029 TYPE=self._NarrowOutputType(info.type_name), 997 TYPE=self._NarrowOutputType(info.type_name),
1030 NAME=info.name, 998 NAME=info.name,
1031 PARAMS=info.ParametersImplementationDeclaration( 999 PARAMS=info.ParametersImplementationDeclaration(
1032 lambda type_name: self._NarrowInputType(type_name))) 1000 lambda type_name: self._NarrowInputType(type_name)))
1033 1001
1034 def AddEventAttributes(self, event_attrs): 1002 def AddEventAttributes(self, event_attrs):
(...skipping 21 matching lines...) Expand all
1056 events_members.Emit( 1024 events_members.Emit(
1057 "\n" 1025 "\n"
1058 " EventListenerList get $NAME() => _get('$RAWNAME');\n", 1026 " EventListenerList get $NAME() => _get('$RAWNAME');\n",
1059 RAWNAME=event_name, 1027 RAWNAME=event_name,
1060 NAME=_html_event_names[event_name]) 1028 NAME=_html_event_names[event_name])
1061 else: 1029 else:
1062 raise Exception('No known html even name for event: ' + event_name) 1030 raise Exception('No known html even name for event: ' + event_name)
1063 1031
1064 def _EmitEventGetter(self, events_class): 1032 def _EmitEventGetter(self, events_class):
1065 self._members_emitter.Emit( 1033 self._members_emitter.Emit(
1066 '\n $TYPE get on() =>\n new $TYPE($EVENTTARGET);\n', 1034 '\n $TYPE get on() =>\n new $TYPE(this);\n',
1067 TYPE=events_class, 1035 TYPE=events_class)
1068 EVENTTARGET='_jsDocument' if self._interface.id == 'Document'
1069 else 'this')
1070 1036
1071 # ------------------------------------------------------------------------------ 1037 # ------------------------------------------------------------------------------
1072 1038
1073 class HtmlFrogSystem(HtmlSystem): 1039 class HtmlFrogSystem(HtmlSystem):
1074 1040
1075 def __init__(self, templates, database, emitters, output_dir, generator): 1041 def __init__(self, templates, database, emitters, output_dir, generator):
1076 super(HtmlFrogSystem, self).__init__( 1042 super(HtmlFrogSystem, self).__init__(
1077 templates, database, emitters, output_dir, generator) 1043 templates, database, emitters, output_dir, generator)
1078 self._dart_frog_file_paths = [] 1044 self._dart_frog_file_paths = []
1079 1045
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1198 self._system = system 1164 self._system = system
1199 self._interface = interface 1165 self._interface = interface
1200 self._super_interface = super_interface 1166 self._super_interface = super_interface
1201 self._dart_code = dart_code 1167 self._dart_code = dart_code
1202 self._base_members = base_members 1168 self._base_members = base_members
1203 self._current_secondary_parent = None 1169 self._current_secondary_parent = None
1204 self._shared = shared 1170 self._shared = shared
1205 self._template = template 1171 self._template = template
1206 1172
1207 def DomObjectName(self): 1173 def DomObjectName(self):
1208 return '_documentPtr' if self._interface.id == 'Document' else '_ptr' 1174 return '_ptr'
1209 1175
1210 # TODO(jacobr): these 3 methods are duplicated. 1176 # TODO(jacobr): these 3 methods are duplicated.
1211 def _NarrowToImplementationType(self, type_name): 1177 def _NarrowToImplementationType(self, type_name):
1212 # TODO(sra): Move into the 'system' and cache the result. 1178 # TODO(sra): Move into the 'system' and cache the result.
1213 if type_name == 'EventListener': 1179 if type_name == 'EventListener':
1214 # Callbacks are typedef functions so don't have a class. 1180 # Callbacks are typedef functions so don't have a class.
1215 return type_name 1181 return type_name
1216 if self._system._database.HasInterface(type_name): 1182 if self._system._database.HasInterface(type_name):
1217 interface = self._system._database.GetInterface(type_name) 1183 interface = self._system._database.GetInterface(type_name)
1218 if RecognizeCallback(interface): 1184 if RecognizeCallback(interface):
(...skipping 22 matching lines...) Expand all
1241 base = self._ImplClassName(supertype) 1207 base = self._ImplClassName(supertype)
1242 if IsDartCollectionType(supertype): 1208 if IsDartCollectionType(supertype):
1243 # List methods are injected in AddIndexer. 1209 # List methods are injected in AddIndexer.
1244 pass 1210 pass
1245 else: 1211 else:
1246 base = self._ImplClassName(supertype) 1212 base = self._ImplClassName(supertype)
1247 1213
1248 # TODO(jacobr): this is fragile. There isn't a guarantee that dart:dom 1214 # TODO(jacobr): this is fragile. There isn't a guarantee that dart:dom
1249 # will continue to exactly match the IDL names. 1215 # will continue to exactly match the IDL names.
1250 dom_name = interface.javascript_binding_name 1216 dom_name = interface.javascript_binding_name
1251 # We hard code the cases for these classes 1217 self._system._wrap_cases.append(
1252 if dom_name != 'HTMLHtmlElement' and dom_name != 'Document': 1218 " case '%s': return new %s._wrap(domObject);" %
1253 self._system._wrap_cases.append( 1219 (dom_name, self._class_name))
1254 ' case "%s": return new %s._wrap(domObject);' %
1255 (dom_name, self._class_name))
1256 1220
1257 extends = ' extends ' + base if base else ' extends _DOMTypeBase' 1221 extends = ' extends ' + base if base else ' extends _DOMTypeBase'
1258 1222
1259 # TODO: Include all implemented interfaces, including other Lists. 1223 # TODO: Include all implemented interfaces, including other Lists.
1260 implements = [interface_name] 1224 implements = [interface_name]
1261 element_type = MaybeTypedArrayElementType(self._interface) 1225 element_type = MaybeTypedArrayElementType(self._interface)
1262 if element_type: 1226 if element_type:
1263 implements.append('List<' + DartType(element_type) + '>') 1227 implements.append('List<' + DartType(element_type) + '>')
1264 implements_str = ', '.join(implements) 1228 implements_str = ', '.join(implements)
1265 1229
1266 (self._members_emitter, 1230 (self._members_emitter,
1267 self._top_level_emitter) = self._dart_code.Emit( 1231 self._top_level_emitter) = self._dart_code.Emit(
1268 self._template + '$!TOP_LEVEL', 1232 self._template + '$!TOP_LEVEL',
1269 #class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC { 1233 #class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
1270 #$!MEMBERS 1234 #$!MEMBERS
1271 #} 1235 #}
1272 NATIVESPEC='', # hack to make reusing the same templates work. 1236 NATIVESPEC='', # hack to make reusing the same templates work.
1273 CLASSNAME=self._class_name, 1237 CLASSNAME=self._class_name,
1274 EXTENDS=extends, 1238 EXTENDS=extends,
1275 IMPLEMENTS=' implements ' + implements_str) 1239 IMPLEMENTS=' implements ' + implements_str)
1276 1240
1277 # Document requires a custom wrapper. 1241 self._members_emitter.Emit(
1278 if dom_name != 'Document': 1242 ' $(CLASSNAME)._wrap(ptr) : super._wrap(ptr);\n',
1279 self._members_emitter.Emit( 1243 CLASSNAME=self._class_name)
1280 ' $(CLASSNAME)._wrap(ptr) : super._wrap(ptr);\n',
1281 CLASSNAME=self._class_name)
1282 1244
1283 # Emit a factory provider class for the constructor. 1245 # Emit a factory provider class for the constructor.
1284 constructor_info = AnalyzeConstructor(interface) 1246 constructor_info = AnalyzeConstructor(interface)
1285 if constructor_info: 1247 if constructor_info:
1286 self._EmitFactoryProvider(interface_name, constructor_info) 1248 self._EmitFactoryProvider(interface_name, constructor_info)
1287 1249
1288 emit_events, events = self._shared.GetEventAttributes(self._interface) 1250 emit_events, events = self._shared.GetEventAttributes(self._interface)
1289 if not emit_events: 1251 if not emit_events:
1290 return 1252 return
1291 elif events: 1253 elif events:
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1355 1317
1356 def _MethodName(self, prefix, name): 1318 def _MethodName(self, prefix, name):
1357 method_name = prefix + name 1319 method_name = prefix + name
1358 if name in self._base_members: # Avoid illegal Dart 'static override'. 1320 if name in self._base_members: # Avoid illegal Dart 'static override'.
1359 method_name = method_name + '_' + self._interface.id 1321 method_name = method_name + '_' + self._interface.id
1360 return method_name 1322 return method_name
1361 1323
1362 def AddAttribute(self, getter, setter): 1324 def AddAttribute(self, getter, setter):
1363 dom_name = DartDomNameOfAttribute(getter or setter) 1325 dom_name = DartDomNameOfAttribute(getter or setter)
1364 html_getter_name = self._shared.RenameInHtmlLibrary( 1326 html_getter_name = self._shared.RenameInHtmlLibrary(
1365 self._interface, dom_name, 'get:') 1327 self._interface, dom_name, 'get:', implementation_class=True)
1366 html_setter_name = self._shared.RenameInHtmlLibrary( 1328 html_setter_name = self._shared.RenameInHtmlLibrary(
1367 self._interface, dom_name, 'set:') 1329 self._interface, dom_name, 'set:', implementation_class=True)
1368 1330
1369 if getter and html_getter_name: 1331 if getter and html_getter_name:
1370 self._AddGetter(getter, html_getter_name) 1332 self._AddGetter(getter, html_getter_name)
1371 if setter and html_setter_name: 1333 if setter and html_setter_name:
1372 self._AddSetter(setter, html_setter_name) 1334 self._AddSetter(setter, html_setter_name)
1373 1335
1374 def _AddGetter(self, attr, html_name): 1336 def _AddGetter(self, attr, html_name):
1375 if self._shared.MaybeReturnDocument(attr.type.id): 1337 self._members_emitter.Emit(
1376 self._members_emitter.Emit( 1338 '\n'
1377 '\n' 1339 ' $TYPE get $(HTML_NAME)() => _wrap($(THIS).$DOM_NAME);\n',
1378 ' $TYPE get $(HTML_NAME)() => ' 1340 HTML_NAME=html_name,
1379 '_FixHtmlDocumentReference(_wrap($(THIS).$DOM_NAME));\n', 1341 DOM_NAME=DartDomNameOfAttribute(attr),
1380 HTML_NAME=html_name, 1342 TYPE=DartType(attr.type.id),
1381 DOM_NAME=DartDomNameOfAttribute(attr), 1343 THIS=self.DomObjectName())
1382 TYPE=DartType(attr.type.id),
1383 THIS=self.DomObjectName())
1384 else:
1385 self._members_emitter.Emit(
1386 '\n'
1387 ' $TYPE get $(HTML_NAME)() => _wrap($(THIS).$DOM_NAME);\n',
1388 HTML_NAME=html_name,
1389 DOM_NAME=DartDomNameOfAttribute(attr),
1390 TYPE=DartType(attr.type.id),
1391 THIS=self.DomObjectName())
1392 1344
1393 def _AddSetter(self, attr, html_name): 1345 def _AddSetter(self, attr, html_name):
1394 self._members_emitter.Emit( 1346 self._members_emitter.Emit(
1395 '\n' 1347 '\n'
1396 ' void set $(HTML_NAME)($TYPE value) { ' 1348 ' void set $(HTML_NAME)($TYPE value) { '
1397 '$(THIS).$DOM_NAME = _unwrap(value); }\n', 1349 '$(THIS).$DOM_NAME = _unwrap(value); }\n',
1398 HTML_NAME=html_name, 1350 HTML_NAME=html_name,
1399 DOM_NAME=DartDomNameOfAttribute(attr), 1351 DOM_NAME=DartDomNameOfAttribute(attr),
1400 TYPE=DartType(attr.type.id), 1352 TYPE=DartType(attr.type.id),
1401 THIS=self.DomObjectName()) 1353 THIS=self.DomObjectName())
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
1615 ' }\n', 1567 ' }\n',
1616 THIS=self.DomObjectName(), 1568 THIS=self.DomObjectName(),
1617 TYPE=DartType(element_type), 1569 TYPE=DartType(element_type),
1618 METHOD=method_name) 1570 METHOD=method_name)
1619 1571
1620 def AddOperation(self, info): 1572 def AddOperation(self, info):
1621 """ 1573 """
1622 Arguments: 1574 Arguments:
1623 info: An OperationInfo object. 1575 info: An OperationInfo object.
1624 """ 1576 """
1625 html_name = self._shared.RenameInHtmlLibrary(self._interface, info.name) 1577 html_name = self._shared.RenameInHtmlLibrary(
1578 self._interface, info.name, implementation_class=True)
1626 1579
1627 if not html_name: 1580 if not html_name:
1628 return 1581 return
1629 1582
1630 body = self._members_emitter.Emit( 1583 body = self._members_emitter.Emit(
1631 '\n' 1584 '\n'
1632 ' $TYPE $HTML_NAME($PARAMS) {\n' 1585 ' $TYPE $HTML_NAME($PARAMS) {\n'
1633 '$!BODY' 1586 '$!BODY'
1634 ' }\n', 1587 ' }\n',
1635 TYPE=info.type_name, 1588 TYPE=info.type_name,
(...skipping 19 matching lines...) Expand all
1655 operation: the IDLOperation to call. 1608 operation: the IDLOperation to call.
1656 """ 1609 """
1657 argument_expressions = self._UnwrappedParameters( 1610 argument_expressions = self._UnwrappedParameters(
1658 info, 1611 info,
1659 len(operation.arguments)) # Just the parameters this far. 1612 len(operation.arguments)) # Just the parameters this far.
1660 1613
1661 if info.type_name != 'void': 1614 if info.type_name != 'void':
1662 # We could place the logic for handling Document directly in _wrap 1615 # We could place the logic for handling Document directly in _wrap
1663 # but we chose to place it here so that bugs in the wrapper and 1616 # but we chose to place it here so that bugs in the wrapper and
1664 # wrapperless implementations are more consistent. 1617 # wrapperless implementations are more consistent.
1665 if self._shared.MaybeReturnDocument(info.type_name): 1618 emitter.Emit('$(INDENT)return _wrap($(THIS).$NAME($ARGS));\n',
1666 emitter.Emit('$(INDENT)return _FixHtmlDocumentReference(' 1619 INDENT=indent,
1667 '_wrap($(THIS).$NAME($ARGS)));\n', 1620 THIS=self.DomObjectName(),
1668 INDENT=indent, 1621 NAME=info.name,
1669 THIS=self.DomObjectName(), 1622 ARGS=argument_expressions)
1670 NAME=info.name,
1671 ARGS=argument_expressions)
1672 else:
1673 emitter.Emit('$(INDENT)return _wrap($(THIS).$NAME($ARGS));\n',
1674 INDENT=indent,
1675 THIS=self.DomObjectName(),
1676 NAME=info.name,
1677 ARGS=argument_expressions)
1678 else: 1623 else:
1679 emitter.Emit('$(INDENT)$(THIS).$NAME($ARGS);\n' 1624 emitter.Emit('$(INDENT)$(THIS).$NAME($ARGS);\n'
1680 '$(INDENT)return;\n', 1625 '$(INDENT)return;\n',
1681 INDENT=indent, 1626 INDENT=indent,
1682 THIS=self.DomObjectName(), 1627 THIS=self.DomObjectName(),
1683 NAME=info.name, 1628 NAME=info.name,
1684 ARGS=argument_expressions) 1629 ARGS=argument_expressions)
1685 1630
1686 def GenerateDispatch(self, emitter, info, indent, position, overloads): 1631 def GenerateDispatch(self, emitter, info, indent, position, overloads):
1687 """Generates a dispatch to one of the overloads. 1632 """Generates a dispatch to one of the overloads.
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1773 # dispatch has removed f(X), leaving only f(Y), but there is no guarantee 1718 # dispatch has removed f(X), leaving only f(Y), but there is no guarantee
1774 # that Y = Z-X, so we need to check for Y. 1719 # that Y = Z-X, so we need to check for Y.
1775 true_code = emitter.Emit( 1720 true_code = emitter.Emit(
1776 '$(INDENT)if ($COND) {\n' 1721 '$(INDENT)if ($COND) {\n'
1777 '$!TRUE' 1722 '$!TRUE'
1778 '$(INDENT)}\n', 1723 '$(INDENT)}\n',
1779 COND=test, INDENT=indent) 1724 COND=test, INDENT=indent)
1780 self.GenerateDispatch( 1725 self.GenerateDispatch(
1781 true_code, info, indent + ' ', position + 1, positive) 1726 true_code, info, indent + ' ', position + 1, positive)
1782 return True 1727 return True
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698