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

Side by Side Diff: utils/apidoc/html_diff.dart

Issue 9600035: Enable new dart:html wrapperless frog bindings and wrapper dartium bindings. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Handle all code review comments 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
« no previous file with comments | « tools/testing/frogpad/frogpad.py ('k') | utils/apidoc/mdn/extract.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 /** 5 /**
6 * A script to assist in documenting the difference between the dart:html API 6 * A script to assist in documenting the difference between the dart:html API
7 * and the old DOM API. 7 * and the old DOM API.
8 */ 8 */
9 #library('html_diff'); 9 #library('html_diff');
10 10
11 #import('dart:coreimpl'); 11 #import('dart:coreimpl');
12 #import('../../frog/lang.dart'); 12 #import('../../frog/lang.dart');
13 #import('../../frog/file_system_vm.dart'); 13 #import('../../frog/file_system_vm.dart');
14 #import('../../frog/file_system.dart'); 14 #import('../../frog/file_system.dart');
15 #import('../../lib/dartdoc/dartdoc.dart'); 15 #import('../../lib/dartdoc/dartdoc.dart');
16 16
17 /** 17 /**
18 * A class for computing a many-to-many mapping between the types and members in 18 * A class for computing a many-to-many mapping between the types and members in
19 * `dart:dom` and `dart:html`. This mapping is based on two indicators: 19 * `dart:dom` and `dart:html`. This mapping is based on two indicators:
20 * 20 *
21 * 1. Auto-detected wrappers. Most `dart:html` types correspond 21 * 1. Auto-detected wrappers. Most `dart:html` types correspond
22 * straightforwardly to a single `dart:dom` type, and have the same name. 22 * straightforwardly to a single `dart:dom` type, and have the same name.
23 * In addition, most `dart:htmlimpl` methods just call a single `dart:dom` 23 * In addition, most `dart:html` methods just call a single `dart:dom`
24 * method. This class detects these simple correspondences automatically. 24 * method. This class detects these simple correspondences automatically.
25 * 25 *
26 * 2. Manual annotations. When it's not clear which `dart:dom` items a given 26 * 2. Manual annotations. When it's not clear which `dart:dom` items a given
27 * `dart:html` item corresponds to, the `dart:htmlimpl` item can be 27 * `dart:html` item corresponds to, the `dart:html` item can be
28 * annotated in the documentation comments using the `@domName` annotation. 28 * annotated in the documentation comments using the `@domName` annotation.
29 * 29 *
30 * The `@domName` annotations for types and members are of the form `@domName 30 * The `@domName` annotations for types and members are of the form `@domName
31 * NAME(, NAME)*`, where the `NAME`s refer to the `dart:dom` types/members that 31 * NAME(, NAME)*`, where the `NAME`s refer to the `dart:dom` types/members that
32 * correspond to the annotated `dart:htmlimpl` type/member. `NAME`s on member 32 * correspond to the annotated `dart:html` type/member. `NAME`s on member
33 * annotations can refer to either fully-qualified member names (e.g. 33 * annotations can refer to either fully-qualified member names (e.g.
34 * `Document.createElement`) or unqualified member names (e.g. `createElement`). 34 * `Document.createElement`) or unqualified member names (e.g. `createElement`).
35 * Unqualified member names are assumed to refer to members of one of the 35 * Unqualified member names are assumed to refer to members of one of the
36 * corresponding `dart:dom` types. 36 * corresponding `dart:dom` types.
37 */ 37 */
38 class HtmlDiff { 38 class HtmlDiff {
39 /** A map from `dart:dom` members to corresponding `dart:html` members. */ 39 /** A map from `dart:dom` members to corresponding `dart:html` members. */
40 final Map<Member, Set<Member>> domToHtml; 40 final Map<Member, Set<Member>> domToHtml;
41 41
42 /** A map from `dart:html` members to corresponding `dart:dom` members. */ 42 /** A map from `dart:html` members to corresponding `dart:dom` members. */
43 final Map<Member, Set<Member>> htmlToDom; 43 final Map<Member, Set<Member>> htmlToDom;
44 44
45 /** A map from `dart:dom` types to corresponding `dart:html` types. */ 45 /** A map from `dart:dom` types to corresponding `dart:html` types. */
46 final Map<Type, Set<Type>> domTypesToHtml; 46 final Map<Type, Set<Type>> domTypesToHtml;
47 47
48 /** A map from `dart:html` types to corresponding `dart:dom` types. */ 48 /** A map from `dart:html` types to corresponding `dart:dom` types. */
49 final Map<Type, Set<Type>> htmlTypesToDom; 49 final Map<Type, Set<Type>> htmlTypesToDom;
50 50
51 final CommentMap comments; 51 final CommentMap comments;
52 52
53 static Library dom; 53 static Library dom;
54 54
55 /** 55 /**
56 * Perform static initialization of [world]. This should be run before 56 * Perform static initialization of [world]. This should be run before
57 * calling [HtmlDiff.run]. 57 * calling [HtmlDiff.run].
58 */ 58 */
59 static void initialize() { 59 static void initialize() {
60 world.processDartScript('dart:htmlimpl'); 60 world.processDartScript('dart:html');
61 world.resolveAll(); 61 world.resolveAll();
62 dom = world.libraries['dart:dom']; 62 dom = world.libraries['dart:dom'];
63 } 63 }
64 64
65 HtmlDiff() : 65 HtmlDiff() :
66 domToHtml = new Map<Member, Set<Member>>(), 66 domToHtml = new Map<Member, Set<Member>>(),
67 htmlToDom = new Map<Member, Set<Member>>(), 67 htmlToDom = new Map<Member, Set<Member>>(),
68 domTypesToHtml = new Map<Type, Set<Type>>(), 68 domTypesToHtml = new Map<Type, Set<Type>>(),
69 htmlTypesToDom = new Map<Type, Set<Type>>(), 69 htmlTypesToDom = new Map<Type, Set<Type>>(),
70 comments = new CommentMap(); 70 comments = new CommentMap();
71 71
72 /** 72 /**
73 * Computes the `dart:dom` to `dart:html` mapping, and places it in 73 * Computes the `dart:dom` to `dart:html` mapping, and places it in
74 * [domToHtml], [htmlToDom], [domTypesToHtml], and [htmlTypesToDom]. Before 74 * [domToHtml], [htmlToDom], [domTypesToHtml], and [htmlTypesToDom]. Before
75 * this is run, Frog should be initialized (via [parseOptions] and 75 * this is run, Frog should be initialized (via [parseOptions] and
76 * [initializeWorld]) and [HtmlDiff.initialize] should be called. 76 * [initializeWorld]) and [HtmlDiff.initialize] should be called.
77 */ 77 */
78 void run() { 78 void run() {
79 final htmlLib = world.libraries['dart:htmlimpl']; 79 final htmlLib = world.libraries['dart:html'];
80 for (var implType in htmlLib.types.getValues()) { 80 for (var implType in htmlLib.types.getValues()) {
81 final domTypes = htmlToDomTypes(implType); 81 final domTypes = htmlToDomTypes(implType);
82 final htmlType = htmlImplToHtmlType(implType); 82 final htmlType = htmlImplToHtmlType(implType);
83 if (htmlType == null) continue; 83 if (htmlType == null) continue;
84 84
85 htmlTypesToDom.putIfAbsent(htmlType, () => new Set()).addAll(domTypes); 85 htmlTypesToDom.putIfAbsent(htmlType, () => new Set()).addAll(domTypes);
86 domTypes.forEach((t) => 86 domTypes.forEach((t) =>
87 domTypesToHtml.putIfAbsent(t, () => new Set()).add(htmlType)); 87 domTypesToHtml.putIfAbsent(t, () => new Set()).add(htmlType));
88 88
89 final members = new List.from(implType.members.getValues()); 89 final members = new List.from(implType.members.getValues());
(...skipping 20 matching lines...) Expand all
110 var htmlName = htmlMember.name; 110 var htmlName = htmlMember.name;
111 if (htmlName.startsWith('get:') || htmlName.startsWith('set:')) { 111 if (htmlName.startsWith('get:') || htmlName.startsWith('set:')) {
112 htmlName = htmlName.substring(4); 112 htmlName = htmlName.substring(4);
113 } 113 }
114 114
115 return domTypeName == htmlTypeName && domName == htmlName; 115 return domTypeName == htmlTypeName && domName == htmlName;
116 } 116 }
117 117
118 /** 118 /**
119 * Records the `dart:dom` to `dart:html` mapping for [implMember] (from 119 * Records the `dart:dom` to `dart:html` mapping for [implMember] (from
120 * `dart:htmlimpl`). [domTypes] are the `dart:dom` [Type]s that correspond to 120 * `dart:html`). [domTypes] are the `dart:dom` [Type]s that correspond to
121 * [implMember]'s defining [Type]. 121 * [implMember]'s defining [Type].
122 */ 122 */
123 void _addMemberDiff(Member implMember, List<Type> domTypes) { 123 void _addMemberDiff(Member implMember, List<Type> domTypes) {
124 if (implMember.isProperty) { 124 if (implMember.isProperty) {
125 if (implMember.canGet) _addMemberDiff(implMember.getter, domTypes); 125 if (implMember.canGet) _addMemberDiff(implMember.getter, domTypes);
126 if (implMember.canSet) _addMemberDiff(implMember.setter, domTypes); 126 if (implMember.canSet) _addMemberDiff(implMember.setter, domTypes);
127 } 127 }
128 128
129 var domMembers = htmlToDomMembers(implMember, domTypes); 129 var domMembers = htmlToDomMembers(implMember, domTypes);
130 var htmlMember = htmlImplToHtmlMember(implMember); 130 var htmlMember = htmlImplToHtmlMember(implMember);
131 if (htmlMember == null && !domMembers.isEmpty()) { 131 if (htmlMember == null && !domMembers.isEmpty()) {
132 print('Warning: dart:htmlimpl member ${implMember.declaringType.name}.' + 132 print('Warning: dart:html member ${implMember.declaringType.name}.' +
133 '${implMember.name} has no corresponding dart:html member.'); 133 '${implMember.name} has no corresponding dart:html member.');
134 } 134 }
135 135
136 if (htmlMember == null) return; 136 if (htmlMember == null) return;
137 if (!domMembers.isEmpty()) htmlToDom[htmlMember] = domMembers; 137 if (!domMembers.isEmpty()) htmlToDom[htmlMember] = domMembers;
138 domMembers.forEach((m) => 138 domMembers.forEach((m) =>
139 domToHtml.putIfAbsent(m, () => new Set()).add(htmlMember)); 139 domToHtml.putIfAbsent(m, () => new Set()).add(htmlMember));
140 } 140 }
141 141
142 /** 142 /**
143 * Returns the `dart:html` [Type] that corresponds to [implType] from 143 * Returns the `dart:html` [Type] that corresponds to [implType] from
144 * `dart:htmlimpl`, or `null` if there is no such correspondence. 144 * `dart:html`, or `null` if there is no such correspondence.
145 */ 145 */
146 Type htmlImplToHtmlType(Type implType) { 146 Type htmlImplToHtmlType(Type implType) {
147 if (implType == null || implType.isTop || implType.interfaces.isEmpty() || 147 if (implType == null || implType.isTop || implType.interfaces.isEmpty() ||
148 implType.interfaces[0].library.name != 'html') { 148 implType.interfaces[0].library.name != 'html') {
149 return null; 149 return null;
150 } 150 }
151 151
152 return implType.interfaces[0]; 152 return implType.interfaces[0];
153 } 153 }
154 154
155 /** 155 /**
156 * Returns the `dart:html` [Member] that corresponds to [implMember] from 156 * Returns the `dart:html` [Member] that corresponds to [implMember] from
157 * `dart:htmlimpl`, or `null` if there is no such correspondence. 157 * `dart:html`, or `null` if there is no such correspondence.
158 */ 158 */
159 Member htmlImplToHtmlMember(Member implMember) { 159 Member htmlImplToHtmlMember(Member implMember) {
160 var htmlType = htmlImplToHtmlType(implMember.declaringType); 160 var htmlType = htmlImplToHtmlType(implMember.declaringType);
161 if (htmlType == null) return null; 161 if (htmlType == null) return null;
162 162
163 bool getter, setter; 163 bool getter, setter;
164 if (implMember.isConstructor || implMember.isFactory) { 164 if (implMember.isConstructor || implMember.isFactory) {
165 var constructor = htmlType.constructors[implMember.name]; 165 var constructor = htmlType.constructors[implMember.name];
166 if (constructor != null) return constructor; 166 if (constructor != null) return constructor;
167 167
168 // Look for a factory constructor whose type and name matches the member. 168 // Look for a factory constructor whose type and name matches the member.
169 return htmlType.factories.getFactoriesFor(implMember.name)[ 169 return htmlType.factories.getFactoriesFor(implMember.name)[
170 implMember.constructorName]; 170 implMember.constructorName];
171 } else if ((getter = implMember.name.startsWith('get:')) || 171 } else if ((getter = implMember.name.startsWith('get:')) ||
172 (setter = implMember.name.startsWith('set:'))) { 172 (setter = implMember.name.startsWith('set:'))) {
173 // Use getMember to follow interface inheritance chains. 173 // Use getMember to follow interface inheritance chains.
174 var htmlProperty = htmlType.getMember(implMember.name.substring(4)); 174 var htmlProperty = htmlType.getMember(implMember.name.substring(4));
175 if (htmlProperty != null) { 175 if (htmlProperty != null) {
176 return getter ? htmlProperty.getter : htmlProperty.setter; 176 return getter ? htmlProperty.getter : htmlProperty.setter;
177 } else { 177 } else {
178 return null; 178 return null;
179 } 179 }
180 } else { 180 } else {
181 return htmlType.getMember(implMember.name); 181 return htmlType.getMember(implMember.name);
182 } 182 }
183 } 183 }
184 184
185 /** 185 /**
186 * Returns the `dart:dom` [Type]s that correspond to [htmlType] from 186 * Returns the `dart:dom` [Type]s that correspond to [htmlType] from
187 * `dart:htmlimpl`. This can be the empty list if no correspondence is found. 187 * `dart:html`. This can be the empty list if no correspondence is found.
188 */ 188 */
189 List<Type> htmlToDomTypes(Type htmlType) { 189 List<Type> htmlToDomTypes(Type htmlType) {
190 if (htmlType.name == null) return []; 190 if (htmlType.name == null) return [];
191 final tags = _getTags(comments.find(htmlType.span)); 191 final tags = _getTags(comments.find(htmlType.span));
192 192
193 if (tags.containsKey('domName')) { 193 if (tags.containsKey('domName')) {
194 var domNames = map(tags['domName'].split(','), (s) => s.trim()); 194 var domNames = map(tags['domName'].split(','), (s) => s.trim());
195 if (domNames.length == 1 && domNames[0] == 'none') return []; 195 if (domNames.length == 1 && domNames[0] == 'none') return [];
196 return map(domNames, (domName) { 196 return map(domNames, (domName) {
197 // DOMWindow is Chrome-specific, so we don't use it in our annotations. 197 // DOMWindow is Chrome-specific, so we don't use it in our annotations.
198 if (domName == 'Window') domName = 'DOMWindow'; 198 if (domName == 'Window') domName = 'DOMWindow';
199 final domType = dom.types[domName]; 199 final domType = dom.types[domName];
200 if (domType == null) print('Warning: no dart:dom type named $domName'); 200 if (domType == null) print('Warning: no dart:dom type named $domName');
201 return domType; 201 return domType;
202 }); 202 });
203 } else { 203 } else {
204 if (!htmlType.name.endsWith('WrappingImplementation')) return []; 204 if (!htmlType.name.endsWith('WrappingImplementation')) return [];
205 final domName = htmlType.name.replaceFirst('WrappingImplementation', ''); 205 final domName = htmlType.name.replaceFirst('WrappingImplementation', '');
206 var domType = dom.types[domName]; 206 var domType = dom.types[domName];
207 if (domType == null && domName.endsWith('Element')) { 207 if (domType == null && domName.endsWith('Element')) {
208 domType = dom.types['HTML$domName']; 208 domType = dom.types['HTML$domName'];
209 } 209 }
210 if (domType == null) domType = dom.types['WebKit$domName']; 210 if (domType == null) domType = dom.types['WebKit$domName'];
211 if (domType == null) { 211 if (domType == null) {
212 print('Warning: no dart:dom type matches dart:htmlimpl ' + 212 print('Warning: no dart:dom type matches dart:html ' +
213 htmlType.name); 213 htmlType.name);
214 return []; 214 return [];
215 } 215 }
216 return [domType]; 216 return [domType];
217 } 217 }
218 } 218 }
219 219
220 /** 220 /**
221 * Returns the `dart:dom` [Member]s that correspond to [htmlMember] from 221 * Returns the `dart:dom` [Member]s that correspond to [htmlMember] from
222 * `dart:htmlimpl`. This can be the empty set if no correspondence is found. 222 * `dart:html`. This can be the empty set if no correspondence is found.
223 * [domTypes] are the `dart:dom` [Type]s that correspond to [implMember]'s 223 * [domTypes] are the `dart:dom` [Type]s that correspond to [implMember]'s
224 * defining [Type]. 224 * defining [Type].
225 */ 225 */
226 Set<Member> htmlToDomMembers(Member htmlMember, List<Type> domTypes) { 226 Set<Member> htmlToDomMembers(Member htmlMember, List<Type> domTypes) {
227 if (htmlMember.isPrivate || htmlMember is! MethodMember) return new Set(); 227 if (htmlMember.isPrivate || htmlMember is! MethodMember) return new Set();
228 final tags = _getTags(comments.find(htmlMember.span)); 228 final tags = _getTags(comments.find(htmlMember.span));
229 if (tags.containsKey('domName')) { 229 if (tags.containsKey('domName')) {
230 final domNames = map(tags['domName'].split(','), (s) => s.trim()); 230 final domNames = map(tags['domName'].split(','), (s) => s.trim());
231 if (domNames.length == 1 && domNames[0] == 'none') return new Set(); 231 if (domNames.length == 1 && domNames[0] == 'none') return new Set();
232 final members = new Set(); 232 final members = new Set();
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 Map<String, String> _getTags(String comment) { 394 Map<String, String> _getTags(String comment) {
395 if (comment == null) return const <String>{}; 395 if (comment == null) return const <String>{};
396 final re = new RegExp("@([a-zA-Z]+) ([^;]+)(?:;|\$)"); 396 final re = new RegExp("@([a-zA-Z]+) ([^;]+)(?:;|\$)");
397 final tags = <String>{}; 397 final tags = <String>{};
398 for (var m in re.allMatches(comment.trim())) { 398 for (var m in re.allMatches(comment.trim())) {
399 tags[m[1]] = m[2]; 399 tags[m[1]] = m[2];
400 } 400 }
401 return tags; 401 return tags;
402 } 402 }
403 } 403 }
OLDNEW
« no previous file with comments | « tools/testing/frogpad/frogpad.py ('k') | utils/apidoc/mdn/extract.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698