OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |