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