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

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: Ready for review 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 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.removeChild',
64 'Node.replaceChild',
65 'NodeSelector.querySelectorAll',
66 'Window.getComputedStyle',
67 ])
68
69 _manually_generated_html_members = set([
70 'Document.querySelectorAll',
71 'Document.querySelector',
58 ]) 72 ])
59 73
60 # Members from the standard dom that exist in the dart:html library with 74 # Members from the standard dom that exist in the dart:html library with
61 # identical functionality but with cleaner names. 75 # identical functionality but with cleaner names.
62 _html_library_renames = { 76 _html_library_renames = {
63 'Document.defaultView': 'window', 77 'Document.defaultView': 'window',
64 'DocumentFragment.querySelector': 'query', 78 'DocumentFragment.querySelector': 'query',
65 'NodeSelector.querySelector': 'query', 79 'NodeSelector.querySelector': 'query',
66 'Element.querySelector': 'query', 80 'Element.querySelector': 'query',
67 'Element.webkitMatchesSelector' : 'matchesSelector', 81 'Element.webkitMatchesSelector' : 'matchesSelector',
68 'Element.scrollIntoViewIfNeeded': 'scrollIntoView', 82 'Element.scrollIntoViewIfNeeded': 'scrollIntoView',
69 'Document.querySelector': 'query',
70 'Node.cloneNode': 'clone', 83 'Node.cloneNode': 'clone',
71 'Node.nextSibling': 'nextNode', 84 'Node.nextSibling': 'nextNode',
72 'Node.ownerDocument': 'document', 85 'Node.ownerDocument': 'document',
73 'Node.parentNode': 'parent', 86 'Node.parentNode': 'parent',
74 'Node.previousSibling': 'previousNode', 87 'Node.previousSibling': 'previousNode',
75 'Node.textContent': 'text', 88 'Node.textContent': 'text',
76 'SVGElement.className': '_svgClassName', 89 'SVGElement.className': '$dom_svgClassName',
77 'SVGAnimatedString.className': '_svgClassName', 90 'SVGAnimatedString.className': '$dom_svgClassName',
78 'SVGStylable.className': '_svgClassName', 91 'SVGStylable.className': '$dom_svgClassName',
79 } 92 }
80 93
81 #TODO(jacobr): inject annotations into the interfaces based on this table and 94 #TODO(jacobr): inject annotations into the interfaces based on this table and
82 # on _html_library_renames. 95 # on _html_library_renames.
83 _injected_doc_fragments = { 96 _injected_doc_fragments = {
84 'Element.query': ' /** @domName querySelector, Document.getElementById */', 97 'Element.query': ' /** @domName querySelector, Document.getElementById */',
85 } 98 }
86 # Members and classes from the dom that should be removed completelly from 99 # 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 100 # dart:html. These could be expressed in the IDL instead but expressing this
88 # as a simple table instead is more concise. 101 # as a simple table instead is more concise.
89 # Syntax is: ClassName.(get\.|set\.)?MemberName 102 # Syntax is: ClassName.(get\.|set\.)?MemberName
90 # Using get: and set: is optional and should only be used when a getter needs 103 # Using get: and set: is optional and should only be used when a getter needs
91 # to be suppressed but not the setter, etc. 104 # to be suppressed but not the setter, etc.
92 # TODO(jacobr): cleanup and augment this list. 105 # TODO(jacobr): cleanup and augment this list.
93 _html_library_remove = set([ 106 _html_library_remove = set([
94 'Window.get:document', # Removed as we have a custom implementation. 107 'Window.get:document', # Removed as we have a custom implementation.
95 'NodeList.item', 108 'NodeList.item',
96 "Attr.*", 109 "Attr.*",
97 # "BarProp.*", 110 # "BarProp.*",
98 # "BarInfo.*", 111 # "BarInfo.*",
99 # "Blob.webkitSlice", 112 # "Blob.webkitSlice",
100 # "CDATASection.*", 113 # "CDATASection.*",
101 # "Comment.*", 114 # "Comment.*",
102 # "DOMImplementation.*", 115 # "DOMImplementation.*",
103 "Document.get:documentElement",
104 "Document.get:forms", 116 "Document.get:forms",
105 # "Document.get:selectedStylesheetSet", 117 # "Document.get:selectedStylesheetSet",
106 # "Document.set:selectedStylesheetSet", 118 # "Document.set:selectedStylesheetSet",
107 # "Document.get:preferredStylesheetSet", 119 # "Document.get:preferredStylesheetSet",
108 "Document.get:links", 120 "Document.get:links",
109 "Document.getElementsByTagName",
110 "Document.set:domain", 121 "Document.set:domain",
111 "Document.get:implementation", 122 "Document.get:implementation",
112 "Document.createAttributeNS", 123 "Document.createAttributeNS",
113 "Document.get:inputEncoding", 124 "Document.get:inputEncoding",
114 "Document.getElementById",
115 "Document.getElementsByClassName",
116 "Document.get:height", 125 "Document.get:height",
117 "Document.get:width", 126 "Document.get:width",
118 "Element.getElementsByClassName",
119 "Element.getElementsByTagNameNS", 127 "Element.getElementsByTagNameNS",
120 "Element.getElementsByTagName",
121 "Document.get:compatMode", 128 "Document.get:compatMode",
122 "Document.importNode", 129 "Document.importNode",
123 "Document.evaluate", 130 "Document.evaluate",
124 "Document.get:images", 131 "Document.get:images",
125 "Document.querySelector",
126 "Document.createExpression", 132 "Document.createExpression",
127 "Document.getOverrideStyle", 133 "Document.getOverrideStyle",
128 "Document.xmlStandalone", 134 "Document.xmlStandalone",
129 "Document.createComment", 135 "Document.createComment",
130 "Document.adoptNode", 136 "Document.adoptNode",
131 "Document.get:characterSet", 137 "Document.get:characterSet",
132 "Document.createAttribute", 138 "Document.createAttribute",
133 "Document.querySelectorAll",
134 "Document.get:URL", 139 "Document.get:URL",
135 "Document.createEntityReference", 140 "Document.createEntityReference",
136 "Document.get:documentURI", 141 "Document.get:documentURI",
137 "Document.set:documentURI", 142 "Document.set:documentURI",
138 "Document.createNodeIterator", 143 "Document.createNodeIterator",
139 "Document.createProcessingInstruction", 144 "Document.createProcessingInstruction",
140 "Document.get:doctype", 145 "Document.get:doctype",
141 "Document.getElementsByName",
142 "Document.createTreeWalker", 146 "Document.createTreeWalker",
143 "Document.location", 147 "Document.location",
144 "Document.createNSResolver", 148 "Document.createNSResolver",
145 "Document.get:xmlEncoding", 149 "Document.get:xmlEncoding",
146 "Document.get:defaultCharset", 150 "Document.get:defaultCharset",
147 "Document.get:applets", 151 "Document.get:applets",
148 "Document.getSelection", 152 "Document.getSelection",
149 "Document.xmlVersion", 153 "Document.xmlVersion",
150 "Document.get:anchors", 154 "Document.get:anchors",
151 "Document.getElementsByTagNameNS", 155 "Document.getElementsByTagNameNS",
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 "Node.isDefaultNamespace", 234 "Node.isDefaultNamespace",
231 "Node.compareDocumentPosition", 235 "Node.compareDocumentPosition",
232 "Node.get:baseURI", 236 "Node.get:baseURI",
233 "Node.isSameNode", 237 "Node.isSameNode",
234 "Node.get:DOCUMENT_POSITION_DISCONNECTED", 238 "Node.get:DOCUMENT_POSITION_DISCONNECTED",
235 "Node.get:DOCUMENT_NODE", 239 "Node.get:DOCUMENT_NODE",
236 "Node.get:DOCUMENT_POSITION_CONTAINS", 240 "Node.get:DOCUMENT_POSITION_CONTAINS",
237 "Node.get:COMMENT_NODE", 241 "Node.get:COMMENT_NODE",
238 "Node.get:ENTITY_REFERENCE_NODE", 242 "Node.get:ENTITY_REFERENCE_NODE",
239 "Node.isSupported", 243 "Node.isSupported",
240 "Node.get:firstChild",
241 "Node.get:DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC", 244 "Node.get:DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC",
242 "Node.get:lastChild",
243 "Node.get:NOTATION_NODE", 245 "Node.get:NOTATION_NODE",
244 "Node.normalize", 246 "Node.normalize",
245 "Node.get:parentElement", 247 "Node.get:parentElement",
246 "Node.get:ATTRIBUTE_NODE", 248 "Node.get:ATTRIBUTE_NODE",
247 "Node.get:ENTITY_NODE", 249 "Node.get:ENTITY_NODE",
248 "Node.get:DOCUMENT_POSITION_CONTAINED_BY", 250 "Node.get:DOCUMENT_POSITION_CONTAINED_BY",
249 "Node.get:prefix", 251 "Node.get:prefix",
250 "Node.set:prefix", 252 "Node.set:prefix",
251 "Node.get:DOCUMENT_POSITION_PRECEDING", 253 "Node.get:DOCUMENT_POSITION_PRECEDING",
252 "Node.get:nodeType", 254 "Node.get:nodeType",
(...skipping 166 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, implementation _class=False):
nweiz 2012/03/28 01:16:17 Line length. I like keeping member_prefix optiona
Jacob 2012/03/28 17:52:54 Done.
449 """ 437 """
450 Returns the name of the member in the HTML library or None if the member is 438 Returns the name of the member in the HTML library or None if the member is
451 suppressed in the HTML library 439 suppressed in the HTML library
452 """ 440 """
453 if not self._AllowInHtmlLibrary(interface, member, member_prefix): 441 if not self._AllowInHtmlLibrary(interface, member, member_prefix):
454 return None 442 return None
455 443
444 target_name = member
456 for interface_name in self._AllAncestorInterfaces(interface): 445 for interface_name in self._AllAncestorInterfaces(interface):
457 name = interface_name + '.' + member 446 name = interface_name + '.' + member
458 if name in _html_library_renames: 447 if name in _html_library_renames:
459 return _html_library_renames[name] 448 target_name = _html_library_renames[name]
460 name = interface.id + '.' + member_prefix + member 449 name = interface.id + '.' + member_prefix + member
461 if name in _html_library_renames: 450 if name in _html_library_renames:
462 return _html_library_renames[name] 451 target_name = _html_library_renames[name]
463 452
464 if self._PrivateInHtmlLibrary(interface, member, member_prefix): 453 if not target_name.startswith('_'):
465 return '_' + member 454 if self._PrivateInHtmlLibrary(interface, member, member_prefix):
455 target_name = '$dom_' + target_name
456 elif implementation_class and self._ManuallyGeneratedInHtmlLibrary(
457 interface, member, member_prefix):
458 target_name = '_' + target_name
466 459
467 # No rename required 460 # No rename required
468 return member 461 return target_name
469 462
470 def _PrivateInHtmlLibrary(self, interface, member, member_prefix): 463 def _PrivateInHtmlLibrary(self, interface, member, member_prefix):
471 return self._Matches(interface, member, member_prefix, 464 return self._Matches(interface, member, member_prefix,
472 _private_html_members) 465 _private_html_members)
473 466
467 def _ManuallyGeneratedInHtmlLibrary(self, interface, member, member_prefix):
468 return self._Matches(interface, member, member_prefix,
469 _manually_generated_html_members)
470
474 # TODO(jacobr): this already exists 471 # TODO(jacobr): this already exists
475 def _TraverseParents(self, interface, callback): 472 def _TraverseParents(self, interface, callback):
476 for parent in interface.parents: 473 for parent in interface.parents:
477 parent_id = parent.type.id 474 parent_id = parent.type.id
478 if self._database.HasInterface(parent_id): 475 if self._database.HasInterface(parent_id):
479 parent_interface = self._database.GetInterface(parent_id) 476 parent_interface = self._database.GetInterface(parent_id)
480 callback(parent_interface) 477 callback(parent_interface)
481 self._TraverseParents(parent_interface, callback) 478 self._TraverseParents(parent_interface, callback)
482 479
483 # TODO(jacobr): this isn't quite right.... 480 # TODO(jacobr): this isn't quite right....
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
694 return 691 return
695 raise Exception('Unexpected getter/setter combination %s %s' % 692 raise Exception('Unexpected getter/setter combination %s %s' %
696 (getter, setter)) 693 (getter, setter))
697 694
698 def AddOperation(self, info): 695 def AddOperation(self, info):
699 """ 696 """
700 Arguments: 697 Arguments:
701 operations - contains the overloads, one or more operations with the same 698 operations - contains the overloads, one or more operations with the same
702 name. 699 name.
703 """ 700 """
704 html_name = self._shared.RenameInHtmlLibrary(self._interface, info.name) 701 html_name = self._shared.RenameInHtmlLibrary(
702 self._interface, info.name, '')
705 if html_name and not self._shared.IsPrivate(html_name): 703 if html_name and not self._shared.IsPrivate(html_name):
706 self._members_emitter.Emit('\n' 704 self._members_emitter.Emit('\n'
707 ' $TYPE $NAME($PARAMS);\n', 705 ' $TYPE $NAME($PARAMS);\n',
708 TYPE=info.type_name, 706 TYPE=info.type_name,
709 NAME=html_name, 707 NAME=html_name,
710 PARAMS=info.ParametersInterfaceDeclaration()) 708 PARAMS=info.ParametersInterfaceDeclaration())
711 709
712 def FinishInterface(self): 710 def FinishInterface(self):
713 pass 711 pass
714 712
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
868 # TODO(sra): Use separate mixins for mutable implementations of List<T>. 866 # TODO(sra): Use separate mixins for mutable implementations of List<T>.
869 # TODO(sra): Use separate mixins for typed array implementations of List<T>. 867 # TODO(sra): Use separate mixins for typed array implementations of List<T>.
870 if self._interface.id != 'NodeList': 868 if self._interface.id != 'NodeList':
871 template_file = 'immutable_list_mixin.darttemplate' 869 template_file = 'immutable_list_mixin.darttemplate'
872 template = self._system._templates.Load(template_file) 870 template = self._system._templates.Load(template_file)
873 self._members_emitter.Emit(template, E=DartType(element_type)) 871 self._members_emitter.Emit(template, E=DartType(element_type))
874 872
875 def AddAttribute(self, getter, setter): 873 def AddAttribute(self, getter, setter):
876 874
877 html_getter_name = self._shared.RenameInHtmlLibrary( 875 html_getter_name = self._shared.RenameInHtmlLibrary(
878 self._interface, DartDomNameOfAttribute(getter), 'get:') 876 self._interface, DartDomNameOfAttribute(getter), 'get:',
877 implementation_class=True)
879 html_setter_name = self._shared.RenameInHtmlLibrary( 878 html_setter_name = self._shared.RenameInHtmlLibrary(
880 self._interface, DartDomNameOfAttribute(getter), 'set:') 879 self._interface, DartDomNameOfAttribute(getter), 'set:',
880 implementation_class=True)
881 881
882 if not html_getter_name: 882 if not html_getter_name:
883 getter = None 883 getter = None
884 if not html_setter_name: 884 if not html_setter_name:
885 setter = None 885 setter = None
886 886
887 if not getter and not setter: 887 if not getter and not setter:
888 return 888 return
889 889
890 if ((getter and (html_getter_name != getter.id or 890 if ((getter and html_getter_name != getter.id) or
nweiz 2012/03/28 01:16:17 None of these parens are really necessary, but eve
Jacob 2012/03/28 17:52:54 I agree that the inner ones aren't needed but I pr
nweiz 2012/03/28 20:29:33 Oh, I see. I assumed Python was smart enough to fo
Jacob 2012/03/28 21:01:30 I wish it was... that is one of the things that an
891 self._shared.MaybeReturnDocument(getter.type.id))) or 891 (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: 892 if getter:
896 self._AddRenamingGetter(getter, html_getter_name) 893 self._AddRenamingGetter(getter, html_getter_name)
897 if setter: 894 if setter:
898 self._AddRenamingSetter(setter, html_setter_name) 895 self._AddRenamingSetter(setter, html_setter_name)
899 return 896 return
900 897
901 # If the (getter, setter) pair is shadowing, we can't generate a shadowing 898 # If the (getter, setter) pair is shadowing, we can't generate a shadowing
902 # field (Issue 1633). 899 # field (Issue 1633).
903 (super_getter, super_getter_interface) = self._FindShadowedAttribute(getter) 900 (super_getter, super_getter_interface) = self._FindShadowedAttribute(getter)
904 (super_setter, super_setter_interface) = self._FindShadowedAttribute(setter) 901 (super_setter, super_setter_interface) = self._FindShadowedAttribute(setter)
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
944 self._AddSetter(setter) 941 self._AddSetter(setter)
945 942
946 def _AddGetter(self, attr): 943 def _AddGetter(self, attr):
947 self._AddRenamingGetter(attr, DartDomNameOfAttribute(attr)) 944 self._AddRenamingGetter(attr, DartDomNameOfAttribute(attr))
948 945
949 def _AddSetter(self, attr): 946 def _AddSetter(self, attr):
950 self._AddRenamingSetter(attr, DartDomNameOfAttribute(attr)) 947 self._AddRenamingSetter(attr, DartDomNameOfAttribute(attr))
951 948
952 def _AddRenamingGetter(self, attr, html_name): 949 def _AddRenamingGetter(self, attr, html_name):
953 return_type = self._NarrowOutputType(attr.type.id) 950 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( 951 self._members_emitter.Emit(
967 '\n $TYPE get $(HTML_NAME)() native "return $(THIS).$NAME;";\n', 952 '\n $TYPE get $(HTML_NAME)() native "return this.$NAME;";\n',
968 HTML_NAME=html_name, 953 HTML_NAME=html_name,
969 NAME=attr.id, 954 NAME=attr.id,
970 TYPE=return_type, 955 TYPE=return_type)
971 THIS='this.parentNode' if self._interface.id == 'Document' else 'this')
972 956
973 def _AddRenamingSetter(self, attr, html_name): 957 def _AddRenamingSetter(self, attr, html_name):
974 self._members_emitter.Emit( 958 self._members_emitter.Emit(
975 '\n void set $HTML_NAME($TYPE value)' 959 '\n void set $HTML_NAME($TYPE value)'
976 ' native "$(THIS).$NAME = value;";\n', 960 ' native "this.$NAME = value;";\n',
977 HTML_NAME=html_name, 961 HTML_NAME=html_name,
978 NAME=attr.id, 962 NAME=attr.id,
979 TYPE=self._NarrowInputType(attr.type.id), 963 TYPE=self._NarrowInputType(attr.type.id))
980 THIS='this.parentNode' if self._interface.id == 'Document' else 'this')
981 964
982 def AddOperation(self, info): 965 def AddOperation(self, info):
983 """ 966 """
984 Arguments: 967 Arguments:
985 info: An OperationInfo object. 968 info: An OperationInfo object.
986 """ 969 """
987 html_name = self._shared.RenameInHtmlLibrary(self._interface, info.name) 970 html_name = self._shared.RenameInHtmlLibrary(
971 self._interface, info.name, '', implementation_class=True)
988 if not html_name: 972 if not html_name:
989 return 973 return
990 974
991 maybe_return_document = self._shared.MaybeReturnDocument(info.type_name)
992
993 # Do we need a native body? 975 # Do we need a native body?
994 if (self._interface.id == 'Document' or # Need alternate 'this' 976 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) 977 return_type = self._NarrowOutputType(info.type_name)
999 978
1000 operation_emitter = self._members_emitter.Emit('$!SCOPE', 979 operation_emitter = self._members_emitter.Emit('$!SCOPE',
1001 THIS=('this.parentNode' if self._interface.id == 'Document'
1002 else 'this'),
1003 TYPE=return_type, 980 TYPE=return_type,
1004 HTML_NAME=html_name, 981 HTML_NAME=html_name,
1005 NAME=info.name, 982 NAME=info.name,
1006 RETURN='' if return_type == 'void' else 'return ', 983 RETURN='' if return_type == 'void' else 'return ',
1007 PARAMNAMES=info.ParametersAsArgumentList(), 984 PARAMNAMES=info.ParametersAsArgumentList(),
1008 PARAMS=info.ParametersImplementationDeclaration( 985 PARAMS=info.ParametersImplementationDeclaration(
1009 lambda type_name: self._NarrowInputType(type_name))) 986 lambda type_name: self._NarrowInputType(type_name)))
1010 987
1011 if maybe_return_document: 988 operation_emitter.Emit(
1012 assert len(info.overloads) == 1 989 '\n'
1013 operation_emitter.Emit( 990 ' $TYPE $(HTML_NAME)($PARAMS)'
1014 '\n' 991 ' 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: 992 else:
1026 self._members_emitter.Emit( 993 self._members_emitter.Emit(
1027 '\n' 994 '\n'
1028 ' $TYPE $NAME($PARAMS) native;\n', 995 ' $TYPE $NAME($PARAMS) native;\n',
1029 TYPE=self._NarrowOutputType(info.type_name), 996 TYPE=self._NarrowOutputType(info.type_name),
1030 NAME=info.name, 997 NAME=info.name,
1031 PARAMS=info.ParametersImplementationDeclaration( 998 PARAMS=info.ParametersImplementationDeclaration(
1032 lambda type_name: self._NarrowInputType(type_name))) 999 lambda type_name: self._NarrowInputType(type_name)))
1033 1000
1034 def AddEventAttributes(self, event_attrs): 1001 def AddEventAttributes(self, event_attrs):
(...skipping 21 matching lines...) Expand all
1056 events_members.Emit( 1023 events_members.Emit(
1057 "\n" 1024 "\n"
1058 " EventListenerList get $NAME() => _get('$RAWNAME');\n", 1025 " EventListenerList get $NAME() => _get('$RAWNAME');\n",
1059 RAWNAME=event_name, 1026 RAWNAME=event_name,
1060 NAME=_html_event_names[event_name]) 1027 NAME=_html_event_names[event_name])
1061 else: 1028 else:
1062 raise Exception('No known html even name for event: ' + event_name) 1029 raise Exception('No known html even name for event: ' + event_name)
1063 1030
1064 def _EmitEventGetter(self, events_class): 1031 def _EmitEventGetter(self, events_class):
1065 self._members_emitter.Emit( 1032 self._members_emitter.Emit(
1066 '\n $TYPE get on() =>\n new $TYPE($EVENTTARGET);\n', 1033 '\n $TYPE get on() =>\n new $TYPE(this);\n',
1067 TYPE=events_class, 1034 TYPE=events_class)
1068 EVENTTARGET='_jsDocument' if self._interface.id == 'Document'
1069 else 'this')
1070 1035
1071 # ------------------------------------------------------------------------------ 1036 # ------------------------------------------------------------------------------
1072 1037
1073 class HtmlFrogSystem(HtmlSystem): 1038 class HtmlFrogSystem(HtmlSystem):
1074 1039
1075 def __init__(self, templates, database, emitters, output_dir, generator): 1040 def __init__(self, templates, database, emitters, output_dir, generator):
1076 super(HtmlFrogSystem, self).__init__( 1041 super(HtmlFrogSystem, self).__init__(
1077 templates, database, emitters, output_dir, generator) 1042 templates, database, emitters, output_dir, generator)
1078 self._dart_frog_file_paths = [] 1043 self._dart_frog_file_paths = []
1079 1044
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1198 self._system = system 1163 self._system = system
1199 self._interface = interface 1164 self._interface = interface
1200 self._super_interface = super_interface 1165 self._super_interface = super_interface
1201 self._dart_code = dart_code 1166 self._dart_code = dart_code
1202 self._base_members = base_members 1167 self._base_members = base_members
1203 self._current_secondary_parent = None 1168 self._current_secondary_parent = None
1204 self._shared = shared 1169 self._shared = shared
1205 self._template = template 1170 self._template = template
1206 1171
1207 def DomObjectName(self): 1172 def DomObjectName(self):
1208 return '_documentPtr' if self._interface.id == 'Document' else '_ptr' 1173 return '_ptr'
1209 1174
1210 # TODO(jacobr): these 3 methods are duplicated. 1175 # TODO(jacobr): these 3 methods are duplicated.
1211 def _NarrowToImplementationType(self, type_name): 1176 def _NarrowToImplementationType(self, type_name):
1212 # TODO(sra): Move into the 'system' and cache the result. 1177 # TODO(sra): Move into the 'system' and cache the result.
1213 if type_name == 'EventListener': 1178 if type_name == 'EventListener':
1214 # Callbacks are typedef functions so don't have a class. 1179 # Callbacks are typedef functions so don't have a class.
1215 return type_name 1180 return type_name
1216 if self._system._database.HasInterface(type_name): 1181 if self._system._database.HasInterface(type_name):
1217 interface = self._system._database.GetInterface(type_name) 1182 interface = self._system._database.GetInterface(type_name)
1218 if RecognizeCallback(interface): 1183 if RecognizeCallback(interface):
(...skipping 22 matching lines...) Expand all
1241 base = self._ImplClassName(supertype) 1206 base = self._ImplClassName(supertype)
1242 if IsDartCollectionType(supertype): 1207 if IsDartCollectionType(supertype):
1243 # List methods are injected in AddIndexer. 1208 # List methods are injected in AddIndexer.
1244 pass 1209 pass
1245 else: 1210 else:
1246 base = self._ImplClassName(supertype) 1211 base = self._ImplClassName(supertype)
1247 1212
1248 # TODO(jacobr): this is fragile. There isn't a guarantee that dart:dom 1213 # TODO(jacobr): this is fragile. There isn't a guarantee that dart:dom
1249 # will continue to exactly match the IDL names. 1214 # will continue to exactly match the IDL names.
1250 dom_name = interface.javascript_binding_name 1215 dom_name = interface.javascript_binding_name
1251 # We hard code the cases for these classes 1216 self._system._wrap_cases.append(
1252 if dom_name != 'HTMLHtmlElement' and dom_name != 'Document': 1217 " case '%s': return new %s._wrap(domObject);" %
1253 self._system._wrap_cases.append( 1218 (dom_name, self._class_name))
1254 ' case "%s": return new %s._wrap(domObject);' %
1255 (dom_name, self._class_name))
1256 1219
1257 extends = ' extends ' + base if base else ' extends _DOMTypeBase' 1220 extends = ' extends ' + base if base else ' extends _DOMTypeBase'
1258 1221
1259 # TODO: Include all implemented interfaces, including other Lists. 1222 # TODO: Include all implemented interfaces, including other Lists.
1260 implements = [interface_name] 1223 implements = [interface_name]
1261 element_type = MaybeTypedArrayElementType(self._interface) 1224 element_type = MaybeTypedArrayElementType(self._interface)
1262 if element_type: 1225 if element_type:
1263 implements.append('List<' + DartType(element_type) + '>') 1226 implements.append('List<' + DartType(element_type) + '>')
1264 implements_str = ', '.join(implements) 1227 implements_str = ', '.join(implements)
1265 1228
1266 (self._members_emitter, 1229 (self._members_emitter,
1267 self._top_level_emitter) = self._dart_code.Emit( 1230 self._top_level_emitter) = self._dart_code.Emit(
1268 self._template + '$!TOP_LEVEL', 1231 self._template + '$!TOP_LEVEL',
1269 #class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC { 1232 #class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
1270 #$!MEMBERS 1233 #$!MEMBERS
1271 #} 1234 #}
1272 NATIVESPEC='', # hack to make reusing the same templates work. 1235 NATIVESPEC='', # hack to make reusing the same templates work.
1273 CLASSNAME=self._class_name, 1236 CLASSNAME=self._class_name,
1274 EXTENDS=extends, 1237 EXTENDS=extends,
1275 IMPLEMENTS=' implements ' + implements_str) 1238 IMPLEMENTS=' implements ' + implements_str)
1276 1239
1277 # Document requires a custom wrapper. 1240 self._members_emitter.Emit(
1278 if dom_name != 'Document': 1241 ' $(CLASSNAME)._wrap(ptr) : super._wrap(ptr);\n',
1279 self._members_emitter.Emit( 1242 CLASSNAME=self._class_name)
1280 ' $(CLASSNAME)._wrap(ptr) : super._wrap(ptr);\n',
1281 CLASSNAME=self._class_name)
1282 1243
1283 # Emit a factory provider class for the constructor. 1244 # Emit a factory provider class for the constructor.
1284 constructor_info = AnalyzeConstructor(interface) 1245 constructor_info = AnalyzeConstructor(interface)
1285 if constructor_info: 1246 if constructor_info:
1286 self._EmitFactoryProvider(interface_name, constructor_info) 1247 self._EmitFactoryProvider(interface_name, constructor_info)
1287 1248
1288 emit_events, events = self._shared.GetEventAttributes(self._interface) 1249 emit_events, events = self._shared.GetEventAttributes(self._interface)
1289 if not emit_events: 1250 if not emit_events:
1290 return 1251 return
1291 elif events: 1252 elif events:
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1355 1316
1356 def _MethodName(self, prefix, name): 1317 def _MethodName(self, prefix, name):
1357 method_name = prefix + name 1318 method_name = prefix + name
1358 if name in self._base_members: # Avoid illegal Dart 'static override'. 1319 if name in self._base_members: # Avoid illegal Dart 'static override'.
1359 method_name = method_name + '_' + self._interface.id 1320 method_name = method_name + '_' + self._interface.id
1360 return method_name 1321 return method_name
1361 1322
1362 def AddAttribute(self, getter, setter): 1323 def AddAttribute(self, getter, setter):
1363 dom_name = DartDomNameOfAttribute(getter or setter) 1324 dom_name = DartDomNameOfAttribute(getter or setter)
1364 html_getter_name = self._shared.RenameInHtmlLibrary( 1325 html_getter_name = self._shared.RenameInHtmlLibrary(
1365 self._interface, dom_name, 'get:') 1326 self._interface, dom_name, 'get:', implementation_class=True)
1366 html_setter_name = self._shared.RenameInHtmlLibrary( 1327 html_setter_name = self._shared.RenameInHtmlLibrary(
1367 self._interface, dom_name, 'set:') 1328 self._interface, dom_name, 'set:', implementation_class=True)
1368 1329
1369 if getter and html_getter_name: 1330 if getter and html_getter_name:
1370 self._AddGetter(getter, html_getter_name) 1331 self._AddGetter(getter, html_getter_name)
1371 if setter and html_setter_name: 1332 if setter and html_setter_name:
1372 self._AddSetter(setter, html_setter_name) 1333 self._AddSetter(setter, html_setter_name)
1373 1334
1374 def _AddGetter(self, attr, html_name): 1335 def _AddGetter(self, attr, html_name):
1375 if self._shared.MaybeReturnDocument(attr.type.id): 1336 self._members_emitter.Emit(
1376 self._members_emitter.Emit( 1337 '\n'
1377 '\n' 1338 ' $TYPE get $(HTML_NAME)() => _wrap($(THIS).$DOM_NAME);\n',
1378 ' $TYPE get $(HTML_NAME)() => ' 1339 HTML_NAME=html_name,
1379 '_FixHtmlDocumentReference(_wrap($(THIS).$DOM_NAME));\n', 1340 DOM_NAME=DartDomNameOfAttribute(attr),
1380 HTML_NAME=html_name, 1341 TYPE=DartType(attr.type.id),
1381 DOM_NAME=DartDomNameOfAttribute(attr), 1342 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 1343
1393 def _AddSetter(self, attr, html_name): 1344 def _AddSetter(self, attr, html_name):
1394 self._members_emitter.Emit( 1345 self._members_emitter.Emit(
1395 '\n' 1346 '\n'
1396 ' void set $(HTML_NAME)($TYPE value) { ' 1347 ' void set $(HTML_NAME)($TYPE value) { '
1397 '$(THIS).$DOM_NAME = _unwrap(value); }\n', 1348 '$(THIS).$DOM_NAME = _unwrap(value); }\n',
1398 HTML_NAME=html_name, 1349 HTML_NAME=html_name,
1399 DOM_NAME=DartDomNameOfAttribute(attr), 1350 DOM_NAME=DartDomNameOfAttribute(attr),
1400 TYPE=DartType(attr.type.id), 1351 TYPE=DartType(attr.type.id),
1401 THIS=self.DomObjectName()) 1352 THIS=self.DomObjectName())
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
1615 ' }\n', 1566 ' }\n',
1616 THIS=self.DomObjectName(), 1567 THIS=self.DomObjectName(),
1617 TYPE=DartType(element_type), 1568 TYPE=DartType(element_type),
1618 METHOD=method_name) 1569 METHOD=method_name)
1619 1570
1620 def AddOperation(self, info): 1571 def AddOperation(self, info):
1621 """ 1572 """
1622 Arguments: 1573 Arguments:
1623 info: An OperationInfo object. 1574 info: An OperationInfo object.
1624 """ 1575 """
1625 html_name = self._shared.RenameInHtmlLibrary(self._interface, info.name) 1576 html_name = self._shared.RenameInHtmlLibrary(
1577 self._interface, info.name, '', implementation_class=True)
1626 1578
1627 if not html_name: 1579 if not html_name:
1628 return 1580 return
1629 1581
1630 body = self._members_emitter.Emit( 1582 body = self._members_emitter.Emit(
1631 '\n' 1583 '\n'
1632 ' $TYPE $HTML_NAME($PARAMS) {\n' 1584 ' $TYPE $HTML_NAME($PARAMS) {\n'
1633 '$!BODY' 1585 '$!BODY'
1634 ' }\n', 1586 ' }\n',
1635 TYPE=info.type_name, 1587 TYPE=info.type_name,
(...skipping 19 matching lines...) Expand all
1655 operation: the IDLOperation to call. 1607 operation: the IDLOperation to call.
1656 """ 1608 """
1657 argument_expressions = self._UnwrappedParameters( 1609 argument_expressions = self._UnwrappedParameters(
1658 info, 1610 info,
1659 len(operation.arguments)) # Just the parameters this far. 1611 len(operation.arguments)) # Just the parameters this far.
1660 1612
1661 if info.type_name != 'void': 1613 if info.type_name != 'void':
1662 # We could place the logic for handling Document directly in _wrap 1614 # 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 1615 # but we chose to place it here so that bugs in the wrapper and
1664 # wrapperless implementations are more consistent. 1616 # wrapperless implementations are more consistent.
1665 if self._shared.MaybeReturnDocument(info.type_name): 1617 emitter.Emit('$(INDENT)return _wrap($(THIS).$NAME($ARGS));\n',
1666 emitter.Emit('$(INDENT)return _FixHtmlDocumentReference(' 1618 INDENT=indent,
1667 '_wrap($(THIS).$NAME($ARGS)));\n', 1619 THIS=self.DomObjectName(),
1668 INDENT=indent, 1620 NAME=info.name,
1669 THIS=self.DomObjectName(), 1621 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: 1622 else:
1679 emitter.Emit('$(INDENT)$(THIS).$NAME($ARGS);\n' 1623 emitter.Emit('$(INDENT)$(THIS).$NAME($ARGS);\n'
1680 '$(INDENT)return;\n', 1624 '$(INDENT)return;\n',
1681 INDENT=indent, 1625 INDENT=indent,
1682 THIS=self.DomObjectName(), 1626 THIS=self.DomObjectName(),
1683 NAME=info.name, 1627 NAME=info.name,
1684 ARGS=argument_expressions) 1628 ARGS=argument_expressions)
1685 1629
1686 def GenerateDispatch(self, emitter, info, indent, position, overloads): 1630 def GenerateDispatch(self, emitter, info, indent, position, overloads):
1687 """Generates a dispatch to one of the overloads. 1631 """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 1717 # 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. 1718 # that Y = Z-X, so we need to check for Y.
1775 true_code = emitter.Emit( 1719 true_code = emitter.Emit(
1776 '$(INDENT)if ($COND) {\n' 1720 '$(INDENT)if ($COND) {\n'
1777 '$!TRUE' 1721 '$!TRUE'
1778 '$(INDENT)}\n', 1722 '$(INDENT)}\n',
1779 COND=test, INDENT=indent) 1723 COND=test, INDENT=indent)
1780 self.GenerateDispatch( 1724 self.GenerateDispatch(
1781 true_code, info, indent + ' ', position + 1, positive) 1725 true_code, info, indent + ' ', position + 1, positive)
1782 return True 1726 return True
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698