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 /// **docgen** is a tool for creating machine readable representations of Dart |
|
Emily Fortuna
2013/11/01 22:34:46
there was a mixture of /// and /** throughout this
| |
| 6 * **docgen** is a tool for creating machine readable representations of Dart | 6 /// code metadata, including: classes, members, comments and annotations. |
| 7 * code metadata, including: classes, members, comments and annotations. | 7 /// |
| 8 * | 8 /// 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. | 9 /// |
| 10 * | 10 /// $ dart docgen.dart [OPTIONS] [FILE/DIR] |
| 11 * $ dart docgen.dart [OPTIONS] [FILE/DIR] | 11 /// |
| 12 * | 12 /// This creates files called `docs/<library_name>.yaml` in your current |
| 13 * This creates files called `docs/<library_name>.yaml` in your current | 13 /// working directory. |
| 14 * working directory. | |
| 15 */ | |
| 16 library docgen; | 14 library docgen; |
| 17 | 15 |
| 18 import 'dart:convert'; | 16 import 'dart:convert'; |
| 19 import 'dart:io'; | 17 import 'dart:io'; |
| 20 import 'dart:async'; | 18 import 'dart:async'; |
| 21 | 19 |
| 22 import 'package:logging/logging.dart'; | 20 import 'package:logging/logging.dart'; |
| 23 import 'package:markdown/markdown.dart' as markdown; | 21 import 'package:markdown/markdown.dart' as markdown; |
| 24 import 'package:path/path.dart' as path; | 22 import 'package:path/path.dart' as path; |
| 25 import 'package:yaml/yaml.dart'; | 23 import 'package:yaml/yaml.dart'; |
| 26 | 24 |
| 27 import 'dart2yaml.dart'; | 25 import 'dart2yaml.dart'; |
| 28 import 'src/io.dart'; | 26 import 'src/io.dart'; |
| 29 import '../../../sdk/lib/_internal/compiler/compiler.dart' as api; | 27 import '../../../sdk/lib/_internal/compiler/compiler.dart' as api; |
| 30 import '../../../sdk/lib/_internal/compiler/implementation/filenames.dart'; | 28 import '../../../sdk/lib/_internal/compiler/implementation/filenames.dart'; |
| 31 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirro r.dart' | 29 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirro r.dart' |
| 32 as dart2js; | 30 as dart2js; |
| 33 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors.dart' ; | 31 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors.dart' ; |
| 34 import '../../../sdk/lib/_internal/compiler/implementation/source_file_provider. dart'; | 32 import '../../../sdk/lib/_internal/compiler/implementation/source_file_provider. dart'; |
| 35 import '../../../sdk/lib/_internal/libraries.dart'; | 33 import '../../../sdk/lib/_internal/libraries.dart'; |
| 36 | 34 |
| 37 var logger = new Logger('Docgen'); | 35 var logger = new Logger('Docgen'); |
| 38 | 36 |
| 39 const String USAGE = 'Usage: dart docgen.dart [OPTIONS] [fooDir/barFile]'; | 37 const String USAGE = 'Usage: dart docgen.dart [OPTIONS] fooDir/barFile'; |
| 40 | 38 |
| 41 | 39 |
| 42 List<String> validAnnotations = const ['metadata.Experimental', | 40 List<String> skippedAnnotations = const [ |
| 43 'metadata.DomName', 'metadata.Deprecated', 'metadata.Unstable', | 41 'metadata.DocsEditable', 'metadata.DomName']; |
| 44 'meta.deprecated', 'metadata.SupportedBrowser']; | |
| 45 | 42 |
| 46 /// Current library being documented to be used for comment links. | 43 /// Current library being documented to be used for comment links. |
| 47 LibraryMirror _currentLibrary; | 44 LibraryMirror _currentLibrary; |
| 48 | 45 |
| 49 /// Current class being documented to be used for comment links. | 46 /// Current class being documented to be used for comment links. |
| 50 ClassMirror _currentClass; | 47 ClassMirror _currentClass; |
| 51 | 48 |
| 52 /// Current member being documented to be used for comment links. | 49 /// Current member being documented to be used for comment links. |
| 53 MemberMirror _currentMember; | 50 MemberMirror _currentMember; |
| 54 | 51 |
| 55 /// Support for [:foo:]-style code comments to the markdown parser. | 52 /// Support for [:foo:]-style code comments to the markdown parser. |
| 56 List<markdown.InlineSyntax> markdownSyntaxes = | 53 List<markdown.InlineSyntax> markdownSyntaxes = |
| 57 [new markdown.CodeSyntax(r'\[:\s?((?:.|\n)*?)\s?:\]')]; | 54 [new markdown.CodeSyntax(r'\[:\s?((?:.|\n)*?)\s?:\]')]; |
| 58 | 55 |
| 59 /// Resolves reference links in doc comments. | 56 /// Resolves reference links in doc comments. |
| 60 markdown.Resolver linkResolver; | 57 markdown.Resolver linkResolver; |
| 61 | 58 |
| 62 /// Index of all indexable items. This also ensures that no class is | 59 /// Index of all indexable items. This also ensures that no class is |
| 63 /// created more than once. | 60 /// created more than once. |
| 64 Map<String, Indexable> entityMap = new Map<String, Indexable>(); | 61 Map<String, Indexable> entityMap = new Map<String, Indexable>(); |
| 65 | 62 |
| 66 /// This is set from the command line arguments flag --include-private | 63 /// This is set from the command line arguments flag --include-private |
| 67 bool _includePrivate = false; | 64 bool _includePrivate = false; |
| 68 | 65 |
| 69 // TODO(janicejl): Make MDN content generic or pluggable. Maybe move | 66 // TODO(janicejl): Make MDN content generic or pluggable. Maybe move |
| 70 // MDN-specific code to its own library that is imported into the default impl? | 67 // MDN-specific code to its own library that is imported into the default impl? |
| 71 /// Map of all the comments for dom elements from MDN. | 68 /// Map of all the comments for dom elements from MDN. |
| 72 Map _mdn; | 69 Map _mdn; |
| 73 | 70 |
| 74 /** | 71 /// Docgen constructor initializes the link resolver for markdown parsing. |
| 75 * Docgen constructor initializes the link resolver for markdown parsing. | 72 /// Also initializes the command line arguments. |
| 76 * Also initializes the command line arguments. | 73 /// |
| 77 * | 74 /// [packageRoot] is the packages directory of the directory being analyzed. |
| 78 * [packageRoot] is the packages directory of the directory being analyzed. | 75 /// If [includeSdk] is `true`, then any SDK libraries explicitly imported will |
| 79 * If [includeSdk] is `true`, then any SDK libraries explicitly imported will | 76 /// also be documented. |
| 80 * also be documented. | 77 /// 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. | 78 /// This option is useful when only the SDK libraries are needed. |
| 82 * This option is useful when only the SDK libraries are needed. | 79 /// |
| 83 * | 80 /// Returned Future completes with true if document generation is successful. |
| 84 * Returns `true` if docgen sucessfuly completes. | |
| 85 */ | |
| 86 Future<bool> docgen(List<String> files, {String packageRoot, | 81 Future<bool> docgen(List<String> files, {String packageRoot, |
| 87 bool outputToYaml: true, bool includePrivate: false, bool includeSdk: false, | 82 bool outputToYaml: true, bool includePrivate: false, bool includeSdk: false, |
| 88 bool parseSdk: false, bool append: false, String introduction: ''}) { | 83 bool parseSdk: false, bool append: false, String introduction: ''}) { |
| 89 _includePrivate = includePrivate; | 84 _includePrivate = includePrivate; |
| 90 if (!append) { | 85 if (!append) { |
| 91 var dir = new Directory('docs'); | 86 var dir = new Directory('docs'); |
| 92 if (dir.existsSync()) dir.deleteSync(recursive: true); | 87 if (dir.existsSync()) dir.deleteSync(recursive: true); |
| 93 } | 88 } |
| 94 | 89 |
| 95 if (packageRoot == null && !parseSdk) { | 90 if (packageRoot == null && !parseSdk) { |
| 96 var type = FileSystemEntity.typeSync(files.first); | 91 var type = FileSystemEntity.typeSync(files.first); |
| 97 if (type == FileSystemEntityType.DIRECTORY) { | 92 if (type == FileSystemEntityType.DIRECTORY) { |
| 98 packageRoot = _findPackageRoot(files.first); | 93 packageRoot = _findPackageRoot(files.first); |
| 99 } else if (type == FileSystemEntityType.FILE) { | 94 } else if (type == FileSystemEntityType.FILE) { |
| 100 logger.warning('WARNING: No package root defined. If Docgen fails, try ' | 95 logger.warning('WARNING: No package root defined. If Docgen fails, try ' |
| 101 'again by setting the --package-root option.'); | 96 'again by setting the --package-root option.'); |
| 102 } | 97 } |
| 103 } | 98 } |
| 104 logger.info('Package Root: ${packageRoot}'); | 99 logger.info('Package Root: ${packageRoot}'); |
| 105 linkResolver = (name) => | 100 linkResolver = (name) => |
| 106 fixReference(name, _currentLibrary, _currentClass, _currentMember); | 101 fixReference(name, _currentLibrary, _currentClass, _currentMember); |
| 107 | 102 |
| 108 return getMirrorSystem(files, packageRoot: packageRoot, parseSdk: parseSdk) | 103 return getMirrorSystem(files, packageRoot: packageRoot, parseSdk: parseSdk) |
| 109 .then((MirrorSystem mirrorSystem) { | 104 .then((MirrorSystem mirrorSystem) { |
| 110 if (mirrorSystem.libraries.isEmpty) { | 105 if (mirrorSystem.libraries.isEmpty) { |
| 111 throw new StateError('No library mirrors were created.'); | 106 throw new StateError('No library mirrors were created.'); |
| 112 } | 107 } |
| 113 var librariesWeAskedFor = _listLibraries(files); | 108 var librariesWeAskedFor = _listLibraries(files); |
| 114 var librariesWeGot = mirrorSystem.libraries.values.where((each) | 109 var librariesWeGot = mirrorSystem.libraries.values.where( |
| 115 => each.uri.scheme == 'file'); | 110 (each) => each.uri.scheme == 'file'); |
| 116 var sdkLibraries = mirrorSystem.libraries.values.where( | 111 var sdkLibraries = mirrorSystem.libraries.values.where( |
| 117 (each) => each.uri.scheme == 'dart'); | 112 (each) => each.uri.scheme == 'dart'); |
| 118 var librariesWeGotByPath = new Map.fromIterables( | 113 var librariesWeGotByPath = new Map.fromIterables( |
| 119 librariesWeGot.map((each) => each.uri.toFilePath()), | 114 librariesWeGot.map((each) => each.uri.toFilePath()), |
| 120 librariesWeGot); | 115 librariesWeGot); |
| 121 var librariesToDocument = librariesWeAskedFor.map((each) => | 116 var librariesToDocument = librariesWeAskedFor.map( |
| 122 librariesWeGotByPath | 117 (each) => librariesWeGotByPath.putIfAbsent(each, |
| 123 .putIfAbsent(each, () => throw "Missing library $each")).toList(); | 118 () => throw "Missing library $each")).toList(); |
| 124 librariesToDocument.addAll((includeSdk || parseSdk) ? sdkLibraries : []); | 119 librariesToDocument.addAll((includeSdk || parseSdk) ? sdkLibraries : []); |
| 125 _documentLibraries(librariesToDocument, includeSdk: includeSdk, | 120 _documentLibraries(librariesToDocument, includeSdk: includeSdk, |
| 126 outputToYaml: outputToYaml, append: append, parseSdk: parseSdk, | 121 outputToYaml: outputToYaml, append: append, parseSdk: parseSdk, |
| 127 introduction: introduction); | 122 introduction: introduction); |
| 128 return true; | 123 return true; |
| 129 }); | 124 }); |
| 130 } | 125 } |
| 131 | 126 |
| 132 /// For a [library] and its corresponding [mirror] that we believe come | 127 /// For a [library] and its corresponding [mirror] that we believe come |
| 133 /// from a package (because it has a file | 128 /// from a package (because it has a file |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 211 var files = listDir(directory, recursive: true); | 206 var files = listDir(directory, recursive: true); |
| 212 // Return '' means that there was no pubspec.yaml and therefor no packageRoot. | 207 // Return '' means that there was no pubspec.yaml and therefor no packageRoot. |
| 213 String packageRoot = files.firstWhere((f) => | 208 String packageRoot = files.firstWhere((f) => |
| 214 f.endsWith('${path.separator}pubspec.yaml'), orElse: () => ''); | 209 f.endsWith('${path.separator}pubspec.yaml'), orElse: () => ''); |
| 215 if (packageRoot != '') { | 210 if (packageRoot != '') { |
| 216 packageRoot = path.join(path.dirname(packageRoot), 'packages'); | 211 packageRoot = path.join(path.dirname(packageRoot), 'packages'); |
| 217 } | 212 } |
| 218 return packageRoot; | 213 return packageRoot; |
| 219 } | 214 } |
| 220 | 215 |
| 221 /** | 216 /// Read a pubspec and return the library name. |
| 222 * Read a pubspec and return the library name. | |
| 223 */ | |
| 224 String _packageName(String pubspecName) { | 217 String _packageName(String pubspecName) { |
| 225 File pubspec = new File(pubspecName); | 218 File pubspec = new File(pubspecName); |
| 226 if (!pubspec.existsSync()) return ''; | 219 if (!pubspec.existsSync()) return ''; |
| 227 var contents = pubspec.readAsStringSync(); | 220 var contents = pubspec.readAsStringSync(); |
| 228 var spec = loadYaml(contents); | 221 var spec = loadYaml(contents); |
| 229 return spec["name"]; | 222 return spec["name"]; |
| 230 } | 223 } |
| 231 | 224 |
| 232 List<String> _listSdk() { | 225 List<String> _listSdk() { |
| 233 var sdk = new List<String>(); | 226 var sdk = new List<String>(); |
| 234 LIBRARIES.forEach((String name, LibraryInfo info) { | 227 LIBRARIES.forEach((String name, LibraryInfo info) { |
| 235 if (info.documented) { | 228 if (info.documented) { |
| 236 sdk.add('dart:$name'); | 229 sdk.add('dart:$name'); |
| 237 logger.info('Add to SDK: ${sdk.last}'); | 230 logger.info('Add to SDK: ${sdk.last}'); |
| 238 } | 231 } |
| 239 }); | 232 }); |
| 240 return sdk; | 233 return sdk; |
| 241 } | 234 } |
| 242 | 235 |
| 243 /** | 236 /// Analyzes set of libraries by getting a mirror system and triggers the |
| 244 * Analyzes set of libraries by getting a mirror system and triggers the | 237 /// documentation of the libraries. |
| 245 * documentation of the libraries. | |
| 246 */ | |
| 247 Future<MirrorSystem> getMirrorSystem(List<String> args, {String packageRoot, | 238 Future<MirrorSystem> getMirrorSystem(List<String> args, {String packageRoot, |
| 248 bool parseSdk: false}) { | 239 bool parseSdk: false}) { |
| 249 var libraries = !parseSdk ? _listLibraries(args) : _listSdk(); | 240 var libraries = !parseSdk ? _listLibraries(args) : _listSdk(); |
| 250 if (libraries.isEmpty) throw new StateError('No Libraries.'); | 241 if (libraries.isEmpty) throw new StateError('No Libraries.'); |
| 251 // Finds the root of SDK library based off the location of docgen. | 242 // Finds the root of SDK library based off the location of docgen. |
| 252 | 243 |
| 253 var root = findRootDirectory(); | 244 var root = findRootDirectory(); |
| 254 var sdkRoot = path.normalize(path.absolute(path.join(root, 'sdk'))); | 245 var sdkRoot = path.normalize(path.absolute(path.join(root, 'sdk'))); |
| 255 logger.info('SDK Root: ${sdkRoot}'); | 246 logger.info('SDK Root: ${sdkRoot}'); |
| 256 return _analyzeLibraries(libraries, sdkRoot, packageRoot: packageRoot); | 247 return _analyzeLibraries(libraries, sdkRoot, packageRoot: packageRoot); |
| 257 } | 248 } |
| 258 | 249 |
| 259 String findRootDirectory() { | 250 String findRootDirectory() { |
| 260 var scriptDir = path.absolute(path.dirname(Platform.script.toFilePath())); | 251 var scriptDir = path.absolute(path.dirname(Platform.script.toFilePath())); |
| 261 var root = scriptDir; | 252 var root = scriptDir; |
| 262 while(path.basename(root) != 'dart') { | 253 while(path.basename(root) != 'dart') { |
| 263 root = path.dirname(root); | 254 root = path.dirname(root); |
| 264 } | 255 } |
| 265 return root; | 256 return root; |
| 266 } | 257 } |
| 267 | 258 |
| 268 /** | 259 /// Analyzes set of libraries and provides a mirror system which can be used |
| 269 * Analyzes set of libraries and provides a mirror system which can be used | 260 /// for static inspection of the source code. |
| 270 * for static inspection of the source code. | |
| 271 */ | |
| 272 Future<MirrorSystem> _analyzeLibraries(List<String> libraries, | 261 Future<MirrorSystem> _analyzeLibraries(List<String> libraries, |
| 273 String libraryRoot, {String packageRoot}) { | 262 String libraryRoot, {String packageRoot}) { |
| 274 SourceFileProvider provider = new CompilerSourceFileProvider(); | 263 SourceFileProvider provider = new CompilerSourceFileProvider(); |
| 275 api.DiagnosticHandler diagnosticHandler = | 264 api.DiagnosticHandler diagnosticHandler = |
| 276 (new FormattingDiagnosticHandler(provider) | 265 (new FormattingDiagnosticHandler(provider) |
| 277 ..showHints = false | 266 ..showHints = false |
| 278 ..showWarnings = false) | 267 ..showWarnings = false) |
| 279 .diagnosticHandler; | 268 .diagnosticHandler; |
| 280 Uri libraryUri = new Uri(scheme: 'file', path: appendSlash(libraryRoot)); | 269 Uri libraryUri = new Uri(scheme: 'file', path: appendSlash(libraryRoot)); |
| 281 Uri packageUri = null; | 270 Uri packageUri = null; |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 292 ..catchError((error) { | 281 ..catchError((error) { |
| 293 logger.severe('Error: Failed to create mirror system. '); | 282 logger.severe('Error: Failed to create mirror system. '); |
| 294 // TODO(janicejl): Use the stack trace package when bug is resolved. | 283 // TODO(janicejl): Use the stack trace package when bug is resolved. |
| 295 // Currently, a string is thrown when it fails to create a mirror | 284 // Currently, a string is thrown when it fails to create a mirror |
| 296 // system, and it is not possible to use the stack trace. BUG(#11622) | 285 // system, and it is not possible to use the stack trace. BUG(#11622) |
| 297 // To avoid printing the stack trace. | 286 // To avoid printing the stack trace. |
| 298 exit(1); | 287 exit(1); |
| 299 }); | 288 }); |
| 300 } | 289 } |
| 301 | 290 |
| 302 /** | 291 /// Creates documentation for filtered libraries. |
| 303 * Creates documentation for filtered libraries. | |
| 304 */ | |
| 305 void _documentLibraries(List<LibraryMirror> libs, {bool includeSdk: false, | 292 void _documentLibraries(List<LibraryMirror> libs, {bool includeSdk: false, |
| 306 bool outputToYaml: true, bool append: false, bool parseSdk: false, | 293 bool outputToYaml: true, bool append: false, bool parseSdk: false, |
| 307 String introduction: ''}) { | 294 String introduction: ''}) { |
| 308 libs.forEach((lib) { | 295 libs.forEach((lib) { |
| 309 // Files belonging to the SDK have a uri that begins with 'dart:'. | 296 // Files belonging to the SDK have a uri that begins with 'dart:'. |
| 310 if (includeSdk || !lib.uri.toString().startsWith('dart:')) { | 297 if (includeSdk || !lib.uri.toString().startsWith('dart:')) { |
| 311 var library = generateLibrary(lib); | 298 var library = generateLibrary(lib); |
| 312 entityMap[library.name] = library; | 299 entityMap[library.name] = library; |
| 313 } | 300 } |
| 314 }); | 301 }); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 392 if (outputToYaml) { | 379 if (outputToYaml) { |
| 393 output = getYamlString(result.toMap()); | 380 output = getYamlString(result.toMap()); |
| 394 outputFile = outputFile + '.yaml'; | 381 outputFile = outputFile + '.yaml'; |
| 395 } else { | 382 } else { |
| 396 output = JSON.encode(result.toMap()); | 383 output = JSON.encode(result.toMap()); |
| 397 outputFile = outputFile + '.json'; | 384 outputFile = outputFile + '.json'; |
| 398 } | 385 } |
| 399 _writeToFile(output, outputFile); | 386 _writeToFile(output, outputFile); |
| 400 } | 387 } |
| 401 | 388 |
| 402 /** | 389 /// Returns true if a library name starts with an underscore, and false |
| 403 * Returns true if a library name starts with an underscore, and false | 390 /// otherwise. |
| 404 * otherwise. | 391 /// |
| 405 * | 392 /// An example that starts with _ is _js_helper. |
| 406 * An example that starts with _ is _js_helper. | 393 /// An example that contains ._ is dart._collection.dev |
| 407 * An example that contains ._ is dart._collection.dev | |
| 408 */ | |
| 409 // This is because LibraryMirror.isPrivate returns `false` all the time. | 394 // This is because LibraryMirror.isPrivate returns `false` all the time. |
| 410 bool _isLibraryPrivate(LibraryMirror mirror) { | 395 bool _isLibraryPrivate(LibraryMirror mirror) { |
| 411 var sdkLibrary = LIBRARIES[mirror.simpleName]; | 396 var sdkLibrary = LIBRARIES[mirror.simpleName]; |
| 412 if (sdkLibrary != null) { | 397 if (sdkLibrary != null) { |
| 413 return !sdkLibrary.documented; | 398 return !sdkLibrary.documented; |
| 414 } else if (mirror.simpleName.startsWith('_') || | 399 } else if (mirror.simpleName.startsWith('_') || |
| 415 mirror.simpleName.contains('._')) { | 400 mirror.simpleName.contains('._')) { |
| 416 return true; | 401 return true; |
| 417 } | 402 } |
| 418 return false; | 403 return false; |
| 419 } | 404 } |
| 420 | 405 |
| 421 /** | 406 /// A declaration is private if itself is private, or the owner is private. |
| 422 * A declaration is private if itself is private, or the owner is private. | |
| 423 */ | |
| 424 // Issue(12202) - A declaration is public even if it's owner is private. | 407 // Issue(12202) - A declaration is public even if it's owner is private. |
| 425 bool _isHidden(DeclarationMirror mirror) { | 408 bool _isHidden(DeclarationMirror mirror) { |
| 426 if (mirror is LibraryMirror) { | 409 if (mirror is LibraryMirror) { |
| 427 return _isLibraryPrivate(mirror); | 410 return _isLibraryPrivate(mirror); |
| 428 } else if (mirror.owner is LibraryMirror) { | 411 } else if (mirror.owner is LibraryMirror) { |
| 429 return (mirror.isPrivate || _isLibraryPrivate(mirror.owner)); | 412 return (mirror.isPrivate || _isLibraryPrivate(mirror.owner)); |
| 430 } else { | 413 } else { |
| 431 return (mirror.isPrivate || _isHidden(mirror.owner)); | 414 return (mirror.isPrivate || _isHidden(mirror.owner)); |
| 432 } | 415 } |
| 433 } | 416 } |
| 434 | 417 |
| 435 bool _isVisible(Indexable item) { | 418 bool _isVisible(Indexable item) { |
| 436 return _includePrivate || !item.isPrivate; | 419 return _includePrivate || !item.isPrivate; |
| 437 } | 420 } |
| 438 | 421 |
| 439 /** | 422 /// Returns a list of meta annotations assocated with a mirror. |
| 440 * Returns a list of meta annotations assocated with a mirror. | |
| 441 */ | |
| 442 List<Annotation> _annotations(DeclarationMirror mirror) { | 423 List<Annotation> _annotations(DeclarationMirror mirror) { |
| 443 var annotationMirrors = mirror.metadata.where((e) => | 424 var annotationMirrors = mirror.metadata.where((e) => |
| 444 e is dart2js.Dart2JsConstructedConstantMirror); | 425 e is dart2js.Dart2JsConstructedConstantMirror); |
| 445 var annotations = []; | 426 var annotations = []; |
| 446 annotationMirrors.forEach((annotation) { | 427 annotationMirrors.forEach((annotation) { |
| 447 var parameterList = annotation.type.variables.values | 428 var parameterList = annotation.type.variables.values |
| 448 .where((e) => e.isFinal) | 429 .where((e) => e.isFinal) |
| 449 .map((e) => annotation.getField(e.simpleName).reflectee) | 430 .map((e) => annotation.getField(e.simpleName).reflectee) |
| 450 .where((e) => e != null) | 431 .where((e) => e != null) |
| 451 .toList(); | 432 .toList(); |
| 452 if (validAnnotations.contains(docName(annotation.type))) { | 433 if (!skippedAnnotations.contains(docName(annotation.type))) { |
| 453 annotations.add(new Annotation(docName(annotation.type), | 434 annotations.add(new Annotation(docName(annotation.type), |
| 454 parameterList)); | 435 parameterList)); |
| 455 } | 436 } |
| 456 }); | 437 }); |
| 457 return annotations; | 438 return annotations; |
| 458 } | 439 } |
| 459 | 440 |
| 460 /** | 441 /// Returns any documentation comments associated with a mirror with |
| 461 * Returns any documentation comments associated with a mirror with | 442 /// simple markdown converted to html. |
| 462 * simple markdown converted to html. | |
| 463 */ | |
| 464 String _commentToHtml(DeclarationMirror mirror) { | 443 String _commentToHtml(DeclarationMirror mirror) { |
| 465 String commentText; | 444 String commentText; |
| 466 mirror.metadata.forEach((metadata) { | 445 mirror.metadata.forEach((metadata) { |
| 467 if (metadata is CommentInstanceMirror) { | 446 if (metadata is CommentInstanceMirror) { |
| 468 CommentInstanceMirror comment = metadata; | 447 CommentInstanceMirror comment = metadata; |
| 469 if (comment.isDocComment) { | 448 if (comment.isDocComment) { |
| 470 if (commentText == null) { | 449 if (commentText == null) { |
| 471 commentText = comment.trimmedText; | 450 commentText = comment.trimmedText; |
| 472 } else { | 451 } else { |
| 473 commentText = '$commentText ${comment.trimmedText}'; | 452 commentText = '$commentText ${comment.trimmedText}'; |
| 474 } | 453 } |
| 475 } | 454 } |
| 476 } | 455 } |
| 477 }); | 456 }); |
| 478 | 457 |
| 479 commentText = commentText == null ? '' : | 458 commentText = commentText == null ? '' : |
| 480 markdown.markdownToHtml(commentText.trim(), linkResolver: linkResolver, | 459 markdown.markdownToHtml(commentText.trim(), linkResolver: linkResolver, |
| 481 inlineSyntaxes: markdownSyntaxes); | 460 inlineSyntaxes: markdownSyntaxes); |
| 482 return commentText; | 461 return commentText; |
| 483 } | 462 } |
| 484 | 463 |
| 485 /** | 464 /// Generates MDN comments from database.json. |
| 486 * Generates MDN comments from database.json. | |
| 487 */ | |
| 488 void _mdnComment(Indexable item) { | 465 void _mdnComment(Indexable item) { |
| 489 //Check if MDN is loaded. | 466 //Check if MDN is loaded. |
| 490 if (_mdn == null) { | 467 if (_mdn == null) { |
| 491 // Reading in MDN related json file. | 468 // Reading in MDN related json file. |
| 492 var root = findRootDirectory(); | 469 var root = findRootDirectory(); |
| 493 var mdnPath = path.join(root, 'utils/apidoc/mdn/database.json'); | 470 var mdnPath = path.join(root, 'utils/apidoc/mdn/database.json'); |
| 494 _mdn = JSON.decode(new File(mdnPath).readAsStringSync()); | 471 _mdn = JSON.decode(new File(mdnPath).readAsStringSync()); |
| 495 } | 472 } |
| 496 if (item.comment.isNotEmpty) return; | 473 if (item.comment.isNotEmpty) return; |
| 497 var domAnnotation = item.annotations.firstWhere( | 474 var domAnnotation = item.annotations.firstWhere( |
| 498 (e) => e.qualifiedName == 'metadata.DomName', orElse: () => null); | 475 (e) => e.qualifiedName == 'metadata.DomName', orElse: () => null); |
| 499 if (domAnnotation == null) return; | 476 if (domAnnotation == null) return; |
| 500 var domName = domAnnotation.parameters.single; | 477 var domName = domAnnotation.parameters.single; |
| 501 var parts = domName.split('.'); | 478 var parts = domName.split('.'); |
| 502 if (parts.length == 2) item.comment = _mdnMemberComment(parts[0], parts[1]); | 479 if (parts.length == 2) item.comment = _mdnMemberComment(parts[0], parts[1]); |
| 503 if (parts.length == 1) item.comment = _mdnTypeComment(parts[0]); | 480 if (parts.length == 1) item.comment = _mdnTypeComment(parts[0]); |
| 504 } | 481 } |
| 505 | 482 |
| 506 /** | 483 /// Generates the MDN Comment for variables and method DOM elements. |
| 507 * Generates the MDN Comment for variables and method DOM elements. | |
| 508 */ | |
| 509 String _mdnMemberComment(String type, String member) { | 484 String _mdnMemberComment(String type, String member) { |
| 510 var mdnType = _mdn[type]; | 485 var mdnType = _mdn[type]; |
| 511 if (mdnType == null) return ''; | 486 if (mdnType == null) return ''; |
| 512 var mdnMember = mdnType['members'].firstWhere((e) => e['name'] == member, | 487 var mdnMember = mdnType['members'].firstWhere((e) => e['name'] == member, |
| 513 orElse: () => null); | 488 orElse: () => null); |
| 514 if (mdnMember == null) return ''; | 489 if (mdnMember == null) return ''; |
| 515 if (mdnMember['help'] == null || mdnMember['help'] == '') return ''; | 490 if (mdnMember['help'] == null || mdnMember['help'] == '') return ''; |
| 516 if (mdnMember['url'] == null) return ''; | 491 if (mdnMember['url'] == null) return ''; |
| 517 return _htmlMdn(mdnMember['help'], mdnMember['url']); | 492 return _htmlMdn(mdnMember['help'], mdnMember['url']); |
| 518 } | 493 } |
| 519 | 494 |
| 520 /** | 495 /// Generates the MDN Comment for class DOM elements. |
| 521 * Generates the MDN Comment for class DOM elements. | |
| 522 */ | |
| 523 String _mdnTypeComment(String type) { | 496 String _mdnTypeComment(String type) { |
| 524 var mdnType = _mdn[type]; | 497 var mdnType = _mdn[type]; |
| 525 if (mdnType == null) return ''; | 498 if (mdnType == null) return ''; |
| 526 if (mdnType['summary'] == null || mdnType['summary'] == "") return ''; | 499 if (mdnType['summary'] == null || mdnType['summary'] == "") return ''; |
| 527 if (mdnType['srcUrl'] == null) return ''; | 500 if (mdnType['srcUrl'] == null) return ''; |
| 528 return _htmlMdn(mdnType['summary'], mdnType['srcUrl']); | 501 return _htmlMdn(mdnType['summary'], mdnType['srcUrl']); |
| 529 } | 502 } |
| 530 | 503 |
| 531 String _htmlMdn(String content, String url) { | 504 String _htmlMdn(String content, String url) { |
| 532 return '<div class="mdn">' + content.trim() + '<p class="mdn-note">' | 505 return '<div class="mdn">' + content.trim() + '<p class="mdn-note">' |
| 533 '<a href="' + url.trim() + '">from Mdn</a></p></div>'; | 506 '<a href="' + url.trim() + '">from Mdn</a></p></div>'; |
| 534 } | 507 } |
| 535 | 508 |
| 536 /** | 509 /// Converts all [foo] references in comments to <a>libraryName.foo</a>. |
| 537 * Converts all [foo] references in comments to <a>libraryName.foo</a>. | |
| 538 */ | |
| 539 markdown.Node fixReference(String name, LibraryMirror currentLibrary, | 510 markdown.Node fixReference(String name, LibraryMirror currentLibrary, |
| 540 ClassMirror currentClass, MemberMirror currentMember) { | 511 ClassMirror currentClass, MemberMirror currentMember) { |
| 541 var reference; | 512 var reference; |
| 542 var memberScope = currentMember == null ? | 513 var memberScope = currentMember == null ? |
| 543 null : currentMember.lookupInScope(name); | 514 null : currentMember.lookupInScope(name); |
| 544 if (memberScope != null) { | 515 if (memberScope != null) { |
| 545 reference = docName(memberScope); | 516 reference = docName(memberScope); |
| 546 } else { | 517 } else { |
| 547 var classScope = currentClass == null ? | 518 var classScope = currentClass == null ? |
| 548 null : currentClass.lookupInScope(name); | 519 null : currentClass.lookupInScope(name); |
| 549 if (classScope != null) { | 520 if (classScope != null) { |
| 550 reference = docName(classScope); | 521 reference = docName(classScope); |
| 551 } else { | 522 } else { |
| 552 var libraryScope = currentLibrary == null ? | 523 var libraryScope = currentLibrary == null ? |
| 553 null : currentLibrary.lookupInScope(name); | 524 null : currentLibrary.lookupInScope(name); |
| 554 reference = libraryScope != null ? docName(libraryScope) : name; | 525 reference = libraryScope != null ? docName(libraryScope) : name; |
| 555 } | 526 } |
| 556 } | 527 } |
| 557 return new markdown.Element.text('a', reference); | 528 return new markdown.Element.text('a', reference); |
| 558 } | 529 } |
| 559 | 530 |
| 560 /** | 531 /// Returns a map of [Variable] objects constructed from [mirrorMap]. |
| 561 * Returns a map of [Variable] objects constructed from [mirrorMap]. | |
| 562 */ | |
| 563 Map<String, Variable> _variables(Map<String, VariableMirror> mirrorMap) { | 532 Map<String, Variable> _variables(Map<String, VariableMirror> mirrorMap) { |
| 564 var data = {}; | 533 var data = {}; |
| 565 // TODO(janicejl): When map to map feature is created, replace the below with | 534 // TODO(janicejl): When map to map feature is created, replace the below with |
| 566 // a filter. Issue(#9590). | 535 // a filter. Issue(#9590). |
| 567 mirrorMap.forEach((String mirrorName, VariableMirror mirror) { | 536 mirrorMap.forEach((String mirrorName, VariableMirror mirror) { |
| 568 _currentMember = mirror; | 537 _currentMember = mirror; |
| 569 if (_includePrivate || !_isHidden(mirror)) { | 538 if (_includePrivate || !_isHidden(mirror)) { |
| 570 entityMap[docName(mirror)] = new Variable(mirrorName, mirror.isFinal, | 539 entityMap[docName(mirror)] = new Variable(mirrorName, mirror.isFinal, |
| 571 mirror.isStatic, mirror.isConst, _type(mirror.type), | 540 mirror.isStatic, mirror.isConst, _type(mirror.type), |
| 572 _commentToHtml(mirror), _annotations(mirror), docName(mirror), | 541 _commentToHtml(mirror), _annotations(mirror), docName(mirror), |
| 573 _isHidden(mirror), docName(mirror.owner)); | 542 _isHidden(mirror), docName(mirror.owner)); |
| 574 data[mirrorName] = entityMap[docName(mirror)]; | 543 data[mirrorName] = entityMap[docName(mirror)]; |
| 575 } | 544 } |
| 576 }); | 545 }); |
| 577 return data; | 546 return data; |
| 578 } | 547 } |
| 579 | 548 |
| 580 /** | 549 /// Returns a map of [Method] objects constructed from [mirrorMap]. |
| 581 * Returns a map of [Method] objects constructed from [mirrorMap]. | |
| 582 */ | |
| 583 MethodGroup _methods(Map<String, MethodMirror> mirrorMap) { | 550 MethodGroup _methods(Map<String, MethodMirror> mirrorMap) { |
| 584 var group = new MethodGroup(); | 551 var group = new MethodGroup(); |
| 585 mirrorMap.forEach((String mirrorName, MethodMirror mirror) { | 552 mirrorMap.forEach((String mirrorName, MethodMirror mirror) { |
| 586 if (_includePrivate || !mirror.isPrivate) { | 553 if (_includePrivate || !mirror.isPrivate) { |
| 587 group.addMethod(mirror); | 554 group.addMethod(mirror); |
| 588 } | 555 } |
| 589 }); | 556 }); |
| 590 return group; | 557 return group; |
| 591 } | 558 } |
| 592 | 559 |
| 593 /** | 560 /// Returns the [Class] for the given [mirror] has already been created, and if |
| 594 * Returns the [Class] for the given [mirror] has already been created, and if | 561 /// it does not exist, creates it. |
| 595 * it does not exist, creates it. | |
| 596 */ | |
| 597 Class _class(ClassMirror mirror) { | 562 Class _class(ClassMirror mirror) { |
| 598 var clazz = entityMap[docName(mirror)]; | 563 var clazz = entityMap[docName(mirror)]; |
| 599 if (clazz == null) { | 564 if (clazz == null) { |
| 600 var superclass = mirror.superclass != null ? | 565 var superclass = mirror.superclass != null ? |
| 601 _class(mirror.superclass) : null; | 566 _class(mirror.superclass) : null; |
| 602 var interfaces = | 567 var interfaces = |
| 603 mirror.superinterfaces.map((interface) => _class(interface)); | 568 mirror.superinterfaces.map((interface) => _class(interface)); |
| 604 clazz = new Class(mirror.simpleName, superclass, _commentToHtml(mirror), | 569 clazz = new Class(mirror.simpleName, superclass, _commentToHtml(mirror), |
| 605 interfaces.toList(), _variables(mirror.variables), | 570 interfaces.toList(), _variables(mirror.variables), |
| 606 _methods(mirror.methods), _annotations(mirror), _generics(mirror), | 571 _methods(mirror.methods), _annotations(mirror), _generics(mirror), |
| 607 docName(mirror), _isHidden(mirror), docName(mirror.owner), | 572 docName(mirror), _isHidden(mirror), docName(mirror.owner), |
| 608 mirror.isAbstract); | 573 mirror.isAbstract); |
| 609 if (superclass != null) clazz.addInherited(superclass); | 574 if (superclass != null) clazz.addInherited(superclass); |
| 610 interfaces.forEach((interface) => clazz.addInherited(interface)); | 575 interfaces.forEach((interface) => clazz.addInherited(interface)); |
| 611 entityMap[docName(mirror)] = clazz; | 576 entityMap[docName(mirror)] = clazz; |
| 612 } | 577 } |
| 613 return clazz; | 578 return clazz; |
| 614 } | 579 } |
| 615 | 580 |
| 616 /** | 581 /// Returns a map of [Class] objects constructed from [mirrorMap]. |
| 617 * Returns a map of [Class] objects constructed from [mirrorMap]. | |
| 618 */ | |
| 619 ClassGroup _classes(Map<String, ClassMirror> mirrorMap) { | 582 ClassGroup _classes(Map<String, ClassMirror> mirrorMap) { |
| 620 var group = new ClassGroup(); | 583 var group = new ClassGroup(); |
| 621 mirrorMap.forEach((String mirrorName, ClassMirror mirror) { | 584 mirrorMap.forEach((String mirrorName, ClassMirror mirror) { |
| 622 group.addClass(mirror); | 585 group.addClass(mirror); |
| 623 }); | 586 }); |
| 624 return group; | 587 return group; |
| 625 } | 588 } |
| 626 | 589 |
| 627 /** | 590 /// Returns a map of [Parameter] objects constructed from [mirrorList]. |
| 628 * Returns a map of [Parameter] objects constructed from [mirrorList]. | |
| 629 */ | |
| 630 Map<String, Parameter> _parameters(List<ParameterMirror> mirrorList) { | 591 Map<String, Parameter> _parameters(List<ParameterMirror> mirrorList) { |
| 631 var data = {}; | 592 var data = {}; |
| 632 mirrorList.forEach((ParameterMirror mirror) { | 593 mirrorList.forEach((ParameterMirror mirror) { |
| 633 _currentMember = mirror; | 594 _currentMember = mirror; |
| 634 data[mirror.simpleName] = new Parameter(mirror.simpleName, | 595 data[mirror.simpleName] = new Parameter(mirror.simpleName, |
| 635 mirror.isOptional, mirror.isNamed, mirror.hasDefaultValue, | 596 mirror.isOptional, mirror.isNamed, mirror.hasDefaultValue, |
| 636 _type(mirror.type), mirror.defaultValue, | 597 _type(mirror.type), mirror.defaultValue, |
| 637 _annotations(mirror)); | 598 _annotations(mirror)); |
| 638 }); | 599 }); |
| 639 return data; | 600 return data; |
| 640 } | 601 } |
| 641 | 602 |
| 642 /** | 603 /// Returns a map of [Generic] objects constructed from the class mirror. |
| 643 * Returns a map of [Generic] objects constructed from the class mirror. | |
| 644 */ | |
| 645 Map<String, Generic> _generics(ClassMirror mirror) { | 604 Map<String, Generic> _generics(ClassMirror mirror) { |
| 646 return new Map.fromIterable(mirror.typeVariables, | 605 return new Map.fromIterable(mirror.typeVariables, |
| 647 key: (e) => e.toString(), | 606 key: (e) => e.toString(), |
| 648 value: (e) => new Generic(e.toString(), e.upperBound.qualifiedName)); | 607 value: (e) => new Generic(e.toString(), e.upperBound.qualifiedName)); |
| 649 } | 608 } |
| 650 | 609 |
| 651 /** | 610 /// Returns a single [Type] object constructed from the Method.returnType |
| 652 * Returns a single [Type] object constructed from the Method.returnType | 611 /// Type mirror. |
| 653 * Type mirror. | |
| 654 */ | |
| 655 Type _type(TypeMirror mirror) { | 612 Type _type(TypeMirror mirror) { |
| 656 return new Type(docName(mirror), _typeGenerics(mirror)); | 613 return new Type(docName(mirror), _typeGenerics(mirror)); |
| 657 } | 614 } |
| 658 | 615 |
| 659 /** | 616 /// Returns a list of [Type] objects constructed from TypeMirrors. |
| 660 * Returns a list of [Type] objects constructed from TypeMirrors. | |
| 661 */ | |
| 662 List<Type> _typeGenerics(TypeMirror mirror) { | 617 List<Type> _typeGenerics(TypeMirror mirror) { |
| 663 if (mirror is ClassMirror && !mirror.isTypedef) { | 618 if (mirror is ClassMirror && !mirror.isTypedef) { |
| 664 var innerList = []; | 619 var innerList = []; |
| 665 mirror.typeArguments.forEach((e) { | 620 mirror.typeArguments.forEach((e) { |
| 666 innerList.add(new Type(docName(e), _typeGenerics(e))); | 621 innerList.add(new Type(docName(e), _typeGenerics(e))); |
| 667 }); | 622 }); |
| 668 return innerList; | 623 return innerList; |
| 669 } | 624 } |
| 670 return []; | 625 return []; |
| 671 } | 626 } |
| 672 | 627 |
| 673 /** | 628 /// Writes text to a file in the 'docs' directory. |
| 674 * Writes text to a file in the 'docs' directory. | |
| 675 */ | |
| 676 void _writeToFile(String text, String filename, {bool append: false}) { | 629 void _writeToFile(String text, String filename, {bool append: false}) { |
| 677 Directory dir = new Directory('docs'); | 630 Directory dir = new Directory('docs'); |
| 678 if (!dir.existsSync()) { | 631 if (!dir.existsSync()) { |
| 679 dir.createSync(); | 632 dir.createSync(); |
| 680 } | 633 } |
| 681 // We assume there's a single extra level of directory structure for packages. | 634 // We assume there's a single extra level of directory structure for packages. |
| 682 if (path.split(filename).length > 1) { | 635 if (path.split(filename).length > 1) { |
| 683 var subdir = new Directory(path.join('docs', path.dirname(filename))); | 636 var subdir = new Directory(path.join('docs', path.dirname(filename))); |
| 684 if (!subdir.existsSync()) { | 637 if (!subdir.existsSync()) { |
| 685 subdir.createSync(); | 638 subdir.createSync(); |
| 686 } | 639 } |
| 687 } | 640 } |
| 688 | 641 |
| 689 File file = new File('docs/$filename'); | 642 File file = new File('docs/$filename'); |
| 690 if (!file.existsSync()) { | 643 if (!file.existsSync()) { |
| 691 file.createSync(); | 644 file.createSync(); |
| 692 } | 645 } |
| 693 file.writeAsStringSync(text, mode: append ? FileMode.APPEND : FileMode.WRITE); | 646 file.writeAsStringSync(text, mode: append ? FileMode.APPEND : FileMode.WRITE); |
| 694 } | 647 } |
| 695 | 648 |
| 696 /** | 649 /// Transforms the map by calling toMap on each value in it. |
| 697 * Transforms the map by calling toMap on each value in it. | |
| 698 */ | |
| 699 Map recurseMap(Map inputMap) { | 650 Map recurseMap(Map inputMap) { |
| 700 var outputMap = {}; | 651 var outputMap = {}; |
| 701 inputMap.forEach((key, value) { | 652 inputMap.forEach((key, value) { |
| 702 if (value is Map) { | 653 if (value is Map) { |
| 703 outputMap[key] = recurseMap(value); | 654 outputMap[key] = recurseMap(value); |
| 704 } else { | 655 } else { |
| 705 outputMap[key] = value.toMap(); | 656 outputMap[key] = value.toMap(); |
| 706 } | 657 } |
| 707 }); | 658 }); |
| 708 return outputMap; | 659 return outputMap; |
| 709 } | 660 } |
| 710 | 661 |
| 711 /** | 662 /// A class representing all programming constructs, like library or class. |
| 712 * A class representing all programming constructs, like library or class. | |
| 713 */ | |
| 714 class Indexable { | 663 class Indexable { |
| 715 String name; | 664 String name; |
| 716 String get qualifiedName => fileName; | 665 String get qualifiedName => fileName; |
| 717 bool isPrivate; | 666 bool isPrivate; |
| 718 | 667 |
| 719 // The qualified name (for URL purposes) and the file name are the same, | 668 // The qualified name (for URL purposes) and the file name are the same, |
| 720 // of the form packageName/ClassName or packageName/ClassName.methodName. | 669 // of the form packageName/ClassName or packageName/ClassName.methodName. |
| 721 // This defines both the URL and the directory structure. | 670 // This defines both the URL and the directory structure. |
| 722 String get fileName => packagePrefix + ownerPrefix + name; | 671 String get fileName => packagePrefix + ownerPrefix + name; |
| 723 | 672 |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 735 | 684 |
| 736 /// Qualified Name of the owner of this Indexable Item. | 685 /// Qualified Name of the owner of this Indexable Item. |
| 737 /// For Library, owner will be ""; | 686 /// For Library, owner will be ""; |
| 738 String owner; | 687 String owner; |
| 739 | 688 |
| 740 Indexable(this.name, this.comment, this.isPrivate, this.owner); | 689 Indexable(this.name, this.comment, this.isPrivate, this.owner); |
| 741 | 690 |
| 742 /// The type of this member to be used in index.txt. | 691 /// The type of this member to be used in index.txt. |
| 743 String get typeName => ''; | 692 String get typeName => ''; |
| 744 | 693 |
| 745 /** | 694 /// Creates a [Map] with this [Indexable]'s name and a preview comment. |
| 746 * Creates a [Map] with this [Indexable]'s name and a preview comment. | |
| 747 */ | |
| 748 Map get previewMap { | 695 Map get previewMap { |
| 749 var finalMap = { 'name' : name, 'qualifiedName' : qualifiedName }; | 696 var finalMap = { 'name' : name, 'qualifiedName' : qualifiedName }; |
| 750 if (comment != '') { | 697 if (comment != '') { |
| 751 var index = comment.indexOf('</p>'); | 698 var index = comment.indexOf('</p>'); |
| 752 finalMap['preview'] = '${comment.substring(0, index)}</p>'; | 699 finalMap['preview'] = '${comment.substring(0, index)}</p>'; |
| 753 } | 700 } |
| 754 return finalMap; | 701 return finalMap; |
| 755 } | 702 } |
| 756 | 703 |
| 757 /// Return an informative [Object.toString] for debugging. | 704 /// Return an informative [Object.toString] for debugging. |
| 758 String toString() => "${super.toString()}(${name.toString()})"; | 705 String toString() => "${super.toString()}(${name.toString()})"; |
| 759 | 706 |
| 760 /// Return a map representation of this type. | 707 /// Return a map representation of this type. |
| 761 Map toMap() {} | 708 Map toMap() {} |
| 762 } | 709 } |
| 763 | 710 |
| 764 /** | 711 /// A class containing contents of a Dart library. |
| 765 * A class containing contents of a Dart library. | |
| 766 */ | |
| 767 class Library extends Indexable { | 712 class Library extends Indexable { |
| 768 | 713 |
| 769 /// Top-level variables in the library. | 714 /// Top-level variables in the library. |
| 770 Map<String, Variable> variables; | 715 Map<String, Variable> variables; |
| 771 | 716 |
| 772 /// Top-level functions in the library. | 717 /// Top-level functions in the library. |
| 773 MethodGroup functions; | 718 MethodGroup functions; |
| 774 | 719 |
| 775 /// Classes defined within the library | 720 /// Classes defined within the library |
| 776 ClassGroup classes; | 721 ClassGroup classes; |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 804 'variables': recurseMap(variables), | 749 'variables': recurseMap(variables), |
| 805 'functions': functions.toMap(), | 750 'functions': functions.toMap(), |
| 806 'classes': classes.toMap(), | 751 'classes': classes.toMap(), |
| 807 'packageName': packageName, | 752 'packageName': packageName, |
| 808 'packageIntro' : packageIntro | 753 'packageIntro' : packageIntro |
| 809 }; | 754 }; |
| 810 | 755 |
| 811 String get typeName => 'library'; | 756 String get typeName => 'library'; |
| 812 } | 757 } |
| 813 | 758 |
| 814 /** | 759 /// A class containing contents of a Dart class. |
| 815 * A class containing contents of a Dart class. | |
| 816 */ | |
| 817 class Class extends Indexable { | 760 class Class extends Indexable { |
| 818 | 761 |
| 819 /// List of the names of interfaces that this class implements. | 762 /// List of the names of interfaces that this class implements. |
| 820 List<Class> interfaces = []; | 763 List<Class> interfaces = []; |
| 821 | 764 |
| 822 /// Names of classes that extends or implements this class. | 765 /// Names of classes that extends or implements this class. |
| 823 Set<String> subclasses = new Set<String>(); | 766 Set<String> subclasses = new Set<String>(); |
| 824 | 767 |
| 825 /// Top-level variables in the class. | 768 /// Top-level variables in the class. |
| 826 Map<String, Variable> variables; | 769 Map<String, Variable> variables; |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 845 | 788 |
| 846 Class(String name, this.superclass, String comment, this.interfaces, | 789 Class(String name, this.superclass, String comment, this.interfaces, |
| 847 this.variables, this.methods, this.annotations, this.generics, | 790 this.variables, this.methods, this.annotations, this.generics, |
| 848 String qualifiedName, bool isPrivate, String owner, this.isAbstract) | 791 String qualifiedName, bool isPrivate, String owner, this.isAbstract) |
| 849 : super(name, comment, isPrivate, owner) { | 792 : super(name, comment, isPrivate, owner) { |
| 850 _mdnComment(this); | 793 _mdnComment(this); |
| 851 } | 794 } |
| 852 | 795 |
| 853 String get typeName => 'class'; | 796 String get typeName => 'class'; |
| 854 | 797 |
| 855 /** | 798 /// Returns a list of all the parent classes. |
| 856 * Returns a list of all the parent classes. | |
| 857 */ | |
| 858 List<Class> parent() { | 799 List<Class> parent() { |
| 859 var parent = superclass == null ? [] : [superclass]; | 800 var parent = superclass == null ? [] : [superclass]; |
| 860 parent.addAll(interfaces); | 801 parent.addAll(interfaces); |
| 861 return parent; | 802 return parent; |
| 862 } | 803 } |
| 863 | 804 |
| 864 /** | 805 /// Add all inherited variables and methods from the provided superclass. |
| 865 * Add all inherited variables and methods from the provided superclass. | 806 /// If [_includePrivate] is true, it also adds the variables and methods from |
| 866 * If [_includePrivate] is true, it also adds the variables and methods from | 807 /// the superclass. |
| 867 * the superclass. | |
| 868 */ | |
| 869 void addInherited(Class superclass) { | 808 void addInherited(Class superclass) { |
| 870 inheritedVariables.addAll(superclass.inheritedVariables); | 809 inheritedVariables.addAll(superclass.inheritedVariables); |
| 871 inheritedVariables.addAll(superclass.variables); | 810 inheritedVariables.addAll(superclass.variables); |
| 872 inheritedMethods.addInherited(superclass); | 811 inheritedMethods.addInherited(superclass); |
| 873 } | 812 } |
| 874 | 813 |
| 875 /** | 814 /// Add the subclass to the class. |
| 876 * Add the subclass to the class. | 815 /// |
| 877 * | 816 /// If [this] is private, it will add the subclass to the list of subclasses i n |
| 878 * If [this] is private, it will add the subclass to the list of subclasses in | 817 /// the superclasses. |
| 879 * the superclasses. | |
| 880 */ | |
| 881 void addSubclass(Class subclass) { | 818 void addSubclass(Class subclass) { |
| 882 if (!_includePrivate && isPrivate) { | 819 if (!_includePrivate && isPrivate) { |
| 883 if (superclass != null) superclass.addSubclass(subclass); | 820 if (superclass != null) superclass.addSubclass(subclass); |
| 884 interfaces.forEach((interface) { | 821 interfaces.forEach((interface) { |
| 885 interface.addSubclass(subclass); | 822 interface.addSubclass(subclass); |
| 886 }); | 823 }); |
| 887 } else { | 824 } else { |
| 888 subclasses.add(subclass.qualifiedName); | 825 subclasses.add(subclass.qualifiedName); |
| 889 } | 826 } |
| 890 } | 827 } |
| 891 | 828 |
| 892 /** | 829 /// Check if this [Class] is an error or exception. |
| 893 * Check if this [Class] is an error or exception. | |
| 894 */ | |
| 895 bool isError() { | 830 bool isError() { |
| 896 if (qualifiedName == 'dart-core.Error' || | 831 if (qualifiedName == 'dart-core.Error' || |
| 897 qualifiedName == 'dart-core.Exception') | 832 qualifiedName == 'dart-core.Exception') |
| 898 return true; | 833 return true; |
| 899 for (var interface in interfaces) { | 834 for (var interface in interfaces) { |
| 900 if (interface.isError()) return true; | 835 if (interface.isError()) return true; |
| 901 } | 836 } |
| 902 if (superclass == null) return false; | 837 if (superclass == null) return false; |
| 903 return superclass.isError(); | 838 return superclass.isError(); |
| 904 } | 839 } |
| 905 | 840 |
| 906 /** | 841 /// Check that the class exists in the owner library. |
| 907 * Check that the class exists in the owner library. | 842 /// |
| 908 * | 843 /// If it does not exist in the owner library, it is a mixin applciation and |
| 909 * If it does not exist in the owner library, it is a mixin applciation and | 844 /// should be removed. |
| 910 * should be removed. | |
| 911 */ | |
| 912 void makeValid() { | 845 void makeValid() { |
| 913 var library = entityMap[owner]; | 846 var library = entityMap[owner]; |
| 914 if (library != null && !library.classes.containsKey(name)) { | 847 if (library != null && !library.classes.containsKey(name)) { |
| 915 this.isPrivate = true; | 848 this.isPrivate = true; |
| 916 // Since we are now making the mixin a private class, make all elements | 849 // Since we are now making the mixin a private class, make all elements |
| 917 // with the mixin as an owner private too. | 850 // with the mixin as an owner private too. |
| 918 entityMap.values.where((e) => e.owner == qualifiedName) | 851 entityMap.values.where((e) => e.owner == qualifiedName) |
| 919 .forEach((element) => element.isPrivate = true); | 852 .forEach((element) => element.isPrivate = true); |
| 920 // Move the subclass up to the next public superclass | 853 // Move the subclass up to the next public superclass |
| 921 subclasses.forEach((subclass) => addSubclass(entityMap[subclass])); | 854 subclasses.forEach((subclass) => addSubclass(entityMap[subclass])); |
| 922 } | 855 } |
| 923 } | 856 } |
| 924 | 857 |
| 925 /** | 858 /// Makes sure that all methods with inherited equivalents have comments. |
| 926 * Makes sure that all methods with inherited equivalents have comments. | |
| 927 */ | |
| 928 void ensureComments() { | 859 void ensureComments() { |
| 929 inheritedMethods.forEach((qualifiedName, inheritedMethod) { | 860 inheritedMethods.forEach((qualifiedName, inheritedMethod) { |
| 930 var method = methods[qualifiedName]; | 861 var method = methods[qualifiedName]; |
| 931 if (method != null) method.ensureCommentFor(inheritedMethod); | 862 if (method != null) method.ensureCommentFor(inheritedMethod); |
| 932 }); | 863 }); |
| 933 } | 864 } |
| 934 | 865 |
| 935 /** | 866 /// If a class extends a private superclass, find the closest public superclas s |
| 936 * If a class extends a private superclass, find the closest public superclass | 867 /// of the private superclass. |
| 937 * of the private superclass. | |
| 938 */ | |
| 939 String validSuperclass() { | 868 String validSuperclass() { |
| 940 if (superclass == null) return 'dart.core.Object'; | 869 if (superclass == null) return 'dart.core.Object'; |
| 941 if (_isVisible(superclass)) return superclass.qualifiedName; | 870 if (_isVisible(superclass)) return superclass.qualifiedName; |
| 942 return superclass.validSuperclass(); | 871 return superclass.validSuperclass(); |
| 943 } | 872 } |
| 944 | 873 |
| 945 /// Generates a map describing the [Class] object. | 874 /// Generates a map describing the [Class] object. |
| 946 Map toMap() => { | 875 Map toMap() => { |
| 947 'name': name, | 876 'name': name, |
| 948 'qualifiedName': qualifiedName, | 877 'qualifiedName': qualifiedName, |
| 949 'comment': comment, | 878 'comment': comment, |
| 950 'isAbstract' : isAbstract, | 879 'isAbstract' : isAbstract, |
| 951 'superclass': validSuperclass(), | 880 'superclass': validSuperclass(), |
| 952 'implements': interfaces.where(_isVisible) | 881 'implements': interfaces.where(_isVisible) |
| 953 .map((e) => e.qualifiedName).toList(), | 882 .map((e) => e.qualifiedName).toList(), |
| 954 'subclass': subclasses.toList(), | 883 'subclass': subclasses.toList(), |
| 955 'variables': recurseMap(variables), | 884 'variables': recurseMap(variables), |
| 956 'inheritedVariables': recurseMap(inheritedVariables), | 885 'inheritedVariables': recurseMap(inheritedVariables), |
| 957 'methods': methods.toMap(), | 886 'methods': methods.toMap(), |
| 958 'inheritedMethods': inheritedMethods.toMap(), | 887 'inheritedMethods': inheritedMethods.toMap(), |
| 959 'annotations': annotations.map((a) => a.toMap()).toList(), | 888 'annotations': annotations.map((a) => a.toMap()).toList(), |
| 960 'generics': recurseMap(generics) | 889 'generics': recurseMap(generics) |
| 961 }; | 890 }; |
| 962 } | 891 } |
| 963 | 892 |
| 964 /** | 893 /// A container to categorize classes into the following groups: abstract |
| 965 * A container to categorize classes into the following groups: abstract | 894 /// classes, regular classes, typedefs, and errors. |
| 966 * classes, regular classes, typedefs, and errors. | |
| 967 */ | |
| 968 class ClassGroup { | 895 class ClassGroup { |
| 969 Map<String, Class> classes = {}; | 896 Map<String, Class> classes = {}; |
| 970 Map<String, Typedef> typedefs = {}; | 897 Map<String, Typedef> typedefs = {}; |
| 971 Map<String, Class> errors = {}; | 898 Map<String, Class> errors = {}; |
| 972 | 899 |
| 973 void addClass(ClassMirror mirror) { | 900 void addClass(ClassMirror mirror) { |
| 974 _currentClass = mirror; | 901 _currentClass = mirror; |
| 975 if (mirror.isTypedef) { | 902 if (mirror.isTypedef) { |
| 976 // This is actually a Dart2jsTypedefMirror, and it does define value, | 903 // This is actually a Dart2jsTypedefMirror, and it does define value, |
| 977 // but we don't have visibility to that type. | 904 // but we don't have visibility to that type. |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 999 if (clazz.isError()) { | 926 if (clazz.isError()) { |
| 1000 errors[mirror.simpleName] = clazz; | 927 errors[mirror.simpleName] = clazz; |
| 1001 } else if (mirror.isClass) { | 928 } else if (mirror.isClass) { |
| 1002 classes[mirror.simpleName] = clazz; | 929 classes[mirror.simpleName] = clazz; |
| 1003 } else { | 930 } else { |
| 1004 throw new ArgumentError('${mirror.simpleName} - no class type match. '); | 931 throw new ArgumentError('${mirror.simpleName} - no class type match. '); |
| 1005 } | 932 } |
| 1006 } | 933 } |
| 1007 } | 934 } |
| 1008 | 935 |
| 1009 /** | 936 /// Checks if the given name is a key for any of the Class Maps. |
| 1010 * Checks if the given name is a key for any of the Class Maps. | |
| 1011 */ | |
| 1012 bool containsKey(String name) { | 937 bool containsKey(String name) { |
| 1013 return classes.containsKey(name) || errors.containsKey(name); | 938 return classes.containsKey(name) || errors.containsKey(name); |
| 1014 } | 939 } |
| 1015 | 940 |
| 1016 Map toMap() => { | 941 Map toMap() => { |
| 1017 'class': classes.values.where(_isVisible) | 942 'class': classes.values.where(_isVisible) |
| 1018 .map((e) => e.previewMap).toList(), | 943 .map((e) => e.previewMap).toList(), |
| 1019 'typedef': recurseMap(typedefs), | 944 'typedef': recurseMap(typedefs), |
| 1020 'error': errors.values.where(_isVisible) | 945 'error': errors.values.where(_isVisible) |
| 1021 .map((e) => e.previewMap).toList() | 946 .map((e) => e.previewMap).toList() |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 1044 'comment': comment, | 969 'comment': comment, |
| 1045 'return': returnType, | 970 'return': returnType, |
| 1046 'parameters': recurseMap(parameters), | 971 'parameters': recurseMap(parameters), |
| 1047 'annotations': annotations.map((a) => a.toMap()).toList(), | 972 'annotations': annotations.map((a) => a.toMap()).toList(), |
| 1048 'generics': recurseMap(generics) | 973 'generics': recurseMap(generics) |
| 1049 }; | 974 }; |
| 1050 | 975 |
| 1051 String get typeName => 'typedef'; | 976 String get typeName => 'typedef'; |
| 1052 } | 977 } |
| 1053 | 978 |
| 1054 /** | 979 /// A class containing properties of a Dart variable. |
| 1055 * A class containing properties of a Dart variable. | |
| 1056 */ | |
| 1057 class Variable extends Indexable { | 980 class Variable extends Indexable { |
| 1058 | 981 |
| 1059 bool isFinal; | 982 bool isFinal; |
| 1060 bool isStatic; | 983 bool isStatic; |
| 1061 bool isConst; | 984 bool isConst; |
| 1062 Type type; | 985 Type type; |
| 1063 | 986 |
| 1064 /// List of the meta annotations on the variable. | 987 /// List of the meta annotations on the variable. |
| 1065 List<Annotation> annotations; | 988 List<Annotation> annotations; |
| 1066 | 989 |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 1078 'final': isFinal.toString(), | 1001 'final': isFinal.toString(), |
| 1079 'static': isStatic.toString(), | 1002 'static': isStatic.toString(), |
| 1080 'constant': isConst.toString(), | 1003 'constant': isConst.toString(), |
| 1081 'type': new List.filled(1, type.toMap()), | 1004 'type': new List.filled(1, type.toMap()), |
| 1082 'annotations': annotations.map((a) => a.toMap()).toList() | 1005 'annotations': annotations.map((a) => a.toMap()).toList() |
| 1083 }; | 1006 }; |
| 1084 | 1007 |
| 1085 String get typeName => 'property'; | 1008 String get typeName => 'property'; |
| 1086 } | 1009 } |
| 1087 | 1010 |
| 1088 /** | 1011 /// A class containing properties of a Dart method. |
| 1089 * A class containing properties of a Dart method. | |
| 1090 */ | |
| 1091 class Method extends Indexable { | 1012 class Method extends Indexable { |
| 1092 | 1013 |
| 1093 /// Parameters for this method. | 1014 /// Parameters for this method. |
| 1094 Map<String, Parameter> parameters; | 1015 Map<String, Parameter> parameters; |
| 1095 | 1016 |
| 1096 bool isStatic; | 1017 bool isStatic; |
| 1097 bool isAbstract; | 1018 bool isAbstract; |
| 1098 bool isConst; | 1019 bool isConst; |
| 1099 bool isConstructor; | 1020 bool isConstructor; |
| 1100 bool isGetter; | 1021 bool isGetter; |
| 1101 bool isSetter; | 1022 bool isSetter; |
| 1102 bool isOperator; | 1023 bool isOperator; |
| 1103 Type returnType; | 1024 Type returnType; |
| 1104 | 1025 |
| 1105 /// Qualified name to state where the comment is inherited from. | 1026 /// Qualified name to state where the comment is inherited from. |
| 1106 String commentInheritedFrom = ""; | 1027 String commentInheritedFrom = ""; |
| 1107 | 1028 |
| 1108 /// List of the meta annotations on the method. | 1029 /// List of the meta annotations on the method. |
| 1109 List<Annotation> annotations; | 1030 List<Annotation> annotations; |
| 1110 | 1031 |
| 1111 Method(String name, this.isStatic, this.isAbstract, this.isConst, | 1032 Method(String name, this.isStatic, this.isAbstract, this.isConst, |
| 1112 this.returnType, String comment, this.parameters, this.annotations, | 1033 this.returnType, String comment, this.parameters, this.annotations, |
| 1113 String qualifiedName, bool isPrivate, String owner, this.isConstructor, | 1034 String qualifiedName, bool isPrivate, String owner, this.isConstructor, |
| 1114 this.isGetter, this.isSetter, this.isOperator) | 1035 this.isGetter, this.isSetter, this.isOperator) |
| 1115 : super(name, comment, isPrivate, owner) { | 1036 : super(name, comment, isPrivate, owner) { |
| 1116 _mdnComment(this); | 1037 _mdnComment(this); |
| 1117 } | 1038 } |
| 1118 | 1039 |
| 1119 /** | 1040 /// Makes sure that the method with an inherited equivalent have comments. |
| 1120 * Makes sure that the method with an inherited equivalent have comments. | |
| 1121 */ | |
| 1122 void ensureCommentFor(Method inheritedMethod) { | 1041 void ensureCommentFor(Method inheritedMethod) { |
| 1123 if (comment.isNotEmpty) return; | 1042 if (comment.isNotEmpty) return; |
| 1124 (entityMap[inheritedMethod.owner] as Class).ensureComments(); | 1043 (entityMap[inheritedMethod.owner] as Class).ensureComments(); |
| 1125 comment = inheritedMethod.comment; | 1044 comment = inheritedMethod.comment; |
| 1126 commentInheritedFrom = inheritedMethod.commentInheritedFrom == '' ? | 1045 commentInheritedFrom = inheritedMethod.commentInheritedFrom == '' ? |
| 1127 inheritedMethod.qualifiedName : inheritedMethod.commentInheritedFrom; | 1046 inheritedMethod.qualifiedName : inheritedMethod.commentInheritedFrom; |
| 1128 } | 1047 } |
| 1129 | 1048 |
| 1130 /// Generates a map describing the [Method] object. | 1049 /// Generates a map describing the [Method] object. |
| 1131 Map toMap() => { | 1050 Map toMap() => { |
| 1132 'name': name, | 1051 'name': name, |
| 1133 'qualifiedName': qualifiedName, | 1052 'qualifiedName': qualifiedName, |
| 1134 'comment': comment, | 1053 'comment': comment, |
| 1135 'commentFrom': commentInheritedFrom, | 1054 'commentFrom': commentInheritedFrom, |
| 1136 'static': isStatic.toString(), | 1055 'static': isStatic.toString(), |
| 1137 'abstract': isAbstract.toString(), | 1056 'abstract': isAbstract.toString(), |
| 1138 'constant': isConst.toString(), | 1057 'constant': isConst.toString(), |
| 1139 'return': new List.filled(1, returnType.toMap()), | 1058 'return': new List.filled(1, returnType.toMap()), |
| 1140 'parameters': recurseMap(parameters), | 1059 'parameters': recurseMap(parameters), |
| 1141 'annotations': annotations.map((a) => a.toMap()).toList() | 1060 'annotations': annotations.map((a) => a.toMap()).toList() |
| 1142 }; | 1061 }; |
| 1143 | 1062 |
| 1144 String get typeName => isConstructor ? 'constructor' : | 1063 String get typeName => isConstructor ? 'constructor' : |
| 1145 isGetter ? 'getter' : isSetter ? 'setter' : | 1064 isGetter ? 'getter' : isSetter ? 'setter' : |
| 1146 isOperator ? 'operator' : 'method'; | 1065 isOperator ? 'operator' : 'method'; |
| 1147 } | 1066 } |
| 1148 | 1067 |
| 1149 /** | 1068 /// A container to categorize methods into the following groups: setters, |
| 1150 * A container to categorize methods into the following groups: setters, | 1069 /// getters, constructors, operators, regular methods. |
| 1151 * getters, constructors, operators, regular methods. | |
| 1152 */ | |
| 1153 class MethodGroup { | 1070 class MethodGroup { |
| 1154 Map<String, Method> setters = {}; | 1071 Map<String, Method> setters = {}; |
| 1155 Map<String, Method> getters = {}; | 1072 Map<String, Method> getters = {}; |
| 1156 Map<String, Method> constructors = {}; | 1073 Map<String, Method> constructors = {}; |
| 1157 Map<String, Method> operators = {}; | 1074 Map<String, Method> operators = {}; |
| 1158 Map<String, Method> regularMethods = {}; | 1075 Map<String, Method> regularMethods = {}; |
| 1159 | 1076 |
| 1160 void addMethod(MethodMirror mirror) { | 1077 void addMethod(MethodMirror mirror) { |
| 1161 var method = new Method(mirror.simpleName, mirror.isStatic, | 1078 var method = new Method(mirror.simpleName, mirror.isStatic, |
| 1162 mirror.isAbstract, mirror.isConstConstructor, _type(mirror.returnType), | 1079 mirror.isAbstract, mirror.isConstConstructor, _type(mirror.returnType), |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1211 } | 1128 } |
| 1212 | 1129 |
| 1213 void forEach(void f(String key, Method value)) { | 1130 void forEach(void f(String key, Method value)) { |
| 1214 setters.forEach(f); | 1131 setters.forEach(f); |
| 1215 getters.forEach(f); | 1132 getters.forEach(f); |
| 1216 operators.forEach(f); | 1133 operators.forEach(f); |
| 1217 regularMethods.forEach(f); | 1134 regularMethods.forEach(f); |
| 1218 } | 1135 } |
| 1219 } | 1136 } |
| 1220 | 1137 |
| 1221 /** | 1138 /// A class containing properties of a Dart method/function parameter. |
| 1222 * A class containing properties of a Dart method/function parameter. | |
| 1223 */ | |
| 1224 class Parameter { | 1139 class Parameter { |
| 1225 | 1140 |
| 1226 String name; | 1141 String name; |
| 1227 bool isOptional; | 1142 bool isOptional; |
| 1228 bool isNamed; | 1143 bool isNamed; |
| 1229 bool hasDefaultValue; | 1144 bool hasDefaultValue; |
| 1230 Type type; | 1145 Type type; |
| 1231 String defaultValue; | 1146 String defaultValue; |
| 1232 | 1147 |
| 1233 /// List of the meta annotations on the parameter. | 1148 /// List of the meta annotations on the parameter. |
| 1234 List<Annotation> annotations; | 1149 List<Annotation> annotations; |
| 1235 | 1150 |
| 1236 Parameter(this.name, this.isOptional, this.isNamed, this.hasDefaultValue, | 1151 Parameter(this.name, this.isOptional, this.isNamed, this.hasDefaultValue, |
| 1237 this.type, this.defaultValue, this.annotations); | 1152 this.type, this.defaultValue, this.annotations); |
| 1238 | 1153 |
| 1239 /// Generates a map describing the [Parameter] object. | 1154 /// Generates a map describing the [Parameter] object. |
| 1240 Map toMap() => { | 1155 Map toMap() => { |
| 1241 'name': name, | 1156 'name': name, |
| 1242 'optional': isOptional.toString(), | 1157 'optional': isOptional.toString(), |
| 1243 'named': isNamed.toString(), | 1158 'named': isNamed.toString(), |
| 1244 'default': hasDefaultValue.toString(), | 1159 'default': hasDefaultValue.toString(), |
| 1245 'type': new List.filled(1, type.toMap()), | 1160 'type': new List.filled(1, type.toMap()), |
| 1246 'value': defaultValue, | 1161 'value': defaultValue, |
| 1247 'annotations': annotations.map((a) => a.toMap()).toList() | 1162 'annotations': annotations.map((a) => a.toMap()).toList() |
| 1248 }; | 1163 }; |
| 1249 } | 1164 } |
| 1250 | 1165 |
| 1251 /** | 1166 /// A class containing properties of a Generic. |
| 1252 * A class containing properties of a Generic. | |
| 1253 */ | |
| 1254 class Generic { | 1167 class Generic { |
| 1255 String name; | 1168 String name; |
| 1256 String type; | 1169 String type; |
| 1257 | 1170 |
| 1258 Generic(this.name, this.type); | 1171 Generic(this.name, this.type); |
| 1259 | 1172 |
| 1260 Map toMap() => { | 1173 Map toMap() => { |
| 1261 'name': name, | 1174 'name': name, |
| 1262 'type': type | 1175 'type': type |
| 1263 }; | 1176 }; |
| 1264 } | 1177 } |
| 1265 | 1178 |
| 1266 /** | 1179 /// Holds the name of a return type, and its generic type parameters. |
| 1267 * Holds the name of a return type, and its generic type parameters. | 1180 /// |
| 1268 * | 1181 /// Return types are of a form [outer]<[inner]>. |
| 1269 * Return types are of a form [outer]<[inner]>. | 1182 /// If there is no [inner] part, [inner] will be an empty list. |
| 1270 * If there is no [inner] part, [inner] will be an empty list. | 1183 /// |
| 1271 * | 1184 /// For example: |
| 1272 * For example: | 1185 /// int size() |
| 1273 * int size() | 1186 /// "return" : |
| 1274 * "return" : | 1187 /// - "outer" : "dart-core.int" |
| 1275 * - "outer" : "dart-core.int" | 1188 /// "inner" : |
| 1276 * "inner" : | 1189 /// |
| 1277 * | 1190 /// List<String> toList() |
| 1278 * List<String> toList() | 1191 /// "return" : |
| 1279 * "return" : | 1192 /// - "outer" : "dart-core.List" |
| 1280 * - "outer" : "dart-core.List" | 1193 /// "inner" : |
| 1281 * "inner" : | 1194 /// - "outer" : "dart-core.String" |
| 1282 * - "outer" : "dart-core.String" | 1195 /// "inner" : |
| 1283 * "inner" : | 1196 /// |
| 1284 * | 1197 /// Map<String, List<int>> |
| 1285 * Map<String, List<int>> | 1198 /// "return" : |
| 1286 * "return" : | 1199 /// - "outer" : "dart-core.Map" |
| 1287 * - "outer" : "dart-core.Map" | 1200 /// "inner" : |
| 1288 * "inner" : | 1201 /// - "outer" : "dart-core.String" |
| 1289 * - "outer" : "dart-core.String" | 1202 /// "inner" : |
| 1290 * "inner" : | 1203 /// - "outer" : "dart-core.List" |
| 1291 * - "outer" : "dart-core.List" | 1204 /// "inner" : |
| 1292 * "inner" : | 1205 /// - "outer" : "dart-core.int" |
| 1293 * - "outer" : "dart-core.int" | 1206 /// "inner" : |
| 1294 * "inner" : | |
| 1295 */ | |
| 1296 class Type { | 1207 class Type { |
| 1297 String outer; | 1208 String outer; |
| 1298 List<Type> inner; | 1209 List<Type> inner; |
| 1299 | 1210 |
| 1300 Type(this.outer, this.inner); | 1211 Type(this.outer, this.inner); |
| 1301 | 1212 |
| 1302 Map toMap() => { | 1213 Map toMap() => { |
| 1303 'outer': outer, | 1214 'outer': outer, |
| 1304 'inner': inner.map((e) => e.toMap()).toList() | 1215 'inner': inner.map((e) => e.toMap()).toList() |
| 1305 }; | 1216 }; |
| 1306 } | 1217 } |
| 1307 | 1218 |
| 1308 /** | 1219 /// Holds the name of the annotation, and its parameters. |
| 1309 * Holds the name of the annotation, and its parameters. | |
| 1310 */ | |
| 1311 class Annotation { | 1220 class Annotation { |
| 1312 String qualifiedName; | 1221 String qualifiedName; |
| 1313 List<String> parameters; | 1222 List<String> parameters; |
| 1314 | 1223 |
| 1315 Annotation(this.qualifiedName, this.parameters); | 1224 Annotation(this.qualifiedName, this.parameters); |
| 1316 | 1225 |
| 1317 Map toMap() => { | 1226 Map toMap() => { |
| 1318 'name': qualifiedName, | 1227 'name': qualifiedName, |
| 1319 'parameters': parameters | 1228 'parameters': parameters |
| 1320 }; | 1229 }; |
| 1321 } | 1230 } |
| 1322 | 1231 |
| 1323 /// Given a mirror, returns its qualified name, but following the conventions | 1232 /// Given a mirror, returns its qualified name, but following the conventions |
| 1324 /// we're using in Dartdoc, which is that library names with dots in them | 1233 /// we're using in Dartdoc, which is that library names with dots in them |
| 1325 /// have them replaced with hyphens. | 1234 /// have them replaced with hyphens. |
| 1326 String docName(DeclarationMirror m) { | 1235 String docName(DeclarationMirror m) { |
| 1327 if (m is LibraryMirror) { | 1236 if (m is LibraryMirror) { |
| 1328 return (m as LibraryMirror).qualifiedName.replaceAll('.','-'); | 1237 return (m as LibraryMirror).qualifiedName.replaceAll('.','-'); |
| 1329 } | 1238 } |
| 1330 var owner = m.owner; | 1239 var owner = m.owner; |
| 1331 if (owner == null) return m.qualifiedName; | 1240 if (owner == null) return m.qualifiedName; |
| 1332 // For the unnamed constructor we just return the class name. | 1241 // For the unnamed constructor we just return the class name. |
| 1333 if (m.simpleName == '') return docName(owner); | 1242 if (m.simpleName == '') return docName(owner); |
| 1334 return docName(owner) + '.' + m.simpleName; | 1243 return docName(owner) + '.' + m.simpleName; |
| 1335 } | 1244 } |
| OLD | NEW |