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

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

Issue 11887006: Changed @domName annotation in comment to full fledge @DomName annotation. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Code review changes. Created 7 years, 11 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/dom/templates/html/impl/pure_interface.darttemplate ('k') | no next file » | 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:io'; 11 import 'dart:io';
12 import 'dart:async';
13 import '../../sdk/lib/html/html_common/metadata.dart';
12 14
13 // TODO(rnystrom): Use "package:" URL (#4968). 15 // TODO(rnystrom): Use "package:" URL (#4968).
14 import '../../sdk/lib/_internal/dartdoc/lib/dartdoc.dart'; 16 import '../../sdk/lib/_internal/dartdoc/lib/dartdoc.dart';
15 import '../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors.dart'; 17 import '../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors.dart';
16 import '../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors_util.dar t'; 18 import '../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors_util.dar t';
17 19
18 // TODO(amouravski): There is currently magic that looks at dart:* libraries 20 // TODO(amouravski): There is currently magic that looks at dart:* libraries
19 // rather than the declared library names. This changed due to recent syntax 21 // rather than the declared library names. This changed due to recent syntax
20 // changes. We should only need to look at the library 'html'. 22 // changes. We should only need to look at the library 'html'.
21 const List<String> HTML_LIBRARY_NAMES = const [ 23 const List<String> HTML_LIBRARY_NAMES = const [
22 'dart:html', 24 'dart:html',
23 'dart:svg', 25 'dart:svg',
24 'dart:web_audio']; 26 'dart:web_audio'];
25 const List<String> HTML_DECLARED_NAMES = const [ 27 const List<String> HTML_DECLARED_NAMES = const [
26 'html', 28 'html',
27 'svg', 29 'svg',
28 'web_audio']; 30 'web_audio'];
29 31
30 /** 32 /**
31 * A class for computing a many-to-many mapping between the types and 33 * A class for computing a many-to-many mapping between the types and
32 * members in `dart:html` and the MDN DOM types. This mapping is 34 * members in `dart:html` and the MDN DOM types. This mapping is
33 * based on two indicators: 35 * based on two indicators:
34 * 36 *
35 * 1. Auto-detected wrappers. Most `dart:html` types correspond 37 * 1. Auto-detected wrappers. Most `dart:html` types correspond
36 * straightforwardly to a single `@domName` type, and 38 * straightforwardly to a single `@DomName` type, and
37 * have the same name. In addition, most `dart:html` methods 39 * have the same name. In addition, most `dart:html` methods
38 * just call a single `@domName` method. This class 40 * just call a single `@DomName` method. This class
39 * detects these simple correspondences automatically. 41 * detects these simple correspondences automatically.
40 * 42 *
41 * 2. Manual annotations. When it's not clear which 43 * 2. Manual annotations. When it's not clear which
42 * `@domName` items a given `dart:html` item 44 * `@DomName` items a given `dart:html` item
43 * corresponds to, the `dart:html` item can be annotated in the 45 * corresponds to, the `dart:html` item can be annotated in the
44 * documentation comments using the `@domName` annotation. 46 * documentation comments using the `@DomName` annotation.
45 * 47 *
46 * The `@domName` annotations for types and members are of the form 48 * The `@DomName` annotations for types and members are of the form
47 * `@domName NAME(, NAME)*`, where the `NAME`s refer to the 49 * `@DomName NAME(, NAME)*`, where the `NAME`s refer to the
48 * `@domName` types/members that correspond to the 50 * `@DomName` types/members that correspond to the
49 * annotated `dart:html` type/member. `NAME`s on member annotations 51 * annotated `dart:html` type/member. `NAME`s on member annotations
50 * can refer to either fully-qualified member names (e.g. 52 * can refer to either fully-qualified member names (e.g.
51 * `Document.createElement`) or unqualified member names 53 * `Document.createElement`) or unqualified member names
52 * (e.g. `createElement`). Unqualified member names are assumed to 54 * (e.g. `createElement`). Unqualified member names are assumed to
53 * refer to members of one of the corresponding `@domName` 55 * refer to members of one of the corresponding `@DomName`
54 * types. 56 * types.
55 */ 57 */
56 class HtmlDiff { 58 class HtmlDiff {
57 /** 59 /**
58 * A map from `dart:html` members to the corresponding fully qualified 60 * A map from `dart:html` members to the corresponding fully qualified
59 * `@domName` member(s). 61 * `@DomName` member(s).
60 */ 62 */
61 final Map<String, Set<String>> htmlToDom; 63 final Map<String, Set<String>> htmlToDom;
62 64
63 /** A map from `dart:html` types to corresponding `@domName` types. */ 65 /** A map from `dart:html` types to corresponding `@DomName` types. */
64 final Map<String, Set<String>> htmlTypesToDom; 66 final Map<String, Set<String>> htmlTypesToDom;
65 67
66 final CommentMap comments; 68 final CommentMap comments;
67 69
68 /** If true, then print warning messages. */ 70 /** If true, then print warning messages. */
69 final bool _printWarnings; 71 final bool _printWarnings;
70 72
71 static Compilation _compilation; 73 static Compilation _compilation;
72 static MirrorSystem _mirrors; 74 static MirrorSystem _mirrors;
73 static LibraryMirror dom; 75 static LibraryMirror dom;
(...skipping 17 matching lines...) Expand all
91 htmlTypesToDom = new Map<String, Set<String>>(), 93 htmlTypesToDom = new Map<String, Set<String>>(),
92 comments = new CommentMap(); 94 comments = new CommentMap();
93 95
94 void warn(String s) { 96 void warn(String s) {
95 if (_printWarnings) { 97 if (_printWarnings) {
96 print('Warning: $s'); 98 print('Warning: $s');
97 } 99 }
98 } 100 }
99 101
100 /** 102 /**
101 * Computes the `@domName` to `dart:html` mapping, and 103 * Computes the `@DomName` to `dart:html` mapping, and
102 * places it in [htmlToDom] and [htmlTypesToDom]. Before this is run, dart2js 104 * places it in [htmlToDom] and [htmlTypesToDom]. Before this is run, dart2js
103 * should be initialized (via [parseOptions] and [initializeWorld]) and 105 * should be initialized (via [parseOptions] and [initializeWorld]) and
104 * [HtmlDiff.initialize] should be called. 106 * [HtmlDiff.initialize] should be called.
105 */ 107 */
106 void run() { 108 void run() {
107 for (var libraryName in HTML_DECLARED_NAMES) { 109 for (var libraryName in HTML_DECLARED_NAMES) {
108 var library = _mirrors.libraries[libraryName]; 110 var library = _mirrors.libraries[libraryName];
109 if (library == null) { 111 if (library == null) {
110 warn('Could not find $libraryName'); 112 warn('Could not find $libraryName');
111 return; 113 return;
112 } 114 }
113 for (ClassMirror type in library.classes.values) { 115 for (ClassMirror type in library.classes.values) {
114 final domTypes = htmlToDomTypes(type); 116 final domTypes = htmlToDomTypes(type);
115 if (domTypes.isEmpty) continue; 117 if (domTypes.isEmpty) continue;
116 118
117 htmlTypesToDom.putIfAbsent(type.qualifiedName, 119 htmlTypesToDom.putIfAbsent(type.qualifiedName,
118 () => new Set()).addAll(domTypes); 120 () => new Set()).addAll(domTypes);
119 121
120 type.members.forEach( 122 type.members.forEach(
121 (_, m) => _addMemberDiff(m, domTypes, library.simpleName)); 123 (_, m) => _addMemberDiff(m, domTypes, library.simpleName));
122 } 124 }
123 } 125 }
124 } 126 }
125 127
126 /** 128 /**
127 * Records the `@domName` to `dart:html` mapping for 129 * Records the `@DomName` to `dart:html` mapping for
128 * [htmlMember] (from `dart:html`). [domTypes] are the 130 * [htmlMember] (from `dart:html`). [domTypes] are the
129 * `@domName` type values that correspond to [htmlMember]'s 131 * `@DomName` type values that correspond to [htmlMember]'s
130 * defining type. 132 * defining type.
131 */ 133 */
132 void _addMemberDiff(MemberMirror htmlMember, List<String> domTypes, 134 void _addMemberDiff(MemberMirror htmlMember, List<String> domTypes,
133 String libraryName) { 135 String libraryName) {
134 var domMembers = htmlToDomMembers(htmlMember, domTypes); 136 var domMembers = htmlToDomMembers(htmlMember, domTypes);
135 if (htmlMember == null && !domMembers.isEmpty) { 137 if (htmlMember == null && !domMembers.isEmpty) {
136 warn('$libraryName member ' 138 warn('$libraryName member '
137 '${htmlMember.owner.simpleName}.' 139 '${htmlMember.owner.simpleName}.'
138 '${htmlMember.simpleName} has no corresponding ' 140 '${htmlMember.simpleName} has no corresponding '
139 '$libraryName member.'); 141 '$libraryName member.');
140 } 142 }
141 143
142 if (htmlMember == null) return; 144 if (htmlMember == null) return;
143 if (!domMembers.isEmpty) { 145 if (!domMembers.isEmpty) {
144 htmlToDom[htmlMember.qualifiedName] = domMembers; 146 htmlToDom[htmlMember.qualifiedName] = domMembers;
145 } 147 }
146 } 148 }
147 149
148 /** 150 /**
149 * Returns the `@domName` type values that correspond to 151 * Returns the `@DomName` type values that correspond to
150 * [htmlType] from `dart:html`. This can be the empty list if no 152 * [htmlType] from `dart:html`. This can be the empty list if no
151 * correspondence is found. 153 * correspondence is found.
152 */ 154 */
153 List<String> htmlToDomTypes(ClassMirror htmlType) { 155 List<String> htmlToDomTypes(ClassMirror htmlType) {
154 if (htmlType.simpleName == null) return []; 156 if (htmlType.simpleName == null) return <String>[];
155 final tags = _getTags(comments.find(htmlType.location)); 157
156 if (tags.containsKey('domName')) { 158 final domNameMetadata = _findMetadata(htmlType.metadata, 'DomName');
159 if (domNameMetadata != null) {
157 var domNames = <String>[]; 160 var domNames = <String>[];
158 for (var s in tags['domName'].split(',')) { 161 var tags = deprecatedFutureValue(domNameMetadata.getField('name'));
162 for (var s in tags.reflectee.split(',')) {
159 domNames.add(s.trim()); 163 domNames.add(s.trim());
160 } 164 }
165
161 if (domNames.length == 1 && domNames[0] == 'none') return <String>[]; 166 if (domNames.length == 1 && domNames[0] == 'none') return <String>[];
162 return domNames; 167 return domNames;
163 } 168 }
164 return <String>[]; 169 return <String>[];
165 } 170 }
166 171
167 /** 172 /**
168 * Returns the `@domName` member values that correspond to 173 * Returns the `@DomName` member values that correspond to
169 * [htmlMember] from `dart:html`. This can be the empty set if no 174 * [htmlMember] from `dart:html`. This can be the empty set if no
170 * correspondence is found. [domTypes] are the 175 * correspondence is found. [domTypes] are the
171 * `@domName` type values that correspond to [htmlMember]'s 176 * `@DomName` type values that correspond to [htmlMember]'s
172 * defining type. 177 * defining type.
173 */ 178 */
174 Set<String> htmlToDomMembers(MemberMirror htmlMember, List<String> domTypes) { 179 Set<String> htmlToDomMembers(MemberMirror htmlMember, List<String> domTypes) {
175 if (htmlMember.isPrivate) return new Set(); 180 if (htmlMember.isPrivate) return new Set();
176 final tags = _getTags(comments.find(htmlMember.location)); 181
177 if (tags.containsKey('domName')) { 182 final domNameMetadata = _findMetadata(htmlMember.metadata, 'DomName');
183 if (domNameMetadata != null) {
178 var domNames = <String>[]; 184 var domNames = <String>[];
179 for (var s in tags['domName'].split(',')) { 185 var tags = deprecatedFutureValue(domNameMetadata.getField('name'));
186 for (var s in tags.reflectee.split(',')) {
180 domNames.add(s.trim()); 187 domNames.add(s.trim());
181 } 188 }
189
182 if (domNames.length == 1 && domNames[0] == 'none') return new Set(); 190 if (domNames.length == 1 && domNames[0] == 'none') return new Set();
183 final members = new Set(); 191 final members = new Set();
184 domNames.forEach((name) { 192 domNames.forEach((name) {
185 var nameMembers = _membersFromName(name, domTypes); 193 var nameMembers = _membersFromName(name, domTypes);
186 if (nameMembers.isEmpty) { 194 if (nameMembers.isEmpty) {
187 if (name.contains('.')) { 195 if (name.contains('.')) {
188 warn('no member $name'); 196 warn('no member $name');
189 } else { 197 } else {
190 final options = <String>[]; 198 final options = <String>[];
191 for (var t in domTypes) { 199 for (var t in domTypes) {
192 options.add('$t.$name'); 200 options.add('$t.$name');
193 } 201 }
194 Strings.join(options, ' or '); 202 Strings.join(options, ' or ');
195 warn('no member $options'); 203 warn('no member $options');
196 } 204 }
197 } 205 }
198 members.addAll(nameMembers); 206 members.addAll(nameMembers);
199 }); 207 });
200 return members; 208 return members;
201 } 209 }
202 210
203 return new Set(); 211 return new Set();
204 } 212 }
205 213
206 /** 214 /**
207 * Returns the `@domName` strings that are indicated by 215 * Returns the `@DomName` strings that are indicated by
208 * [name]. [name] can be either an unqualified member name 216 * [name]. [name] can be either an unqualified member name
209 * (e.g. `createElement`), in which case it's treated as the name of 217 * (e.g. `createElement`), in which case it's treated as the name of
210 * a member of one of [defaultTypes], or a fully-qualified member 218 * a member of one of [defaultTypes], or a fully-qualified member
211 * name (e.g. `Document.createElement`), in which case it's treated as a 219 * name (e.g. `Document.createElement`), in which case it's treated as a
212 * member of the @domName element (`Document` in this case). 220 * member of the @DomName element (`Document` in this case).
213 */ 221 */
214 Set<String> _membersFromName(String name, List<String> defaultTypes) { 222 Set<String> _membersFromName(String name, List<String> defaultTypes) {
215 if (!name.contains('.', 0)) { 223 if (!name.contains('.', 0)) {
216 if (defaultTypes.isEmpty) { 224 if (defaultTypes.isEmpty) {
217 warn('no default type for $name'); 225 warn('no default type for $name');
218 return new Set(); 226 return new Set();
219 } 227 }
220 final members = new Set<String>(); 228 final members = new Set<String>();
221 defaultTypes.forEach((t) { members.add('$t.$name'); }); 229 defaultTypes.forEach((t) { members.add('$t.$name'); });
222 return members; 230 return members;
223 } 231 }
224 232
225 if (name.split('.').length != 2) { 233 if (name.split('.').length != 2) {
226 warn('invalid member name ${name}'); 234 warn('invalid member name ${name}');
227 return new Set(); 235 return new Set();
228 } 236 }
229 return new Set.from([name]); 237 return new Set.from([name]);
230 } 238 }
231 239
232 /**
233 * Extracts a [Map] from tag names to values from [comment], which is parsed
234 * from a Dart source file via dartdoc. Tags are of the form `@NAME VALUE`,
235 * where `NAME` is alphabetic and `VALUE` can contain any character other than
236 * `;`. Multiple tags can be separated by semicolons.
237 *
238 * At time of writing, the only tag that's used is `@domName`.
239 */
240 Map<String, String> _getTags(String comment) {
241 if (comment == null) return const <String, String>{};
242 final re = new RegExp("@([a-zA-Z]+) ([^;]+)(?:;|\$)");
243 final tags = <String, String>{};
244 for (var m in re.allMatches(comment.trim())) {
245 tags[m[1]] = m[2];
246 }
247 return tags;
248 }
249 } 240 }
241
242 /// Returns the metadata for the given string or null if not found.
243 InstanceMirror _findMetadata(List<InstanceMirror> metadataList, String find) {
244 return metadataList.firstMatching(
245 (metadata) => metadata.type.simpleName == find,
246 orElse: () => null);
247 }
OLDNEW
« no previous file with comments | « tools/dom/templates/html/impl/pure_interface.darttemplate ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698