OLD | NEW |
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 * This generates the reference documentation for the core libraries that come | 6 * This generates the reference documentation for the core libraries that come |
7 * with dart. It is built on top of dartdoc, which is a general-purpose library | 7 * with dart. It is built on top of dartdoc, which is a general-purpose library |
8 * for generating docs from any Dart code. This library extends that to include | 8 * for generating docs from any Dart code. This library extends that to include |
9 * additional information and styling specific to our standard library. | 9 * additional information and styling specific to our standard library. |
10 * | 10 * |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
88 | 88 |
89 print('Parsing MDN data...'); | 89 print('Parsing MDN data...'); |
90 final mdnFile = new File.fromPath(doc.scriptDir.append('mdn/database.json')); | 90 final mdnFile = new File.fromPath(doc.scriptDir.append('mdn/database.json')); |
91 final mdn = json.parse(mdnFile.readAsStringSync()); | 91 final mdn = json.parse(mdnFile.readAsStringSync()); |
92 | 92 |
93 print('Cross-referencing dart:html...'); | 93 print('Cross-referencing dart:html...'); |
94 HtmlDiff.initialize(libPath); | 94 HtmlDiff.initialize(libPath); |
95 _diff = new HtmlDiff(printWarnings:false); | 95 _diff = new HtmlDiff(printWarnings:false); |
96 _diff.run(); | 96 _diff.run(); |
97 | 97 |
98 // Process handwritten HTML documentation. | |
99 print('Processing handwritten HTML documentation...'); | |
100 final htmldoc = new Htmldoc(); | |
101 htmldoc.includeApi = true; | |
102 htmldoc.documentLibraries( | |
103 <Path>[doc.scriptDir.append('../../tools/dom/doc/html.dartdoc')], | |
104 libPath, pkgPath); | |
105 | |
106 // Process libraries. | 98 // Process libraries. |
107 | 99 |
108 // TODO(johnniwinther): Libraries for the compilation seem to be more like | 100 // TODO(johnniwinther): Libraries for the compilation seem to be more like |
109 // URIs. Perhaps Path should have a toURI() method. | 101 // URIs. Perhaps Path should have a toURI() method. |
110 // Add all of the core libraries. | 102 // Add all of the core libraries. |
111 final apidocLibraries = <Path>[]; | 103 final apidocLibraries = <Path>[]; |
112 LIBRARIES.forEach((String name, LibraryInfo info) { | 104 LIBRARIES.forEach((String name, LibraryInfo info) { |
113 if (info.documented) { | 105 if (info.documented) { |
114 apidocLibraries.add(new Path('dart:$name')); | 106 apidocLibraries.add(new Path('dart:$name')); |
115 } | 107 } |
(...skipping 15 matching lines...) Expand all Loading... |
131 } else if (new File.fromPath(newStylePath).existsSync()) { | 123 } else if (new File.fromPath(newStylePath).existsSync()) { |
132 apidocLibraries.add(newStylePath); | 124 apidocLibraries.add(newStylePath); |
133 includedLibraries.add(libName); | 125 includedLibraries.add(libName); |
134 } else { | 126 } else { |
135 print('Warning: could not find package at $path'); | 127 print('Warning: could not find package at $path'); |
136 } | 128 } |
137 }; | 129 }; |
138 | 130 |
139 lister.onDone = (success) { | 131 lister.onDone = (success) { |
140 print('Generating docs...'); | 132 print('Generating docs...'); |
141 final apidoc = new Apidoc(mdn, htmldoc, outputDir, mode, generateAppCache, | 133 final apidoc = new Apidoc(mdn, outputDir, mode, generateAppCache, |
142 excludedLibraries); | 134 excludedLibraries); |
143 apidoc.dartdocPath = | 135 apidoc.dartdocPath = |
144 doc.scriptDir.append('../../sdk/lib/_internal/dartdoc/'); | 136 doc.scriptDir.append('../../sdk/lib/_internal/dartdoc/'); |
145 // Select the libraries to include in the produced documentation: | 137 // Select the libraries to include in the produced documentation: |
146 apidoc.includeApi = true; | 138 apidoc.includeApi = true; |
147 apidoc.includedLibraries = includedLibraries; | 139 apidoc.includedLibraries = includedLibraries; |
148 | 140 |
149 Future.wait([copiedStatic, copiedApiDocStatic]).then((_) { | 141 Future.wait([copiedStatic, copiedApiDocStatic]).then((_) { |
150 apidoc.documentLibraries(apidocLibraries, libPath, pkgPath); | 142 apidoc.documentLibraries(apidocLibraries, libPath, pkgPath); |
151 | 143 |
152 final compiled = doc.compileScript(mode, outputDir, libPath); | 144 final compiled = doc.compileScript(mode, outputDir, libPath); |
153 | 145 |
154 Future.wait([compiled, copiedStatic, copiedApiDocStatic]).then((_) { | 146 Future.wait([compiled, copiedStatic, copiedApiDocStatic]).then((_) { |
155 apidoc.cleanup(); | 147 apidoc.cleanup(); |
156 }); | 148 }); |
157 }); | 149 }); |
158 }; | 150 }; |
159 } | 151 } |
160 | 152 |
161 /** | |
162 * This class is purely here to scrape handwritten HTML documentation. | |
163 * This scraped documentation will later be merged with the generated | |
164 * HTML library. | |
165 */ | |
166 class Htmldoc extends doc.Dartdoc { | |
167 doc.DocComment libraryComment; | |
168 | |
169 /** | |
170 * Map from qualified type names to comments. | |
171 */ | |
172 Map<String, doc.DocComment> typeComments; | |
173 | |
174 /** | |
175 * Map from qualified member names to comments. | |
176 */ | |
177 Map<String, doc.DocComment> memberComments; | |
178 | |
179 Htmldoc() { | |
180 typeComments = new Map<String, doc.DocComment>(); | |
181 memberComments = new Map<String, doc.DocComment>(); | |
182 } | |
183 | |
184 // Suppress any actual writing to file. This is only for analysis. | |
185 void endFile() { | |
186 } | |
187 | |
188 void write(String s) { | |
189 } | |
190 | |
191 doc.DocComment getRecordedLibraryComment(LibraryMirror library) { | |
192 if (HTML_LIBRARY_NAMES.contains(doc.displayName(library))) { | |
193 return libraryComment; | |
194 } | |
195 return null; | |
196 } | |
197 | |
198 doc.DocComment getRecordedTypeComment(TypeMirror type) { | |
199 if (typeComments.containsKey(type.qualifiedName)) { | |
200 return typeComments[type.qualifiedName]; | |
201 } | |
202 return null; | |
203 } | |
204 | |
205 doc.DocComment getRecordedMemberComment(MemberMirror member) { | |
206 if (memberComments.containsKey(member.qualifiedName)) { | |
207 return memberComments[member.qualifiedName]; | |
208 } | |
209 return null; | |
210 } | |
211 | |
212 // These methods are subclassed and used for internal processing. | |
213 // Do not invoke outside of this class. | |
214 doc.DocComment getLibraryComment(LibraryMirror library) { | |
215 doc.DocComment comment = super.getLibraryComment(library); | |
216 libraryComment = comment; | |
217 return comment; | |
218 } | |
219 | |
220 doc.DocComment getTypeComment(TypeMirror type) { | |
221 doc.DocComment comment = super.getTypeComment(type); | |
222 recordTypeComment(type, comment); | |
223 return comment; | |
224 } | |
225 | |
226 doc.DocComment getMemberComment(MemberMirror member) { | |
227 doc.DocComment comment = super.getMemberComment(member); | |
228 recordMemberComment(member, comment); | |
229 return comment; | |
230 } | |
231 | |
232 void recordTypeComment(TypeMirror type, doc.DocComment comment) { | |
233 if (comment != null && comment.text.contains('@domName')) { | |
234 // This is not a handwritten comment. | |
235 return; | |
236 } | |
237 typeComments[type.qualifiedName] = comment; | |
238 } | |
239 | |
240 void recordMemberComment(MemberMirror member, doc.DocComment comment) { | |
241 if (comment != null && comment.text.contains('@domName')) { | |
242 // This is not a handwritten comment. | |
243 return; | |
244 } | |
245 memberComments[member.qualifiedName] = comment; | |
246 } | |
247 } | |
248 | |
249 class Apidoc extends doc.Dartdoc { | 153 class Apidoc extends doc.Dartdoc { |
250 /** Big ball of JSON containing the scraped MDN documentation. */ | 154 /** Big ball of JSON containing the scraped MDN documentation. */ |
251 final Map mdn; | 155 final Map mdn; |
252 | 156 |
253 final Htmldoc htmldoc; | |
254 | 157 |
255 static const disqusShortname = 'dartapidocs'; | 158 static const disqusShortname = 'dartapidocs'; |
256 | 159 |
257 // A set of type names (TypeMirror.simpleName values) to ignore while | 160 // A set of type names (TypeMirror.simpleName values) to ignore while |
258 // looking up information from MDN data. TODO(eub, jacobr): fix up the MDN | 161 // looking up information from MDN data. TODO(eub, jacobr): fix up the MDN |
259 // import scripts so they run correctly and generate data that doesn't have | 162 // import scripts so they run correctly and generate data that doesn't have |
260 // any entries that need to be ignored. | 163 // any entries that need to be ignored. |
261 static Set<String> _mdnTypeNamesToSkip = null; | 164 static Set<String> _mdnTypeNamesToSkip = null; |
262 | 165 |
263 /** | 166 /** |
264 * The URL to the page on MDN that content was pulled from for the current | 167 * The URL to the page on MDN that content was pulled from for the current |
265 * type being documented. Will be `null` if the type doesn't use any MDN | 168 * type being documented. Will be `null` if the type doesn't use any MDN |
266 * content. | 169 * content. |
267 */ | 170 */ |
268 String mdnUrl = null; | 171 String mdnUrl = null; |
269 | 172 |
270 Apidoc(this.mdn, this.htmldoc, Path outputDir, int mode, | 173 Apidoc(this.mdn, Path outputDir, int mode, |
271 bool generateAppCache, [excludedLibraries]) { | 174 bool generateAppCache, [excludedLibraries]) { |
272 if (?excludedLibraries) { | 175 if (?excludedLibraries) { |
273 this.excludedLibraries = excludedLibraries; | 176 this.excludedLibraries = excludedLibraries; |
274 } | 177 } |
275 | 178 |
276 this.outputDir = outputDir; | 179 this.outputDir = outputDir; |
277 this.mode = mode; | 180 this.mode = mode; |
278 this.generateAppCache = generateAppCache; | 181 this.generateAppCache = generateAppCache; |
279 | 182 |
280 // Skip bad entries in the checked-in mdn/database.json: | 183 // Skip bad entries in the checked-in mdn/database.json: |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
387 doc.DocComment createDocComment(String text, | 290 doc.DocComment createDocComment(String text, |
388 [ClassMirror inheritedFrom]) { | 291 [ClassMirror inheritedFrom]) { |
389 String strippedText = | 292 String strippedText = |
390 text.replaceAll(new RegExp("@([a-zA-Z]+) ([^;]+)(?:;|\$)"), | 293 text.replaceAll(new RegExp("@([a-zA-Z]+) ([^;]+)(?:;|\$)"), |
391 '').trim(); | 294 '').trim(); |
392 if (strippedText.isEmpty) return null; | 295 if (strippedText.isEmpty) return null; |
393 return super.createDocComment(strippedText, inheritedFrom); | 296 return super.createDocComment(strippedText, inheritedFrom); |
394 } | 297 } |
395 | 298 |
396 doc.DocComment getLibraryComment(LibraryMirror library) { | 299 doc.DocComment getLibraryComment(LibraryMirror library) { |
397 if (HTML_LIBRARY_NAMES.contains(doc.displayName(library))) { | |
398 return htmldoc.libraryComment; | |
399 } | |
400 return super.getLibraryComment(library); | 300 return super.getLibraryComment(library); |
401 } | 301 } |
402 | 302 |
403 doc.DocComment getTypeComment(TypeMirror type) { | 303 doc.DocComment getTypeComment(TypeMirror type) { |
404 return _mergeDocs( | 304 return _mergeDocs( |
405 includeMdnTypeComment(type), super.getTypeComment(type), | 305 includeMdnTypeComment(type), super.getTypeComment(type)); |
406 htmldoc.getRecordedTypeComment(type)); | |
407 } | 306 } |
408 | 307 |
409 doc.DocComment getMemberComment(MemberMirror member) { | 308 doc.DocComment getMemberComment(MemberMirror member) { |
410 return _mergeDocs( | 309 return _mergeDocs( |
411 includeMdnMemberComment(member), super.getMemberComment(member), | 310 includeMdnMemberComment(member), super.getMemberComment(member)); |
412 htmldoc.getRecordedMemberComment(member)); | |
413 } | 311 } |
414 | 312 |
415 doc.DocComment _mergeDocs(MdnComment mdnComment, | 313 doc.DocComment _mergeDocs(MdnComment mdnComment, |
416 doc.DocComment fileComment, | 314 doc.DocComment fileComment) { |
417 doc.DocComment handWrittenComment) { | |
418 // Prefer the hand-written comment first. | |
419 if (handWrittenComment != null) return handWrittenComment; | |
420 | |
421 // Otherwise, prefer comment from the (possibly generated) Dart file. | 315 // Otherwise, prefer comment from the (possibly generated) Dart file. |
422 if (fileComment != null) return fileComment; | 316 if (fileComment != null) return fileComment; |
423 | 317 |
424 // Finally, fallback on MDN if available. | 318 // Finally, fallback on MDN if available. |
425 if (mdnComment != null) { | 319 if (mdnComment != null) { |
426 mdnUrl = mdnComment.mdnUrl; | 320 mdnUrl = mdnComment.mdnUrl; |
427 return mdnComment; | 321 return mdnComment; |
428 } | 322 } |
429 | 323 |
430 // We got nothing! | 324 // We got nothing! |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
589 return ''' | 483 return ''' |
590 <div class="mdn"> | 484 <div class="mdn"> |
591 $mdnComment | 485 $mdnComment |
592 <div class="mdn-note"><a href="$mdnUrl">from MDN</a></div> | 486 <div class="mdn-note"><a href="$mdnUrl">from MDN</a></div> |
593 </div> | 487 </div> |
594 '''; | 488 '''; |
595 } | 489 } |
596 | 490 |
597 String toString() => mdnComment; | 491 String toString() => mdnComment; |
598 } | 492 } |
OLD | NEW |