Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 * **docgen** is a tool for creating machine readable representations of Dart | 6 * **docgen** is a tool for creating machine readable representations of Dart |
| 7 * code metadata, including: classes, members, comments and annotations. | 7 * code metadata, including: classes, members, comments and annotations. |
| 8 * | 8 * |
| 9 * docgen is run on a `.dart` file or a directory containing `.dart` files. | 9 * docgen is run on a `.dart` file or a directory containing `.dart` files. |
| 10 * | 10 * |
| 11 * $ dart docgen.dart [OPTIONS] [FILE/DIR] | 11 * $ dart docgen.dart [OPTIONS] [FILE/DIR] |
| 12 * | 12 * |
| 13 * This creates files called `docs/<library_name>.yaml` in your current | 13 * This creates files called `docs/<library_name>.yaml` in your current |
| 14 * working directory. | 14 * working directory. |
| 15 */ | 15 */ |
| 16 library docgen; | 16 library docgen; |
| 17 | 17 |
| 18 import 'dart:convert'; | 18 import 'dart:convert'; |
| 19 import 'dart:io'; | 19 import 'dart:io'; |
| 20 import 'dart:async'; | 20 import 'dart:async'; |
| 21 | 21 |
| 22 import 'package:logging/logging.dart'; | 22 import 'package:logging/logging.dart'; |
| 23 import 'package:markdown/markdown.dart' as markdown; | 23 import 'package:markdown/markdown.dart' as markdown; |
| 24 import 'package:path/path.dart' as path; | 24 import 'package:path/path.dart' as path; |
| 25 import 'package:yaml/yaml.dart'; | |
| 25 | 26 |
| 26 import 'dart2yaml.dart'; | 27 import 'dart2yaml.dart'; |
| 27 import 'src/io.dart'; | 28 import 'src/io.dart'; |
| 28 import '../../../sdk/lib/_internal/compiler/compiler.dart' as api; | 29 import '../../../sdk/lib/_internal/compiler/compiler.dart' as api; |
| 29 import '../../../sdk/lib/_internal/compiler/implementation/filenames.dart'; | 30 import '../../../sdk/lib/_internal/compiler/implementation/filenames.dart'; |
| 30 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirro r.dart' | 31 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirro r.dart' |
| 31 as dart2js; | 32 as dart2js; |
| 32 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors.dart' ; | 33 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors.dart' ; |
| 33 import '../../../sdk/lib/_internal/compiler/implementation/source_file_provider. dart'; | 34 import '../../../sdk/lib/_internal/compiler/implementation/source_file_provider. dart'; |
| 34 import '../../../sdk/lib/_internal/libraries.dart'; | 35 import '../../../sdk/lib/_internal/libraries.dart'; |
| 35 | 36 |
| 36 var logger = new Logger('Docgen'); | 37 var logger = new Logger('Docgen'); |
| 37 | 38 |
| 38 const String USAGE = 'Usage: dart docgen.dart [OPTIONS] [fooDir/barFile]'; | 39 const String USAGE = 'Usage: dart docgen.dart [OPTIONS] [fooDir/barFile]'; |
| 39 | 40 |
| 40 | 41 |
| 41 List<String> validAnnotations = const ['metadata.Experimental', | 42 List<String> validAnnotations = const ['metadata.Experimental', |
| 42 'metadata.DomName', 'metadata.Deprecated', 'metadata.Unstable', | 43 'metadata.DomName', 'metadata.Deprecated', 'metadata.Unstable', |
| 43 'meta.deprecated', 'metadata.SupportedBrowser']; | 44 'meta.deprecated', 'metadata.SupportedBrowser']; |
| 44 | 45 |
| 45 /// Current library being documented to be used for comment links. | 46 /// Current library being documented to be used for comment links. |
| 46 LibraryMirror _currentLibrary; | 47 LibraryMirror _currentLibrary; |
| 47 | 48 |
| 48 /// Current class being documented to be used for comment links. | 49 /// Current class being documented to be used for comment links. |
| 49 ClassMirror _currentClass; | 50 ClassMirror _currentClass; |
| 50 | 51 |
| 51 /// Current member being documented to be used for comment links. | 52 /// Current member being documented to be used for comment links. |
| 52 MemberMirror _currentMember; | 53 MemberMirror _currentMember; |
| 53 | 54 |
| 54 /// Support for [:foo:]-style code comments to the markdown parser. | 55 /// Support for [:foo:]-style code comments to the markdown parser. |
| 55 List<markdown.InlineSyntax> markdownSyntaxes = | 56 List<markdown.InlineSyntax> markdownSyntaxes = |
| 56 [new markdown.CodeSyntax(r'\[:\s?((?:.|\n)*?)\s?:\]')]; | 57 [new markdown.CodeSyntax(r'\[:\s?((?:.|\n)*?)\s?:\]')]; |
| 57 | 58 |
| 58 /// Resolves reference links in doc comments. | 59 /// Resolves reference links in doc comments. |
| 59 markdown.Resolver linkResolver; | 60 markdown.Resolver linkResolver; |
| 60 | 61 |
| 61 /// Index of all indexable items. This also ensures that no class is | 62 /// Index of all indexable items. This also ensures that no class is |
| 62 /// created more than once. | 63 /// created more than once. |
| 63 Map<String, Indexable> entityMap = new Map<String, Indexable>(); | 64 Map<String, Indexable> entityMap = new Map<String, Indexable>(); |
| 64 | 65 |
| 65 /// This is set from the command line arguments flag --include-private | 66 /// This is set from the command line arguments flag --include-private |
| 66 bool _includePrivate = false; | 67 bool _includePrivate = false; |
| 67 | 68 |
| 68 // TODO(janicejl): Make MDN content generic or pluggable. Maybe move | 69 // TODO(janicejl): Make MDN content generic or pluggable. Maybe move |
| 69 // MDN-specific code to its own library that is imported into the default impl? | 70 // MDN-specific code to its own library that is imported into the default impl? |
| 70 /// Map of all the comments for dom elements from MDN. | 71 /// Map of all the comments for dom elements from MDN. |
| 71 Map _mdn; | 72 Map _mdn; |
| 72 | 73 |
| 73 /** | 74 /** |
| 74 * Docgen constructor initializes the link resolver for markdown parsing. | 75 * Docgen constructor initializes the link resolver for markdown parsing. |
| 75 * Also initializes the command line arguments. | 76 * Also initializes the command line arguments. |
| 76 * | 77 * |
| 77 * [packageRoot] is the packages directory of the directory being analyzed. | 78 * [packageRoot] is the packages directory of the directory being analyzed. |
| 78 * If [includeSdk] is `true`, then any SDK libraries explicitly imported will | 79 * If [includeSdk] is `true`, then any SDK libraries explicitly imported will |
| 79 * also be documented. | 80 * also be documented. |
| 80 * If [parseSdk] is `true`, then all Dart SDK libraries will be documented. | 81 * If [parseSdk] is `true`, then all Dart SDK libraries will be documented. |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 102 } | 103 } |
| 103 logger.info('Package Root: ${packageRoot}'); | 104 logger.info('Package Root: ${packageRoot}'); |
| 104 linkResolver = (name) => | 105 linkResolver = (name) => |
| 105 fixReference(name, _currentLibrary, _currentClass, _currentMember); | 106 fixReference(name, _currentLibrary, _currentClass, _currentMember); |
| 106 | 107 |
| 107 return getMirrorSystem(files, packageRoot: packageRoot, parseSdk: parseSdk) | 108 return getMirrorSystem(files, packageRoot: packageRoot, parseSdk: parseSdk) |
| 108 .then((MirrorSystem mirrorSystem) { | 109 .then((MirrorSystem mirrorSystem) { |
| 109 if (mirrorSystem.libraries.isEmpty) { | 110 if (mirrorSystem.libraries.isEmpty) { |
| 110 throw new StateError('No library mirrors were created.'); | 111 throw new StateError('No library mirrors were created.'); |
| 111 } | 112 } |
| 112 _documentLibraries(mirrorSystem.libraries.values,includeSdk: includeSdk, | 113 var librariesWeAskedFor = _listLibraries(files); |
| 113 outputToYaml: outputToYaml, append: append, parseSdk: parseSdk, | 114 var librariesWeGot = mirrorSystem.libraries.values.where((each) |
| 115 => each.uri.scheme == 'file'); | |
| 116 var sdkLibraries = mirrorSystem.libraries.values.where( | |
| 117 (each) => each.uri.scheme == 'dart'); | |
| 118 var librariesWeGotByPath = new Map.fromIterables( | |
| 119 librariesWeGot.map((each) => each.uri.toFilePath()), | |
| 120 librariesWeGot); | |
| 121 var librariesToDocument = librariesWeAskedFor.map((each) => | |
| 122 librariesWeGotByPath | |
| 123 .putIfAbsent(each, () => throw "Missing library $each")).toList(); | |
| 124 librariesToDocument.addAll((includeSdk || parseSdk) ? sdkLibraries : []); | |
| 125 _documentLibraries(librariesToDocument, includeSdk: includeSdk, | |
| 126 outputToYaml: outputToYaml, append: append, parseSdk: parseSdk, | |
| 114 introduction: introduction); | 127 introduction: introduction); |
| 115 | |
| 116 return true; | 128 return true; |
| 117 }); | 129 }); |
| 118 } | 130 } |
| 119 | 131 |
| 132 /// For a [library] and its corresponding [mirror] that we believe come | |
| 133 /// from a package (because it has a file | |
| 134 /// URI) look for the package name and set it on [library]. | |
| 135 _findPackage(Library library, LibraryMirror mirror) { | |
| 136 if (mirror.uri.scheme != 'file') return; | |
| 137 var filePath = mirror.uri.toFilePath(); | |
| 138 // We assume that we are documenting only libraries under package/lib | |
| 139 var rootdir = path.dirname((path.dirname(filePath))); | |
| 140 var pubspec = path.join(rootdir, 'pubspec.yaml'); | |
| 141 library.packageName = _packageName(pubspec); | |
| 142 } | |
| 143 | |
| 120 List<String> _listLibraries(List<String> args) { | 144 List<String> _listLibraries(List<String> args) { |
| 121 if (args.length != 1) throw new UnsupportedError(USAGE); | |
| 122 var libraries = new List<String>(); | 145 var libraries = new List<String>(); |
| 123 var type = FileSystemEntity.typeSync(args[0]); | 146 for (var arg in args) { |
| 147 var type = FileSystemEntity.typeSync(arg); | |
| 124 | 148 |
| 125 if (type == FileSystemEntityType.FILE) { | 149 if (type == FileSystemEntityType.FILE) { |
| 126 if (args[0].endsWith('.dart')) { | 150 if (arg.endsWith('.dart')) { |
| 127 libraries.add(path.absolute(args[0])); | 151 libraries.add(path.absolute(arg)); |
| 128 logger.info('Added to libraries: ${libraries.last}'); | 152 logger.info('Added to libraries: ${libraries.last}'); |
| 153 } | |
| 154 } else { | |
| 155 libraries.addAll(_listDartFromDir(arg)); | |
| 129 } | 156 } |
| 130 } else { | |
| 131 libraries.addAll(_listDartFromDir(args[0])); | |
| 132 } | 157 } |
| 133 return libraries; | 158 return libraries; |
| 134 } | 159 } |
| 135 | 160 |
| 136 List<String> _listDartFromDir(String args) { | 161 List<String> _listDartFromDir(String args) { |
| 137 var libraries = []; | 162 var libraries = []; |
| 138 // To avoid anaylzing package files twice, only files with paths not | 163 // To avoid anaylzing package files twice, only files with paths not |
| 139 // containing '/packages' will be added. The only exception is if the file to | 164 // containing '/packages' will be added. The only exception is if the file to |
| 140 // analyze already has a '/package' in its path. | 165 // analyze already has a '/package' in its path. |
| 141 var files = listDir(args, recursive: true).where((f) => f.endsWith('.dart') && | 166 var files = listDir(args, recursive: true).where((f) => f.endsWith('.dart') && |
| 142 (!f.contains('${path.separator}packages') || | 167 (!f.contains('${path.separator}packages') || |
| 143 args.contains('${path.separator}packages'))).toList(); | 168 args.contains('${path.separator}packages'))).toList(); |
| 144 | 169 |
| 145 files.forEach((f) { | 170 files.forEach((String f) { |
| 146 // Only add the file if it does not contain 'part of' | 171 // Only include libraries at the top level of "lib" |
| 147 // TODO(janicejl): Remove when Issue(12406) is resolved. | 172 if (path.basename(path.dirname(f)) == 'lib') { |
| 148 var contents = new File(f).readAsStringSync(); | 173 // Only add the file if it does not contain 'part of' |
| 149 if (!(contents.contains(new RegExp('\npart of ')) || | 174 // TODO(janicejl): Remove when Issue(12406) is resolved. |
| 150 contents.startsWith(new RegExp('part of ')))) { | 175 var contents = new File(f).readAsStringSync(); |
| 151 libraries.add(f); | 176 if (!(contents.contains(new RegExp('\npart of ')) || |
| 152 logger.info('Added to libraries: $f'); | 177 contents.startsWith(new RegExp('part of ')))) { |
| 178 libraries.add(f); | |
| 179 logger.info('Added to libraries: $f'); | |
| 180 } | |
| 153 } | 181 } |
| 154 }); | 182 }); |
| 155 return libraries; | 183 return libraries; |
| 156 } | 184 } |
| 157 | 185 |
| 158 String _findPackageRoot(String directory) { | 186 String _findPackageRoot(String directory) { |
| 159 var files = listDir(directory, recursive: true); | 187 var files = listDir(directory, recursive: true); |
| 160 // Return '' means that there was no pubspec.yaml and therefor no packageRoot. | 188 // Return '' means that there was no pubspec.yaml and therefor no packageRoot. |
| 161 String packageRoot = files.firstWhere((f) => | 189 String packageRoot = files.firstWhere((f) => |
| 162 f.endsWith('${path.separator}pubspec.yaml'), orElse: () => ''); | 190 f.endsWith('${path.separator}pubspec.yaml'), orElse: () => ''); |
| 163 if (packageRoot != '') { | 191 if (packageRoot != '') { |
| 164 packageRoot = path.join(path.dirname(packageRoot), 'packages'); | 192 packageRoot = path.join(path.dirname(packageRoot), 'packages'); |
| 165 } | 193 } |
| 166 return packageRoot; | 194 return packageRoot; |
| 167 } | 195 } |
| 168 | 196 |
| 197 /** | |
| 198 * Read a pubspec and return the library name. | |
| 199 */ | |
| 200 String _packageName(String pubspecName) { | |
| 201 File pubspec = new File(pubspecName); | |
| 202 if (!pubspec.existsSync()) return ''; | |
| 203 var contents = pubspec.readAsStringSync(); | |
| 204 var spec = loadYaml(contents); | |
| 205 return spec["name"]; | |
| 206 } | |
| 207 | |
| 169 List<String> _listSdk() { | 208 List<String> _listSdk() { |
| 170 var sdk = new List<String>(); | 209 var sdk = new List<String>(); |
| 171 LIBRARIES.forEach((String name, LibraryInfo info) { | 210 LIBRARIES.forEach((String name, LibraryInfo info) { |
| 172 if (info.documented) { | 211 if (info.documented) { |
| 173 sdk.add('dart:$name'); | 212 sdk.add('dart:$name'); |
| 174 logger.info('Add to SDK: ${sdk.last}'); | 213 logger.info('Add to SDK: ${sdk.last}'); |
| 175 } | 214 } |
| 176 }); | 215 }); |
| 177 return sdk; | 216 return sdk; |
| 178 } | 217 } |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 193 } | 232 } |
| 194 | 233 |
| 195 /** | 234 /** |
| 196 * Analyzes set of libraries and provides a mirror system which can be used | 235 * Analyzes set of libraries and provides a mirror system which can be used |
| 197 * for static inspection of the source code. | 236 * for static inspection of the source code. |
| 198 */ | 237 */ |
| 199 Future<MirrorSystem> _analyzeLibraries(List<String> libraries, | 238 Future<MirrorSystem> _analyzeLibraries(List<String> libraries, |
| 200 String libraryRoot, {String packageRoot}) { | 239 String libraryRoot, {String packageRoot}) { |
| 201 SourceFileProvider provider = new CompilerSourceFileProvider(); | 240 SourceFileProvider provider = new CompilerSourceFileProvider(); |
| 202 api.DiagnosticHandler diagnosticHandler = | 241 api.DiagnosticHandler diagnosticHandler = |
| 203 new FormattingDiagnosticHandler(provider).diagnosticHandler; | 242 (new FormattingDiagnosticHandler(provider) |
| 243 ..showHints = false | |
| 244 ..showWarnings = false) | |
| 245 .diagnosticHandler; | |
| 204 Uri libraryUri = new Uri(scheme: 'file', path: appendSlash(libraryRoot)); | 246 Uri libraryUri = new Uri(scheme: 'file', path: appendSlash(libraryRoot)); |
| 205 Uri packageUri = null; | 247 Uri packageUri = null; |
| 206 if (packageRoot != null) { | 248 if (packageRoot != null) { |
| 207 packageUri = new Uri(scheme: 'file', path: appendSlash(packageRoot)); | 249 packageUri = new Uri(scheme: 'file', path: appendSlash(packageRoot)); |
| 208 } | 250 } |
| 209 List<Uri> librariesUri = <Uri>[]; | 251 List<Uri> librariesUri = <Uri>[]; |
| 210 libraries.forEach((library) { | 252 libraries.forEach((library) { |
| 211 librariesUri.add(currentDirectory.resolve(library)); | 253 librariesUri.add(currentDirectory.resolve(library)); |
| 212 }); | 254 }); |
| 213 return dart2js.analyze(librariesUri, libraryUri, packageUri, | 255 return dart2js.analyze(librariesUri, libraryUri, packageUri, |
| 214 provider.readStringFromUri, diagnosticHandler, | 256 provider.readStringFromUri, diagnosticHandler, |
| 215 ['--preserve-comments', '--categories=Client,Server']) | 257 ['--preserve-comments', '--categories=Client,Server']) |
| 216 ..catchError((error) { | 258 ..catchError((error) { |
| 217 logger.severe('Error: Failed to create mirror system. '); | 259 logger.severe('Error: Failed to create mirror system. '); |
| 218 // TODO(janicejl): Use the stack trace package when bug is resolved. | 260 // TODO(janicejl): Use the stack trace package when bug is resolved. |
| 219 // Currently, a string is thrown when it fails to create a mirror | 261 // Currently, a string is thrown when it fails to create a mirror |
| 220 // system, and it is not possible to use the stack trace. BUG(#11622) | 262 // system, and it is not possible to use the stack trace. BUG(#11622) |
| 221 // To avoid printing the stack trace. | 263 // To avoid printing the stack trace. |
| 222 exit(1); | 264 exit(1); |
| 223 }); | 265 }); |
| 224 } | 266 } |
| 225 | 267 |
| 226 /** | 268 /** |
| 227 * Creates documentation for filtered libraries. | 269 * Creates documentation for filtered libraries. |
| 228 */ | 270 */ |
| 229 void _documentLibraries(List<LibraryMirror> libs, {bool includeSdk: false, | 271 void _documentLibraries(List<LibraryMirror> libs, {bool includeSdk: false, |
| 230 bool outputToYaml: true, bool append: false, bool parseSdk: false, | 272 bool outputToYaml: true, bool append: false, bool parseSdk: false, |
| 231 String introduction: ''}) { | 273 String introduction: ''}) { |
| 232 libs.forEach((lib) { | 274 libs.forEach((lib) { |
| 233 // Files belonging to the SDK have a uri that begins with 'dart:'. | 275 // Files belonging to the SDK have a uri that begins with 'dart:'. |
| 234 if (includeSdk || !lib.uri.toString().startsWith('dart:')) { | 276 if (includeSdk || !lib.uri.toString().startsWith('dart:')) { |
| 235 var library = generateLibrary(lib); | 277 var library = generateLibrary(lib); |
| 236 entityMap[library.qualifiedName] = library; | 278 entityMap[library.qualifiedName] = library; |
| 237 } | 279 } |
| 238 }); | 280 }); |
| 239 // After everything is created, do a pass through all classes to make sure no | 281 // After everything is created, do a pass through all classes to make sure no |
| 240 // intermediate classes created by mixins are included. | 282 // intermediate classes created by mixins are included. |
| 241 entityMap.values.where((e) => e is Class).forEach((c) => c.makeValid()); | 283 entityMap.values.where((e) => e is Class).forEach((c) => c.makeValid()); |
| 242 // Everything is a subclass of Object, therefore empty the list to avoid a | 284 // Everything is a subclass of Object, therefore empty the list to avoid a |
| 243 // giant list of subclasses to be printed out. | 285 // giant list of subclasses to be printed out. |
| 244 if (parseSdk) entityMap['dart.core.Object'].subclasses.clear(); | 286 if (parseSdk) entityMap['dart.core.Object'].subclasses.clear(); |
| 245 | 287 |
| 246 var filteredEntities = entityMap.values.where(_isVisible); | 288 var filteredEntities = entityMap.values.where(_isVisible); |
| 247 | 289 |
| 248 // Outputs a JSON file with all libraries and their preview comments. | 290 // Outputs a JSON file with all libraries and their preview comments. |
| 249 // This will help the viewer know what libraries are available to read in. | 291 // This will help the viewer know what libraries are available to read in. |
| 250 var libraryMap; | 292 var libraryMap; |
| 251 if (append) { | 293 if (append) { |
| 252 var docsDir = listDir('docs'); | 294 var docsDir = listDir('docs'); |
| 253 if (!docsDir.contains('docs/library_list.json')) { | 295 if (!docsDir.contains('docs/library_list.json')) { |
| 254 throw new StateError('No library_list.json'); | 296 throw new StateError('No library_list.json'); |
| 255 } | 297 } |
| 256 libraryMap = | 298 libraryMap = |
| 257 JSON.decode(new File('docs/library_list.json').readAsStringSync()); | 299 JSON.decode(new File('docs/library_list.json').readAsStringSync()); |
| 258 libraryMap['libraries'].addAll(filteredEntities | 300 libraryMap['libraries'].addAll(filteredEntities |
| 259 .where((e) => e is Library) | 301 .where((e) => e is Library) |
| 260 .map((e) => e.previewMap)); | 302 .map((e) => e.previewMap)); |
| 261 if (introduction.isNotEmpty) { | 303 if (introduction.isNotEmpty) { |
| 262 var intro = libraryMap['introduction']; | 304 var intro = libraryMap['introduction']; |
| 263 if (intro.isNotEmpty) intro += '<br/><br/>'; | 305 if (intro.isNotEmpty) intro += '<br/><br/>'; |
| 264 intro += markdown.markdownToHtml( | 306 intro += markdown.markdownToHtml( |
| 265 new File(introduction).readAsStringSync(), | 307 new File(introduction).readAsStringSync(), |
| 266 linkResolver: linkResolver, inlineSyntaxes: markdownSyntaxes); | 308 linkResolver: linkResolver, inlineSyntaxes: markdownSyntaxes); |
| 267 libraryMap['introduction'] = intro; | 309 libraryMap['introduction'] = intro; |
| 268 } | 310 } |
| 269 outputToYaml = libraryMap['filetype'] == 'yaml'; | 311 outputToYaml = libraryMap['filetype'] == 'yaml'; |
| 270 } else { | 312 } else { |
| 271 libraryMap = { | 313 libraryMap = { |
| 272 'libraries' : filteredEntities.where((e) => | 314 'libraries' : filteredEntities.where((e) => |
| 273 e is Library).map((e) => e.previewMap).toList(), | 315 e is Library).map((e) => e.previewMap).toList(), |
| 274 'introduction' : introduction == '' ? | 316 'introduction' : introduction == '' ? |
| 275 '' : markdown.markdownToHtml(new File(introduction) | 317 '' : markdown.markdownToHtml(new File(introduction) |
| 276 .readAsStringSync(), linkResolver: linkResolver, | 318 .readAsStringSync(), linkResolver: linkResolver, |
| 277 inlineSyntaxes: markdownSyntaxes), | 319 inlineSyntaxes: markdownSyntaxes), |
| 278 'filetype' : outputToYaml ? 'yaml' : 'json' | 320 'filetype' : outputToYaml ? 'yaml' : 'json' |
| 279 }; | 321 }; |
| 280 } | 322 } |
| 281 _writeToFile(JSON.encode(libraryMap), 'library_list.json'); | 323 _writeToFile(JSON.encode(libraryMap), 'library_list.json'); |
| 282 // Output libraries and classes to file after all information is generated. | 324 // Output libraries and classes to file after all information is generated. |
| 283 filteredEntities.where((e) => e is Class || e is Library).forEach((output) { | 325 filteredEntities.where((e) => e is Class || e is Library).forEach((output) { |
| 284 _writeIndexableToFile(output, outputToYaml); | 326 _writeIndexableToFile(output, outputToYaml); |
| 285 }); | 327 }); |
| 286 // Outputs all the qualified names documented with their type. | 328 // Outputs all the qualified names documented with their type. |
| 287 // This will help generate search results. | 329 // This will help generate search results. |
| 288 _writeToFile(filteredEntities.map((e) => | 330 _writeToFile(filteredEntities.map((e) => |
| 289 '${e.qualifiedName} ${e.typeName}').join('\n'), | 331 '${e.qualifiedName} ${e.typeName}').join('\n') + '\n', |
| 290 'index.txt', append: append); | 332 'index.txt', append: append); |
| 333 var index = new Map.fromIterables( | |
| 334 filteredEntities.map((e) => e.qualifiedName), | |
| 335 filteredEntities.map((e) => e.typeName)); | |
|
terry
2013/10/24 14:17:30
Minor point, I'm sure it's not a perf issue now, b
| |
| 336 if (append) { | |
| 337 var previousIndex = | |
| 338 JSON.decode(new File('docs/index.json').readAsStringSync()); | |
| 339 index.addAll(previousIndex); | |
| 340 } | |
| 341 _writeToFile(JSON.encode(index), 'index.json'); | |
| 291 } | 342 } |
| 292 | 343 |
| 293 Library generateLibrary(dart2js.Dart2JsLibraryMirror library) { | 344 Library generateLibrary(dart2js.Dart2JsLibraryMirror library) { |
| 294 _currentLibrary = library; | 345 _currentLibrary = library; |
| 295 var result = new Library(library.qualifiedName, _commentToHtml(library), | 346 var result = new Library(library.qualifiedName, _commentToHtml(library), |
| 296 _variables(library.variables), | 347 _variables(library.variables), |
| 297 _methods(library.functions), | 348 _methods(library.functions), |
| 298 _classes(library.classes), _isHidden(library)); | 349 _classes(library.classes), _isHidden(library)); |
| 350 _findPackage(result, library); | |
| 299 logger.fine('Generated library for ${result.name}'); | 351 logger.fine('Generated library for ${result.name}'); |
| 300 return result; | 352 return result; |
| 301 } | 353 } |
| 302 | 354 |
| 303 void _writeIndexableToFile(Indexable result, bool outputToYaml) { | 355 void _writeIndexableToFile(Indexable result, bool outputToYaml) { |
| 304 if (outputToYaml) { | 356 if (outputToYaml) { |
| 305 _writeToFile(getYamlString(result.toMap()), '${result.qualifiedName}.yaml'); | 357 _writeToFile(getYamlString(result.toMap()), '${result.qualifiedName}.yaml'); |
| 306 } else { | 358 } else { |
| 307 _writeToFile(JSON.encode(result.toMap()), '${result.qualifiedName}.json'); | 359 _writeToFile(JSON.encode(result.toMap()), '${result.qualifiedName}.json'); |
| 308 } | 360 } |
| 309 } | 361 } |
| 310 | 362 |
| 311 /** | 363 /** |
| 312 * Returns true if a library name starts with an underscore, and false | 364 * Returns true if a library name starts with an underscore, and false |
| 313 * otherwise. | 365 * otherwise. |
| 314 * | 366 * |
| 315 * An example that starts with _ is _js_helper. | 367 * An example that starts with _ is _js_helper. |
| 316 * An example that contains ._ is dart._collection.dev | 368 * An example that contains ._ is dart._collection.dev |
| 317 */ | 369 */ |
| 318 // This is because LibraryMirror.isPrivate returns `false` all the time. | 370 // This is because LibraryMirror.isPrivate returns `false` all the time. |
| 319 bool _isLibraryPrivate(LibraryMirror mirror) { | 371 bool _isLibraryPrivate(LibraryMirror mirror) { |
| 320 var sdkLibrary = LIBRARIES[mirror.simpleName]; | 372 var sdkLibrary = LIBRARIES[mirror.simpleName]; |
| 321 if (sdkLibrary != null) { | 373 if (sdkLibrary != null) { |
| 322 return !sdkLibrary.documented; | 374 return !sdkLibrary.documented; |
| 323 } else if (mirror.simpleName.startsWith('_') || | 375 } else if (mirror.simpleName.startsWith('_') || |
| 324 mirror.simpleName.contains('._')) { | 376 mirror.simpleName.contains('._')) { |
| 325 return true; | 377 return true; |
| 326 } | 378 } |
| 327 return false; | 379 return false; |
| 328 } | 380 } |
| 329 | 381 |
| 330 /** | 382 /** |
| 331 * A declaration is private if itself is private, or the owner is private. | 383 * A declaration is private if itself is private, or the owner is private. |
| 332 */ | 384 */ |
| 333 // Issue(12202) - A declaration is public even if it's owner is private. | 385 // Issue(12202) - A declaration is public even if it's owner is private. |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 385 } | 437 } |
| 386 }); | 438 }); |
| 387 | 439 |
| 388 commentText = commentText == null ? '' : | 440 commentText = commentText == null ? '' : |
| 389 markdown.markdownToHtml(commentText.trim(), linkResolver: linkResolver, | 441 markdown.markdownToHtml(commentText.trim(), linkResolver: linkResolver, |
| 390 inlineSyntaxes: markdownSyntaxes); | 442 inlineSyntaxes: markdownSyntaxes); |
| 391 return commentText; | 443 return commentText; |
| 392 } | 444 } |
| 393 | 445 |
| 394 /** | 446 /** |
| 395 * Generates MDN comments from database.json. | 447 * Generates MDN comments from database.json. |
| 396 */ | 448 */ |
| 397 void _mdnComment(Indexable item) { | 449 void _mdnComment(Indexable item) { |
| 398 //Check if MDN is loaded. | 450 //Check if MDN is loaded. |
| 399 if (_mdn == null) { | 451 if (_mdn == null) { |
| 400 // Reading in MDN related json file. | 452 // Reading in MDN related json file. |
| 401 var mdnDir = path.join(path.dirname(path.dirname(path.dirname(path.dirname( | 453 var mdnDir = path.join(path.dirname(path.dirname(path.dirname(path.dirname( |
| 402 path.absolute(new Options().script))))), 'utils', 'apidoc', 'mdn'); | 454 path.absolute(new Options().script))))), 'utils', 'apidoc', 'mdn'); |
| 403 _mdn = JSON.decode(new File(path.join(mdnDir, 'database.json')) | 455 _mdn = JSON.decode(new File(path.join(mdnDir, 'database.json')) |
| 404 .readAsStringSync()); | 456 .readAsStringSync()); |
| 405 } | 457 } |
| 406 if (item.comment.isNotEmpty) return; | 458 if (item.comment.isNotEmpty) return; |
| 407 var domAnnotation = item.annotations.firstWhere( | 459 var domAnnotation = item.annotations.firstWhere( |
| 408 (e) => e.qualifiedName == 'metadata.DomName', orElse: () => null); | 460 (e) => e.qualifiedName == 'metadata.DomName', orElse: () => null); |
| 409 if (domAnnotation == null) return; | 461 if (domAnnotation == null) return; |
| 410 var domName = domAnnotation.parameters.single; | 462 var domName = domAnnotation.parameters.single; |
| 411 var parts = domName.split('.'); | 463 var parts = domName.split('.'); |
| 412 if (parts.length == 2) item.comment = _mdnMemberComment(parts[0], parts[1]); | 464 if (parts.length == 2) item.comment = _mdnMemberComment(parts[0], parts[1]); |
| 413 if (parts.length == 1) item.comment = _mdnTypeComment(parts[0]); | 465 if (parts.length == 1) item.comment = _mdnTypeComment(parts[0]); |
| 414 } | 466 } |
| 415 | 467 |
| 416 /** | 468 /** |
| 417 * Generates the MDN Comment for variables and method DOM elements. | 469 * Generates the MDN Comment for variables and method DOM elements. |
| 418 */ | 470 */ |
| 419 String _mdnMemberComment(String type, String member) { | 471 String _mdnMemberComment(String type, String member) { |
| 420 var mdnType = _mdn[type]; | 472 var mdnType = _mdn[type]; |
| 421 if (mdnType == null) return ''; | 473 if (mdnType == null) return ''; |
| 422 var mdnMember = mdnType['members'].firstWhere((e) => e['name'] == member, | 474 var mdnMember = mdnType['members'].firstWhere((e) => e['name'] == member, |
| 423 orElse: () => null); | 475 orElse: () => null); |
| 424 if (mdnMember == null) return ''; | 476 if (mdnMember == null) return ''; |
| 425 if (mdnMember['help'] == null || mdnMember['help'] == '') return ''; | 477 if (mdnMember['help'] == null || mdnMember['help'] == '') return ''; |
| 426 if (mdnMember['url'] == null) return ''; | 478 if (mdnMember['url'] == null) return ''; |
| 427 return _htmlMdn(mdnMember['help'], mdnMember['url']); | 479 return _htmlMdn(mdnMember['help'], mdnMember['url']); |
| 428 } | 480 } |
| 429 | 481 |
| 430 /** | 482 /** |
| 431 * Generates the MDN Comment for class DOM elements. | 483 * Generates the MDN Comment for class DOM elements. |
| 432 */ | 484 */ |
| 433 String _mdnTypeComment(String type) { | 485 String _mdnTypeComment(String type) { |
| 434 var mdnType = _mdn[type]; | 486 var mdnType = _mdn[type]; |
| 435 if (mdnType == null) return ''; | 487 if (mdnType == null) return ''; |
| 436 if (mdnType['summary'] == null || mdnType['summary'] == "") return ''; | 488 if (mdnType['summary'] == null || mdnType['summary'] == "") return ''; |
| 437 if (mdnType['srcUrl'] == null) return ''; | 489 if (mdnType['srcUrl'] == null) return ''; |
| 438 return _htmlMdn(mdnType['summary'], mdnType['srcUrl']); | 490 return _htmlMdn(mdnType['summary'], mdnType['srcUrl']); |
| 439 } | 491 } |
| 440 | 492 |
| 441 String _htmlMdn(String content, String url) { | 493 String _htmlMdn(String content, String url) { |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 620 | 672 |
| 621 /// Documentation comment with converted markdown. | 673 /// Documentation comment with converted markdown. |
| 622 String comment; | 674 String comment; |
| 623 | 675 |
| 624 /// Qualified Name of the owner of this Indexable Item. | 676 /// Qualified Name of the owner of this Indexable Item. |
| 625 /// For Library, owner will be ""; | 677 /// For Library, owner will be ""; |
| 626 String owner; | 678 String owner; |
| 627 | 679 |
| 628 Indexable(this.name, this.comment, this.qualifiedName, this.isPrivate, | 680 Indexable(this.name, this.comment, this.qualifiedName, this.isPrivate, |
| 629 this.owner); | 681 this.owner); |
| 630 | 682 |
| 631 /// The type of this member to be used in index.txt. | 683 /// The type of this member to be used in index.txt. |
| 632 String get typeName => ''; | 684 String get typeName => ''; |
| 633 | 685 |
| 634 /** | 686 /** |
| 635 * Creates a [Map] with this [Indexable]'s name and a preview comment. | 687 * Creates a [Map] with this [Indexable]'s name and a preview comment. |
| 636 */ | 688 */ |
| 637 Map get previewMap { | 689 Map get previewMap { |
| 638 var finalMap = { 'name' : qualifiedName }; | 690 var finalMap = { 'name' : qualifiedName }; |
| 639 if (comment != '') { | 691 if (comment != '') { |
| 640 var index = comment.indexOf('</p>'); | 692 var index = comment.indexOf('</p>'); |
| 641 finalMap['preview'] = '${comment.substring(0, index)}</p>'; | 693 finalMap['preview'] = '${comment.substring(0, index)}</p>'; |
| 642 } | 694 } |
| 643 return finalMap; | 695 return finalMap; |
| 644 } | 696 } |
| 645 } | 697 } |
| 646 | 698 |
| 647 /** | 699 /** |
| 648 * A class containing contents of a Dart library. | 700 * A class containing contents of a Dart library. |
| 649 */ | 701 */ |
| 650 class Library extends Indexable { | 702 class Library extends Indexable { |
| 651 | 703 |
| 652 /// Top-level variables in the library. | 704 /// Top-level variables in the library. |
| 653 Map<String, Variable> variables; | 705 Map<String, Variable> variables; |
| 654 | 706 |
| 655 /// Top-level functions in the library. | 707 /// Top-level functions in the library. |
| 656 MethodGroup functions; | 708 MethodGroup functions; |
| 657 | 709 |
| 658 /// Classes defined within the library | 710 /// Classes defined within the library |
| 659 ClassGroup classes; | 711 ClassGroup classes; |
| 660 | 712 |
| 713 String packageName = ''; | |
| 714 | |
| 715 Map get previewMap => super.previewMap..['packageName'] = packageName; | |
| 716 | |
| 661 Library(String name, String comment, this.variables, | 717 Library(String name, String comment, this.variables, |
| 662 this.functions, this.classes, bool isPrivate) : super(name, comment, | 718 this.functions, this.classes, bool isPrivate) : super(name, comment, |
| 663 name, isPrivate, "") {} | 719 name, isPrivate, "") {} |
| 664 | 720 |
| 665 /// Generates a map describing the [Library] object. | 721 /// Generates a map describing the [Library] object. |
| 666 Map toMap() => { | 722 Map toMap() => { |
| 667 'name': name, | 723 'name': name, |
| 668 'qualifiedName': qualifiedName, | 724 'qualifiedName': qualifiedName, |
| 669 'comment': comment, | 725 'comment': comment, |
| 670 'variables': recurseMap(variables), | 726 'variables': recurseMap(variables), |
| 671 'functions': functions.toMap(), | 727 'functions': functions.toMap(), |
| 672 'classes': classes.toMap() | 728 'classes': classes.toMap(), |
| 729 'packageName': packageName, | |
| 673 }; | 730 }; |
| 674 | 731 |
| 675 String get typeName => 'library'; | 732 String get typeName => 'library'; |
| 676 } | 733 } |
| 677 | 734 |
| 678 /** | 735 /** |
| 679 * A class containing contents of a Dart class. | 736 * A class containing contents of a Dart class. |
| 680 */ | 737 */ |
| 681 class Class extends Indexable { | 738 class Class extends Indexable { |
| 682 | 739 |
| 683 /// List of the names of interfaces that this class implements. | 740 /// List of the names of interfaces that this class implements. |
| 684 List<Class> interfaces = []; | 741 List<Class> interfaces = []; |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 702 Map<String, Generic> generics; | 759 Map<String, Generic> generics; |
| 703 | 760 |
| 704 Class superclass; | 761 Class superclass; |
| 705 bool isAbstract; | 762 bool isAbstract; |
| 706 | 763 |
| 707 /// List of the meta annotations on the class. | 764 /// List of the meta annotations on the class. |
| 708 List<Annotation> annotations; | 765 List<Annotation> annotations; |
| 709 | 766 |
| 710 Class(String name, this.superclass, String comment, this.interfaces, | 767 Class(String name, this.superclass, String comment, this.interfaces, |
| 711 this.variables, this.methods, this.annotations, this.generics, | 768 this.variables, this.methods, this.annotations, this.generics, |
| 712 String qualifiedName, bool isPrivate, String owner, this.isAbstract) | 769 String qualifiedName, bool isPrivate, String owner, this.isAbstract) |
| 713 : super(name, comment, qualifiedName, isPrivate, owner) { | 770 : super(name, comment, qualifiedName, isPrivate, owner) { |
| 714 _mdnComment(this); | 771 _mdnComment(this); |
| 715 } | 772 } |
| 716 | 773 |
| 717 String get typeName => 'class'; | 774 String get typeName => 'class'; |
| 718 | 775 |
| 719 /** | 776 /** |
| 720 * Returns a list of all the parent classes. | 777 * Returns a list of all the parent classes. |
| 721 */ | 778 */ |
| 722 List<Class> parent() { | 779 List<Class> parent() { |
| 723 var parent = superclass == null ? [] : [superclass]; | 780 var parent = superclass == null ? [] : [superclass]; |
| 724 parent.addAll(interfaces); | 781 parent.addAll(interfaces); |
| 725 return parent; | 782 return parent; |
| 726 } | 783 } |
| 727 | 784 |
| 728 /** | 785 /** |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 745 void addSubclass(Class subclass) { | 802 void addSubclass(Class subclass) { |
| 746 if (!_includePrivate && isPrivate) { | 803 if (!_includePrivate && isPrivate) { |
| 747 if (superclass != null) superclass.addSubclass(subclass); | 804 if (superclass != null) superclass.addSubclass(subclass); |
| 748 interfaces.forEach((interface) { | 805 interfaces.forEach((interface) { |
| 749 interface.addSubclass(subclass); | 806 interface.addSubclass(subclass); |
| 750 }); | 807 }); |
| 751 } else { | 808 } else { |
| 752 subclasses.add(subclass.qualifiedName); | 809 subclasses.add(subclass.qualifiedName); |
| 753 } | 810 } |
| 754 } | 811 } |
| 755 | 812 |
| 756 /** | 813 /** |
| 757 * Check if this [Class] is an error or exception. | 814 * Check if this [Class] is an error or exception. |
| 758 */ | 815 */ |
| 759 bool isError() { | 816 bool isError() { |
| 760 if (qualifiedName == 'dart.core.Error' || | 817 if (qualifiedName == 'dart.core.Error' || |
| 761 qualifiedName == 'dart.core.Exception') | 818 qualifiedName == 'dart.core.Exception') |
| 762 return true; | 819 return true; |
| 763 for (var interface in interfaces) { | 820 for (var interface in interfaces) { |
| 764 if (interface.isError()) return true; | 821 if (interface.isError()) return true; |
| 765 } | 822 } |
| 766 if (superclass == null) return false; | 823 if (superclass == null) return false; |
| 767 return superclass.isError(); | 824 return superclass.isError(); |
| 768 } | 825 } |
| 769 | 826 |
| 770 /** | 827 /** |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 840 if (_includePrivate || !mirror.isPrivate) { | 897 if (_includePrivate || !mirror.isPrivate) { |
| 841 entityMap[mirror.qualifiedName] = new Typedef(mirror.simpleName, | 898 entityMap[mirror.qualifiedName] = new Typedef(mirror.simpleName, |
| 842 mirror.value.returnType.qualifiedName, _commentToHtml(mirror), | 899 mirror.value.returnType.qualifiedName, _commentToHtml(mirror), |
| 843 _generics(mirror), _parameters(mirror.value.parameters), | 900 _generics(mirror), _parameters(mirror.value.parameters), |
| 844 _annotations(mirror), mirror.qualifiedName, _isHidden(mirror), | 901 _annotations(mirror), mirror.qualifiedName, _isHidden(mirror), |
| 845 mirror.owner.qualifiedName); | 902 mirror.owner.qualifiedName); |
| 846 typedefs[mirror.simpleName] = entityMap[mirror.qualifiedName]; | 903 typedefs[mirror.simpleName] = entityMap[mirror.qualifiedName]; |
| 847 } | 904 } |
| 848 } else { | 905 } else { |
| 849 var clazz = _class(mirror); | 906 var clazz = _class(mirror); |
| 850 | 907 |
| 851 // Adding inherited parent variables and methods. | 908 // Adding inherited parent variables and methods. |
| 852 clazz.parent().forEach((parent) { | 909 clazz.parent().forEach((parent) { |
| 853 if (_isVisible(clazz)) { | 910 if (_isVisible(clazz)) { |
| 854 parent.addSubclass(clazz); | 911 parent.addSubclass(clazz); |
| 855 } | 912 } |
| 856 }); | 913 }); |
| 857 | 914 |
| 858 clazz.ensureComments(); | 915 clazz.ensureComments(); |
| 859 | 916 |
| 860 if (clazz.isError()) { | 917 if (clazz.isError()) { |
| 861 errors[mirror.simpleName] = clazz; | 918 errors[mirror.simpleName] = clazz; |
| 862 } else if (mirror.isClass) { | 919 } else if (mirror.isClass) { |
| 863 classes[mirror.simpleName] = clazz; | 920 classes[mirror.simpleName] = clazz; |
| 864 } else { | 921 } else { |
| 865 throw new ArgumentError('${mirror.simpleName} - no class type match. '); | 922 throw new ArgumentError('${mirror.simpleName} - no class type match. '); |
| 866 } | 923 } |
| 867 } | 924 } |
| 868 } | 925 } |
| 869 | 926 |
| 870 /** | 927 /** |
| 871 * Checks if the given name is a key for any of the Class Maps. | 928 * Checks if the given name is a key for any of the Class Maps. |
| 872 */ | 929 */ |
| 873 bool containsKey(String name) { | 930 bool containsKey(String name) { |
| 874 return classes.containsKey(name) || errors.containsKey(name); | 931 return classes.containsKey(name) || errors.containsKey(name); |
| 875 } | 932 } |
| 876 | 933 |
| 877 Map toMap() => { | 934 Map toMap() => { |
| 878 'class': classes.values.where(_isVisible) | 935 'class': classes.values.where(_isVisible) |
| 879 .map((e) => e.previewMap).toList(), | 936 .map((e) => e.previewMap).toList(), |
| 880 'typedef': recurseMap(typedefs), | 937 'typedef': recurseMap(typedefs), |
| 881 'error': errors.values.where(_isVisible) | 938 'error': errors.values.where(_isVisible) |
| 882 .map((e) => e.previewMap).toList() | 939 .map((e) => e.previewMap).toList() |
| 883 }; | 940 }; |
| 884 } | 941 } |
| 885 | 942 |
| 886 class Typedef extends Indexable { | 943 class Typedef extends Indexable { |
| 887 String returnType; | 944 String returnType; |
| 888 | 945 |
| 889 Map<String, Parameter> parameters; | 946 Map<String, Parameter> parameters; |
| 890 | 947 |
| 891 /// Generic information about the typedef. | 948 /// Generic information about the typedef. |
| 892 Map<String, Generic> generics; | 949 Map<String, Generic> generics; |
| 893 | 950 |
| 894 /// List of the meta annotations on the typedef. | 951 /// List of the meta annotations on the typedef. |
| 895 List<Annotation> annotations; | 952 List<Annotation> annotations; |
| 896 | 953 |
| 897 Typedef(String name, this.returnType, String comment, this.generics, | 954 Typedef(String name, this.returnType, String comment, this.generics, |
| 898 this.parameters, this.annotations, | 955 this.parameters, this.annotations, |
| 899 String qualifiedName, bool isPrivate, String owner) | 956 String qualifiedName, bool isPrivate, String owner) |
| 900 : super(name, comment, qualifiedName, isPrivate, owner); | 957 : super(name, comment, qualifiedName, isPrivate, owner); |
| 901 | 958 |
| 902 Map toMap() => { | 959 Map toMap() => { |
| 903 'name': name, | 960 'name': name, |
| 904 'qualifiedName': qualifiedName, | 961 'qualifiedName': qualifiedName, |
| 905 'comment': comment, | 962 'comment': comment, |
| 906 'return': returnType, | 963 'return': returnType, |
| 907 'parameters': recurseMap(parameters), | 964 'parameters': recurseMap(parameters), |
| 908 'annotations': annotations.map((a) => a.toMap()).toList(), | 965 'annotations': annotations.map((a) => a.toMap()).toList(), |
| 909 'generics': recurseMap(generics) | 966 'generics': recurseMap(generics) |
| 910 }; | 967 }; |
| 911 | 968 |
| 912 String get typeName => 'typedef'; | 969 String get typeName => 'typedef'; |
| 913 } | 970 } |
| 914 | 971 |
| 915 /** | 972 /** |
| 916 * A class containing properties of a Dart variable. | 973 * A class containing properties of a Dart variable. |
| 917 */ | 974 */ |
| 918 class Variable extends Indexable { | 975 class Variable extends Indexable { |
| 919 | 976 |
| 920 bool isFinal; | 977 bool isFinal; |
| 921 bool isStatic; | 978 bool isStatic; |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 935 Map toMap() => { | 992 Map toMap() => { |
| 936 'name': name, | 993 'name': name, |
| 937 'qualifiedName': qualifiedName, | 994 'qualifiedName': qualifiedName, |
| 938 'comment': comment, | 995 'comment': comment, |
| 939 'final': isFinal.toString(), | 996 'final': isFinal.toString(), |
| 940 'static': isStatic.toString(), | 997 'static': isStatic.toString(), |
| 941 'constant': isConst.toString(), | 998 'constant': isConst.toString(), |
| 942 'type': new List.filled(1, type.toMap()), | 999 'type': new List.filled(1, type.toMap()), |
| 943 'annotations': annotations.map((a) => a.toMap()).toList() | 1000 'annotations': annotations.map((a) => a.toMap()).toList() |
| 944 }; | 1001 }; |
| 945 | 1002 |
| 946 String get typeName => 'property'; | 1003 String get typeName => 'property'; |
| 947 } | 1004 } |
| 948 | 1005 |
| 949 /** | 1006 /** |
| 950 * A class containing properties of a Dart method. | 1007 * A class containing properties of a Dart method. |
| 951 */ | 1008 */ |
| 952 class Method extends Indexable { | 1009 class Method extends Indexable { |
| 953 | 1010 |
| 954 /// Parameters for this method. | 1011 /// Parameters for this method. |
| 955 Map<String, Parameter> parameters; | 1012 Map<String, Parameter> parameters; |
| 956 | 1013 |
| 957 bool isStatic; | 1014 bool isStatic; |
| 958 bool isAbstract; | 1015 bool isAbstract; |
| 959 bool isConst; | 1016 bool isConst; |
| 960 bool isConstructor; | 1017 bool isConstructor; |
| 961 bool isGetter; | 1018 bool isGetter; |
| 962 bool isSetter; | 1019 bool isSetter; |
| 963 bool isOperator; | 1020 bool isOperator; |
| 964 Type returnType; | 1021 Type returnType; |
| 965 | 1022 |
| 966 /// Qualified name to state where the comment is inherited from. | 1023 /// Qualified name to state where the comment is inherited from. |
| 967 String commentInheritedFrom = ""; | 1024 String commentInheritedFrom = ""; |
| 968 | 1025 |
| 969 /// List of the meta annotations on the method. | 1026 /// List of the meta annotations on the method. |
| 970 List<Annotation> annotations; | 1027 List<Annotation> annotations; |
| 971 | 1028 |
| 972 Method(String name, this.isStatic, this.isAbstract, this.isConst, | 1029 Method(String name, this.isStatic, this.isAbstract, this.isConst, |
| 973 this.returnType, String comment, this.parameters, this.annotations, | 1030 this.returnType, String comment, this.parameters, this.annotations, |
| 974 String qualifiedName, bool isPrivate, String owner, this.isConstructor, | 1031 String qualifiedName, bool isPrivate, String owner, this.isConstructor, |
| 975 this.isGetter, this.isSetter, this.isOperator) | 1032 this.isGetter, this.isSetter, this.isOperator) |
| 976 : super(name, comment, qualifiedName, isPrivate, owner) { | 1033 : super(name, comment, qualifiedName, isPrivate, owner) { |
| 977 _mdnComment(this); | 1034 _mdnComment(this); |
| 978 } | 1035 } |
| 979 | 1036 |
| 980 /** | 1037 /** |
| 981 * Makes sure that the method with an inherited equivalent have comments. | 1038 * Makes sure that the method with an inherited equivalent have comments. |
| 982 */ | 1039 */ |
| 983 void ensureCommentFor(Method inheritedMethod) { | 1040 void ensureCommentFor(Method inheritedMethod) { |
| 984 if (comment.isNotEmpty) return; | 1041 if (comment.isNotEmpty) return; |
| 985 entityMap[inheritedMethod.owner].ensureComments(); | 1042 entityMap[inheritedMethod.owner].ensureComments(); |
| 986 comment = inheritedMethod.comment; | 1043 comment = inheritedMethod.comment; |
| 987 commentInheritedFrom = inheritedMethod.commentInheritedFrom == '' ? | 1044 commentInheritedFrom = inheritedMethod.commentInheritedFrom == '' ? |
| 988 inheritedMethod.qualifiedName : inheritedMethod.commentInheritedFrom; | 1045 inheritedMethod.qualifiedName : inheritedMethod.commentInheritedFrom; |
| 989 } | 1046 } |
| 990 | 1047 |
| 991 /// Generates a map describing the [Method] object. | 1048 /// Generates a map describing the [Method] object. |
| 992 Map toMap() => { | 1049 Map toMap() => { |
| 993 'name': name, | 1050 'name': name, |
| 994 'qualifiedName': qualifiedName, | 1051 'qualifiedName': qualifiedName, |
| 995 'comment': comment, | 1052 'comment': comment, |
| 996 'commentFrom': commentInheritedFrom, | 1053 'commentFrom': commentInheritedFrom, |
| 997 'static': isStatic.toString(), | 1054 'static': isStatic.toString(), |
| 998 'abstract': isAbstract.toString(), | 1055 'abstract': isAbstract.toString(), |
| 999 'constant': isConst.toString(), | 1056 'constant': isConst.toString(), |
| 1000 'return': new List.filled(1, returnType.toMap()), | 1057 'return': new List.filled(1, returnType.toMap()), |
| 1001 'parameters': recurseMap(parameters), | 1058 'parameters': recurseMap(parameters), |
| 1002 'annotations': annotations.map((a) => a.toMap()).toList() | 1059 'annotations': annotations.map((a) => a.toMap()).toList() |
| 1003 }; | 1060 }; |
| 1004 | 1061 |
| 1005 String get typeName => isConstructor ? 'constructor' : | 1062 String get typeName => isConstructor ? 'constructor' : |
| 1006 isGetter ? 'getter' : isSetter ? 'setter' : | 1063 isGetter ? 'getter' : isSetter ? 'setter' : |
| 1007 isOperator ? 'operator' : 'method'; | 1064 isOperator ? 'operator' : 'method'; |
| 1008 } | 1065 } |
| 1009 | 1066 |
| 1010 /** | 1067 /** |
| 1011 * A container to categorize methods into the following groups: setters, | 1068 * A container to categorize methods into the following groups: setters, |
| 1012 * getters, constructors, operators, regular methods. | 1069 * getters, constructors, operators, regular methods. |
| 1013 */ | 1070 */ |
| 1014 class MethodGroup { | 1071 class MethodGroup { |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1173 String qualifiedName; | 1230 String qualifiedName; |
| 1174 List<String> parameters; | 1231 List<String> parameters; |
| 1175 | 1232 |
| 1176 Annotation(this.qualifiedName, this.parameters); | 1233 Annotation(this.qualifiedName, this.parameters); |
| 1177 | 1234 |
| 1178 Map toMap() => { | 1235 Map toMap() => { |
| 1179 'name': qualifiedName, | 1236 'name': qualifiedName, |
| 1180 'parameters': parameters | 1237 'parameters': parameters |
| 1181 }; | 1238 }; |
| 1182 } | 1239 } |
| OLD | NEW |