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 * |
11 * Usage: | 11 * Usage: |
12 * | 12 * |
13 * $ dart apidoc.dart [--out=<output directory>] | 13 * $ dart apidoc.dart [--out=<output directory>] |
14 */ | 14 */ |
15 library apidoc; | 15 library apidoc; |
16 | 16 |
17 import 'dart:async'; | 17 import 'dart:async'; |
18 import 'dart:io'; | 18 import 'dart:io'; |
19 import 'dart:json' as json; | 19 import 'dart:json' as json; |
20 | 20 |
21 import 'html_diff.dart'; | 21 import 'html_diff.dart'; |
22 | 22 |
23 // TODO(rnystrom): Use "package:" URL (#4968). | 23 // TODO(rnystrom): Use "package:" URL (#4968). |
24 import '../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors.dart'; | 24 import '../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors.dart'; |
25 import '../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors_util.dar
t'; | 25 import '../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors_util.dar
t'; |
26 import '../../sdk/lib/_internal/compiler/implementation/filenames.dart'; | 26 import '../../sdk/lib/_internal/compiler/implementation/filenames.dart'; |
27 import '../../sdk/lib/_internal/dartdoc/lib/dartdoc.dart'; | 27 import '../../sdk/lib/_internal/dartdoc/lib/dartdoc.dart'; |
28 import '../../sdk/lib/_internal/libraries.dart'; | 28 import '../../sdk/lib/_internal/libraries.dart'; |
29 import 'package:path/path.dart' as pathos; | 29 import 'package:path/path.dart' as path; |
30 | 30 |
31 HtmlDiff _diff; | 31 HtmlDiff _diff; |
32 | 32 |
33 void main() { | 33 void main() { |
34 final args = new Options().arguments; | 34 final args = new Options().arguments; |
35 | 35 |
36 int mode = MODE_STATIC; | 36 int mode = MODE_STATIC; |
37 Path outputDir = new Path('docs'); | 37 String outputDir = 'docs'; |
38 bool generateAppCache = false; | 38 bool generateAppCache = false; |
39 | 39 |
40 List<String> excludedLibraries = <String>[]; | 40 List<String> excludedLibraries = <String>[]; |
41 | 41 |
42 // For libraries that have names matching the package name, | 42 // For libraries that have names matching the package name, |
43 // such as library unittest in package unittest, we just give | 43 // such as library unittest in package unittest, we just give |
44 // the package name with a --include-lib argument, such as: | 44 // the package name with a --include-lib argument, such as: |
45 // --include-lib=unittest. These arguments are collected in | 45 // --include-lib=unittest. These arguments are collected in |
46 // includedLibraries. | 46 // includedLibraries. |
47 List<String> includedLibraries = <String>[]; | 47 List<String> includedLibraries = <String>[]; |
(...skipping 26 matching lines...) Expand all Loading... |
74 break; | 74 break; |
75 | 75 |
76 default: | 76 default: |
77 if (arg.startsWith('--exclude-lib=')) { | 77 if (arg.startsWith('--exclude-lib=')) { |
78 excludedLibraries.add(arg.substring('--exclude-lib='.length)); | 78 excludedLibraries.add(arg.substring('--exclude-lib='.length)); |
79 } else if (arg.startsWith('--include-lib=')) { | 79 } else if (arg.startsWith('--include-lib=')) { |
80 includedLibraries.add(arg.substring('--include-lib='.length)); | 80 includedLibraries.add(arg.substring('--include-lib='.length)); |
81 } else if (arg.startsWith('--extra-lib=')) { | 81 } else if (arg.startsWith('--extra-lib=')) { |
82 extraLibraries.add(arg.substring('--extra-lib='.length)); | 82 extraLibraries.add(arg.substring('--extra-lib='.length)); |
83 } else if (arg.startsWith('--out=')) { | 83 } else if (arg.startsWith('--out=')) { |
84 outputDir = new Path(arg.substring('--out='.length)); | 84 outputDir = arg.substring('--out='.length); |
85 } else if (arg.startsWith('--package-root=')) { | 85 } else if (arg.startsWith('--package-root=')) { |
86 packageRoot = arg.substring('--package-root='.length); | 86 packageRoot = arg.substring('--package-root='.length); |
87 } else if (arg.startsWith('--version=')) { | 87 } else if (arg.startsWith('--version=')) { |
88 version = arg.substring('--version='.length); | 88 version = arg.substring('--version='.length); |
89 } else { | 89 } else { |
90 print('Unknown option: $arg'); | 90 print('Unknown option: $arg'); |
91 return; | 91 return; |
92 } | 92 } |
93 break; | 93 break; |
94 } | 94 } |
95 } | 95 } |
96 | 96 |
97 final libPath = scriptDir.append('../../sdk/'); | 97 final libPath = path.join(scriptDir, '..', '..', 'sdk/'); |
98 | 98 |
99 cleanOutputDirectory(outputDir); | 99 cleanOutputDirectory(outputDir); |
100 | 100 |
101 print('Copying static files...'); | 101 print('Copying static files...'); |
102 // The basic dartdoc-provided static content. | 102 // The basic dartdoc-provided static content. |
103 final copiedStatic = copyDirectory( | 103 final copiedStatic = copyDirectory( |
104 scriptDir.append('../../sdk/lib/_internal/dartdoc/static'), | 104 path.join(scriptDir, |
| 105 '..', '..', 'sdk', 'lib', '_internal', 'dartdoc', 'static'), |
105 outputDir); | 106 outputDir); |
106 | 107 |
107 // The apidoc-specific static content. | 108 // The apidoc-specific static content. |
108 final copiedApiDocStatic = copyDirectory( | 109 final copiedApiDocStatic = copyDirectory( |
109 scriptDir.append('static'), | 110 path.join(scriptDir, 'static'), |
110 outputDir); | 111 outputDir); |
111 | 112 |
112 print('Parsing MDN data...'); | 113 print('Parsing MDN data...'); |
113 final mdnFile = new File.fromPath(scriptDir.append('mdn/database.json')); | 114 final mdnFile = new File(path.join(scriptDir, 'mdn', 'database.json')); |
114 final mdn = json.parse(mdnFile.readAsStringSync()); | 115 final mdn = json.parse(mdnFile.readAsStringSync()); |
115 | 116 |
116 print('Cross-referencing dart:html...'); | 117 print('Cross-referencing dart:html...'); |
117 // TODO(amouravski): move HtmlDiff inside of the future chain below to re-use | 118 // TODO(amouravski): move HtmlDiff inside of the future chain below to re-use |
118 // the MirrorSystem already analyzed. | 119 // the MirrorSystem already analyzed. |
119 _diff = new HtmlDiff(printWarnings:false); | 120 _diff = new HtmlDiff(printWarnings:false); |
120 Future htmlDiff = _diff.run(currentDirectory.resolve(libPath.toString())); | 121 Future htmlDiff = _diff.run(currentDirectory.resolve(libPath)); |
121 | 122 |
122 // TODO(johnniwinther): Libraries for the compilation seem to be more like | 123 // TODO(johnniwinther): Libraries for the compilation seem to be more like |
123 // URIs. Perhaps Path should have a toURI() method. | 124 // URIs. Perhaps Path should have a toURI() method. |
124 // Add all of the core libraries. | 125 // Add all of the core libraries. |
125 final apidocLibraries = <Uri>[]; | 126 final apidocLibraries = <Uri>[]; |
126 LIBRARIES.forEach((String name, LibraryInfo info) { | 127 LIBRARIES.forEach((String name, LibraryInfo info) { |
127 if (info.documented) { | 128 if (info.documented) { |
128 apidocLibraries.add(Uri.parse('dart:$name')); | 129 apidocLibraries.add(Uri.parse('dart:$name')); |
129 } | 130 } |
130 }); | 131 }); |
131 | 132 |
132 // TODO(amouravski): This code is really wonky. | 133 // TODO(amouravski): This code is really wonky. |
133 var lister = new Directory.fromPath(scriptDir.append('../../pkg')).list(); | 134 var lister = new Directory(path.join(scriptDir, '..', '..', 'pkg')).list(); |
134 lister.listen((entity) { | 135 lister.listen((entity) { |
135 if (entity is Directory) { | 136 if (entity is Directory) { |
136 var path = new Path(entity.path); | 137 var libName = path.basename(entity.path); |
137 var libName = path.filename; | 138 var libPath = path.join(entity.path, 'lib', '${libName}.dart'); |
138 var libPath = path.append('lib/$libName.dart'); | |
139 | 139 |
140 // Ignore some libraries. | 140 // Ignore some libraries. |
141 if (excludedLibraries.contains(libName)) { | 141 if (excludedLibraries.contains(libName)) { |
142 return; | 142 return; |
143 } | 143 } |
144 | 144 |
145 // Ignore hidden directories (like .svn) as well as pkg.xcodeproj. | 145 // Ignore hidden directories (like .svn) as well as pkg.xcodeproj. |
146 if (libName.startsWith('.') || libName.endsWith('.xcodeproj')) { | 146 if (libName.startsWith('.') || libName.endsWith('.xcodeproj')) { |
147 return; | 147 return; |
148 } | 148 } |
149 | 149 |
150 if (new File.fromPath(libPath).existsSync()) { | 150 if (new File(libPath).existsSync()) { |
151 apidocLibraries.add(pathos.toUri(libPath.toNativePath())); | 151 apidocLibraries.add(path.toUri(libPath)); |
152 includedLibraries.add(libName); | 152 includedLibraries.add(libName); |
153 } else { | 153 } else { |
154 print('Warning: could not find package at $path'); | 154 print('Warning: could not find package at ${entity.path}'); |
155 } | 155 } |
156 } | 156 } |
157 }, onDone: () { | 157 }, onDone: () { |
158 // Add any --extra libraries that had full pkg paths. | 158 // Add any --extra libraries that had full pkg paths. |
159 // TODO(gram): if the handling of --include-lib libraries in the | 159 // TODO(gram): if the handling of --include-lib libraries in the |
160 // listen() block above is cleaned up, then this will need to be | 160 // listen() block above is cleaned up, then this will need to be |
161 // too, as it is a special case of the above. | 161 // too, as it is a special case of the above. |
162 for (var lib in extraLibraries) { | 162 for (var lib in extraLibraries) { |
163 var libPath = new Path('../../$lib'); | 163 var libPath = '../../$lib'; |
164 if (new File.fromPath(libPath).existsSync()) { | 164 if (new File(libPath).existsSync()) { |
165 apidocLibraries.add(pathos.toUri(libPath.toNativePath())); | 165 apidocLibraries.add(path.toUri(libPath)); |
166 var libName = libPath.filename.replaceAll('.dart', ''); | 166 var libName = libPath.replaceAll('.dart', ''); |
167 includedLibraries.add(libName); | 167 includedLibraries.add(libName); |
168 } | 168 } |
169 } | 169 } |
170 | 170 |
171 final apidoc = new Apidoc(mdn, outputDir, mode, generateAppCache, | 171 final apidoc = new Apidoc(mdn, outputDir, mode, generateAppCache, |
172 excludedLibraries, version); | 172 excludedLibraries, version); |
173 apidoc.dartdocPath = | 173 apidoc.dartdocPath = |
174 scriptDir.append('../../sdk/lib/_internal/dartdoc/'); | 174 path.join(scriptDir, '..', '..', 'sdk', 'lib', '_internal', 'dartdoc'); |
175 // Select the libraries to include in the produced documentation: | 175 // Select the libraries to include in the produced documentation: |
176 apidoc.includeApi = true; | 176 apidoc.includeApi = true; |
177 apidoc.includedLibraries = includedLibraries; | 177 apidoc.includedLibraries = includedLibraries; |
178 | 178 |
179 // TODO(amouravski): make apidoc use roughly the same flow as bin/dartdoc. | 179 // TODO(amouravski): make apidoc use roughly the same flow as bin/dartdoc. |
180 Future.wait([copiedStatic, copiedApiDocStatic, htmlDiff]) | 180 Future.wait([copiedStatic, copiedApiDocStatic, htmlDiff]) |
181 .then((_) => apidoc.documentLibraries(apidocLibraries, libPath, | 181 .then((_) => apidoc.documentLibraries(apidocLibraries, libPath, |
182 packageRoot)) | 182 packageRoot)) |
183 .then((_) => compileScript(mode, outputDir, libPath, apidoc.tmpPath)) | 183 .then((_) => compileScript(mode, outputDir, libPath, apidoc.tmpPath)) |
184 .then((_) => print(apidoc.status)) | 184 .then((_) => print(apidoc.status)) |
(...skipping 19 matching lines...) Expand all Loading... |
204 // any entries that need to be ignored. | 204 // any entries that need to be ignored. |
205 static Set<String> _mdnTypeNamesToSkip = null; | 205 static Set<String> _mdnTypeNamesToSkip = null; |
206 | 206 |
207 /** | 207 /** |
208 * The URL to the page on MDN that content was pulled from for the current | 208 * The URL to the page on MDN that content was pulled from for the current |
209 * type being documented. Will be `null` if the type doesn't use any MDN | 209 * type being documented. Will be `null` if the type doesn't use any MDN |
210 * content. | 210 * content. |
211 */ | 211 */ |
212 String mdnUrl = null; | 212 String mdnUrl = null; |
213 | 213 |
214 Apidoc(this.mdn, Path outputDir, int mode, bool generateAppCache, | 214 Apidoc(this.mdn, String outputDir, int mode, bool generateAppCache, |
215 [List<String> excludedLibraries, String version]) { | 215 [List<String> excludedLibraries, String version]) { |
216 if (excludedLibraries != null) this.excludedLibraries = excludedLibraries; | 216 if (excludedLibraries != null) this.excludedLibraries = excludedLibraries; |
217 this.version = version; | 217 this.version = version; |
218 this.outputDir = outputDir; | 218 this.outputDir = outputDir; |
219 this.mode = mode; | 219 this.mode = mode; |
220 this.generateAppCache = generateAppCache; | 220 this.generateAppCache = generateAppCache; |
221 | 221 |
222 // Skip bad entries in the checked-in mdn/database.json: | 222 // Skip bad entries in the checked-in mdn/database.json: |
223 // * UnknownElement has a top-level Gecko DOM page in German. | 223 // * UnknownElement has a top-level Gecko DOM page in German. |
224 if (_mdnTypeNamesToSkip == null) | 224 if (_mdnTypeNamesToSkip == null) |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
472 var memberName = '$typeName.${member.simpleName}'; | 472 var memberName = '$typeName.${member.simpleName}'; |
473 if (member is MethodMirror && member.isConstructor) { | 473 if (member is MethodMirror && member.isConstructor) { |
474 final separator = member.constructorName == '' ? '' : '.'; | 474 final separator = member.constructorName == '' ? '' : '.'; |
475 memberName = 'new $typeName$separator${member.constructorName}'; | 475 memberName = 'new $typeName$separator${member.constructorName}'; |
476 } | 476 } |
477 | 477 |
478 return a(memberUrl(member), memberName); | 478 return a(memberUrl(member), memberName); |
479 } | 479 } |
480 } | 480 } |
481 | 481 |
OLD | NEW |