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 /// **docgen** is a tool for creating machine readable representations of Dart | 5 /// **docgen** is a tool for creating machine readable representations of Dart |
| 6 /// code metadata, including: classes, members, comments and annotations. | 6 /// code metadata, including: classes, members, comments and annotations. |
| 7 /// | 7 /// |
| 8 /// docgen is run on a `.dart` file or a directory containing `.dart` files. | 8 /// docgen is run on a `.dart` file or a directory containing `.dart` files. |
| 9 /// | 9 /// |
| 10 /// $ dart docgen.dart [OPTIONS] [FILE/DIR] | 10 /// $ dart docgen.dart [OPTIONS] [FILE/DIR] |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 89 * [A Tour of the Dart Libraries](http://www.dartlang.org/docs/dart-up-and-runn ing/contents/ch03.html) | 89 * [A Tour of the Dart Libraries](http://www.dartlang.org/docs/dart-up-and-runn ing/contents/ch03.html) |
| 90 | 90 |
| 91 This API reference is automatically generated from the source code in the | 91 This API reference is automatically generated from the source code in the |
| 92 [Dart project](https://code.google.com/p/dart/). | 92 [Dart project](https://code.google.com/p/dart/). |
| 93 If you'd like to contribute to this documentation, see | 93 If you'd like to contribute to this documentation, see |
| 94 [Contributing](https://code.google.com/p/dart/wiki/Contributing) | 94 [Contributing](https://code.google.com/p/dart/wiki/Contributing) |
| 95 and | 95 and |
| 96 [Writing API Documentation](https://code.google.com/p/dart/wiki/WritingApiDocume ntation). | 96 [Writing API Documentation](https://code.google.com/p/dart/wiki/WritingApiDocume ntation). |
| 97 """; | 97 """; |
| 98 | 98 |
| 99 // TODO(efortuna): The use of this field is odd (this is based on how it was | |
| 100 // originally used. Try to cleanup. | |
| 101 /// Index of all indexable items. This also ensures that no class is | |
| 102 /// created more than once. | |
| 103 Map<String, Indexable> entityMap = new Map<String, Indexable>(); | |
| 104 | |
| 105 /// Docgen constructor initializes the link resolver for markdown parsing. | 99 /// Docgen constructor initializes the link resolver for markdown parsing. |
| 106 /// Also initializes the command line arguments. | 100 /// Also initializes the command line arguments. |
| 107 /// | 101 /// |
| 108 /// [packageRoot] is the packages directory of the directory being analyzed. | 102 /// [packageRoot] is the packages directory of the directory being analyzed. |
| 109 /// If [includeSdk] is `true`, then any SDK libraries explicitly imported will | 103 /// If [includeSdk] is `true`, then any SDK libraries explicitly imported will |
| 110 /// also be documented. | 104 /// also be documented. |
| 111 /// If [parseSdk] is `true`, then all Dart SDK libraries will be documented. | 105 /// If [parseSdk] is `true`, then all Dart SDK libraries will be documented. |
| 112 /// This option is useful when only the SDK libraries are needed. | 106 /// This option is useful when only the SDK libraries are needed. |
| 113 /// | 107 /// |
| 114 /// Returned Future completes with true if document generation is successful. | 108 /// Returned Future completes with true if document generation is successful. |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 182 LibraryMirror _getOwningLibraryFromMirror(DeclarationMirror mirror) { | 176 LibraryMirror _getOwningLibraryFromMirror(DeclarationMirror mirror) { |
| 183 if (mirror is LibraryMirror) return mirror; | 177 if (mirror is LibraryMirror) return mirror; |
| 184 if (mirror == null) return null; | 178 if (mirror == null) return null; |
| 185 return _getOwningLibraryFromMirror(mirror.owner); | 179 return _getOwningLibraryFromMirror(mirror.owner); |
| 186 } | 180 } |
| 187 } | 181 } |
| 188 | 182 |
| 189 /// Docgen representation of an item to be documented, that wraps around a | 183 /// Docgen representation of an item to be documented, that wraps around a |
| 190 /// dart2js mirror. | 184 /// dart2js mirror. |
| 191 abstract class MirrorBased { | 185 abstract class MirrorBased { |
| 186 /// The original dart2js mirror around which this object wraps. | |
| 192 DeclarationMirror get mirror; | 187 DeclarationMirror get mirror; |
| 193 | 188 |
| 194 /// Returns a list of meta annotations assocated with a mirror. | 189 /// Returns a list of meta annotations assocated with a mirror. |
| 195 List<Annotation> _createAnnotations(DeclarationMirror mirror, | 190 List<Annotation> _createAnnotations(DeclarationMirror mirror, |
| 196 Library owningLibrary) { | 191 Library owningLibrary) { |
| 197 var annotationMirrors = mirror.metadata.where((e) => | 192 var annotationMirrors = mirror.metadata.where((e) => |
| 198 e is dart2js.Dart2JsConstructedConstantMirror); | 193 e is dart2js.Dart2JsConstructedConstantMirror); |
| 199 var annotations = []; | 194 var annotations = []; |
| 200 annotationMirrors.forEach((annotation) { | 195 annotationMirrors.forEach((annotation) { |
| 201 var docgenAnnotation = new Annotation(annotation, owningLibrary); | 196 var docgenAnnotation = new Annotation(annotation, owningLibrary); |
| 202 if (!_SKIPPED_ANNOTATIONS.contains( | 197 if (!_SKIPPED_ANNOTATIONS.contains( |
| 203 docgenAnnotation.mirror.qualifiedName)) { | 198 docgenAnnotation.mirror.qualifiedName)) { |
| 204 annotations.add(docgenAnnotation); | 199 annotations.add(docgenAnnotation); |
| 205 } | 200 } |
| 206 }); | 201 }); |
| 207 return annotations; | 202 return annotations; |
| 208 } | 203 } |
| 209 } | 204 } |
| 210 | 205 |
| 206 /// Top level documentation traversal and generation object. | |
| 207 /// | |
| 208 /// Yes, everything in this class is used statically so this technically need | |
|
Alan Knight
2014/01/31 17:48:53
missing "doesn't" ?
Emily Fortuna
2014/02/01 02:06:48
Done
| |
| 209 /// to be its own class, but it's grouped together for semantic separation from | |
| 210 /// the other classes and functionality in this library. | |
| 211 class _Generator { | 211 class _Generator { |
| 212 /// The directory where the output docs are generated. | |
| 212 static var _outputDirectory; | 213 static var _outputDirectory; |
| 213 | 214 |
| 214 /// This is set from the command line arguments flag --include-private | 215 /// This is set from the command line arguments flag --include-private |
| 215 static bool _includePrivate = false; | 216 static bool _includePrivate = false; |
| 216 | 217 |
| 217 /// Library names to explicitly exclude. | 218 /// Library names to explicitly exclude. |
| 218 /// | 219 /// |
| 219 /// Set from the command line option | 220 /// Set from the command line option |
| 220 /// --exclude-lib. | 221 /// --exclude-lib. |
| 221 static List<String> _excluded; | 222 static List<String> _excluded; |
| 222 | 223 |
| 224 /// Logger for printing out progress of documentation generation. | |
| 223 static Logger logger = new Logger('Docgen'); | 225 static Logger logger = new Logger('Docgen'); |
| 224 | 226 |
| 225 /// Docgen constructor initializes the link resolver for markdown parsing. | 227 /// Docgen constructor initializes the link resolver for markdown parsing. |
| 226 /// Also initializes the command line arguments. | 228 /// Also initializes the command line arguments. |
| 227 /// | 229 /// |
| 228 /// [packageRoot] is the packages directory of the directory being analyzed. | 230 /// [packageRoot] is the packages directory of the directory being analyzed. |
| 229 /// If [includeSdk] is `true`, then any SDK libraries explicitly imported will | 231 /// If [includeSdk] is `true`, then any SDK libraries explicitly imported will |
| 230 /// also be documented. | 232 /// also be documented. |
| 231 /// If [parseSdk] is `true`, then all Dart SDK libraries will be documented. | 233 /// If [parseSdk] is `true`, then all Dart SDK libraries will be documented. |
| 232 /// This option is useful when only the SDK libraries are needed. | 234 /// This option is useful when only the SDK libraries are needed. |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 252 if (includeSdk) { | 254 if (includeSdk) { |
| 253 allLibraries.addAll(_listSdk()); | 255 allLibraries.addAll(_listSdk()); |
| 254 } | 256 } |
| 255 | 257 |
| 256 return getMirrorSystem(allLibraries, packageRoot: updatedPackageRoot, | 258 return getMirrorSystem(allLibraries, packageRoot: updatedPackageRoot, |
| 257 parseSdk: parseSdk) | 259 parseSdk: parseSdk) |
| 258 .then((MirrorSystem mirrorSystem) { | 260 .then((MirrorSystem mirrorSystem) { |
| 259 if (mirrorSystem.libraries.isEmpty) { | 261 if (mirrorSystem.libraries.isEmpty) { |
| 260 throw new StateError('No library mirrors were created.'); | 262 throw new StateError('No library mirrors were created.'); |
| 261 } | 263 } |
| 262 Indexable.initializeTopLevelLibraries(mirrorSystem); | 264 Indexable._initializeTopLevelLibraries(mirrorSystem); |
| 263 | 265 |
| 264 var availableLibraries = mirrorSystem.libraries.values.where( | 266 var availableLibraries = mirrorSystem.libraries.values.where( |
| 265 (each) => each.uri.scheme == 'file'); | 267 (each) => each.uri.scheme == 'file'); |
| 266 var availableLibrariesByPath = new Map.fromIterables( | 268 var availableLibrariesByPath = new Map.fromIterables( |
| 267 availableLibraries.map((each) => each.uri), | 269 availableLibraries.map((each) => each.uri), |
| 268 availableLibraries); | 270 availableLibraries); |
| 269 var librariesToDocument = requestedLibraries.map( | 271 var librariesToDocument = requestedLibraries.map( |
| 270 (each) => availableLibrariesByPath.putIfAbsent(each, | 272 (each) => availableLibrariesByPath.putIfAbsent(each, |
| 271 () => throw "Missing library $each")).toList(); | 273 () => throw "Missing library $each")).toList(); |
| 272 librariesToDocument.addAll( | 274 librariesToDocument.addAll( |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 298 if (!subdir.existsSync()) { | 300 if (!subdir.existsSync()) { |
| 299 subdir.createSync(); | 301 subdir.createSync(); |
| 300 } | 302 } |
| 301 } | 303 } |
| 302 } | 304 } |
| 303 File file = new File(path.join(_outputDirectory, filename)); | 305 File file = new File(path.join(_outputDirectory, filename)); |
| 304 file.writeAsStringSync(text, | 306 file.writeAsStringSync(text, |
| 305 mode: append ? FileMode.APPEND : FileMode.WRITE); | 307 mode: append ? FileMode.APPEND : FileMode.WRITE); |
| 306 } | 308 } |
| 307 | 309 |
| 310 /// Resolve all the links in the introductory comments for a given library or | |
| 311 /// package as specified by [filename]. | |
| 312 static String _readIntroductionFile(String fileName, bool includeSdk) { | |
| 313 var linkResolver = (name) => Indexable.globalFixReference(name); | |
| 314 var defaultText = includeSdk ? _DEFAULT_SDK_INTRODUCTION : ''; | |
| 315 var introText = defaultText; | |
| 316 if (fileName.isNotEmpty) { | |
| 317 var introFile = new File(fileName); | |
| 318 introText = introFile.existsSync() ? introFile.readAsStringSync() : | |
| 319 defaultText; | |
| 320 } | |
| 321 return markdown.markdownToHtml(introText, | |
| 322 linkResolver: linkResolver, inlineSyntaxes: _MARKDOWN_SYNTAXES); | |
| 323 } | |
| 324 | |
| 308 /// Creates documentation for filtered libraries. | 325 /// Creates documentation for filtered libraries. |
| 309 static void _documentLibraries(List<LibraryMirror> libs, | 326 static void _documentLibraries(List<LibraryMirror> libs, |
| 310 {bool includeSdk: false, bool outputToYaml: true, bool append: false, | 327 {bool includeSdk: false, bool outputToYaml: true, bool append: false, |
| 311 bool parseSdk: false, String introFileName: ''}) { | 328 bool parseSdk: false, String introFileName: ''}) { |
| 312 libs.forEach((lib) { | 329 libs.forEach((lib) { |
| 313 // Files belonging to the SDK have a uri that begins with 'dart:'. | 330 // Files belonging to the SDK have a uri that begins with 'dart:'. |
| 314 if (includeSdk || !lib.uri.toString().startsWith('dart:')) { | 331 if (includeSdk || !lib.uri.toString().startsWith('dart:')) { |
| 315 var library = generateLibrary(lib); | 332 var library = generateLibrary(lib); |
| 316 entityMap[library.name] = library; | |
| 317 } | 333 } |
| 318 }); | 334 }); |
| 319 | 335 |
| 320 var filteredEntities = entityMap.values.where(_isFullChainVisible); | 336 var filteredEntities = new Set<Indexable>(); |
| 321 | 337 for (Map<String, Set<Indexable>> firstLevel in |
| 322 /*var filteredEntities2 = new Set<MirrorBased>(); | 338 Indexable._mirrorToDocgen.values) { |
| 323 for (Map<String, Set<MirrorBased>> firstLevel in mirrorToDocgen.values) { | 339 for (Set<Indexable> items in firstLevel.values) { |
| 324 for (Set<MirrorBased> items in firstLevel.values) { | 340 for (Indexable item in items) { |
| 325 for (MirrorBased item in items) { | |
| 326 if (_isFullChainVisible(item)) { | 341 if (_isFullChainVisible(item)) { |
| 327 filteredEntities2.add(item); | 342 if (item is! Method || |
| 343 (item is Method && item.methodInheritedFrom == null)) { | |
| 344 filteredEntities.add(item); | |
| 345 } | |
| 328 } | 346 } |
| 329 } | 347 } |
| 330 } | 348 } |
| 331 }*/ | 349 } |
| 332 | |
| 333 /*print('THHHHHEEE DIFFERENCE IS'); | |
| 334 var set1 = new Set.from(filteredEntities); | |
| 335 var set2 = new Set.from(filteredEntities2); | |
| 336 var aResult = set2.difference(set1); | |
| 337 for (MirrorBased r in aResult) { | |
| 338 print(' a result is $r and ${r.docName}'); | |
| 339 }*/ | |
| 340 //print(set1.difference(set2)); | |
| 341 | 350 |
| 342 // Outputs a JSON file with all libraries and their preview comments. | 351 // Outputs a JSON file with all libraries and their preview comments. |
| 343 // This will help the viewer know what libraries are available to read in. | 352 // This will help the viewer know what libraries are available to read in. |
| 344 var libraryMap; | 353 var libraryMap; |
| 345 var linkResolver = (name) => Indexable.globalFixReference(name); | |
| 346 | |
| 347 String readIntroductionFile(String fileName, includeSdk) { | |
| 348 var defaultText = includeSdk ? _DEFAULT_SDK_INTRODUCTION : ''; | |
| 349 var introText = defaultText; | |
| 350 if (fileName.isNotEmpty) { | |
| 351 var introFile = new File(fileName); | |
| 352 introText = introFile.existsSync() ? introFile.readAsStringSync() : | |
| 353 defaultText; | |
| 354 } | |
| 355 return markdown.markdownToHtml(introText, | |
| 356 linkResolver: linkResolver, inlineSyntaxes: _MARKDOWN_SYNTAXES); | |
| 357 } | |
| 358 | 354 |
| 359 if (append) { | 355 if (append) { |
| 360 var docsDir = listDir(_outputDirectory); | 356 var docsDir = listDir(_outputDirectory); |
| 361 if (!docsDir.contains('$_outputDirectory/library_list.json')) { | 357 if (!docsDir.contains('$_outputDirectory/library_list.json')) { |
| 362 throw new StateError('No library_list.json'); | 358 throw new StateError('No library_list.json'); |
| 363 } | 359 } |
| 364 libraryMap = | 360 libraryMap = |
| 365 JSON.decode(new File( | 361 JSON.decode(new File( |
| 366 '$_outputDirectory/library_list.json').readAsStringSync()); | 362 '$_outputDirectory/library_list.json').readAsStringSync()); |
| 367 libraryMap['libraries'].addAll(filteredEntities | 363 libraryMap['libraries'].addAll(filteredEntities |
| 368 .where((e) => e is Library) | 364 .where((e) => e is Library) |
| 369 .map((e) => e.previewMap)); | 365 .map((e) => e.previewMap)); |
| 370 var intro = libraryMap['introduction']; | 366 var intro = libraryMap['introduction']; |
| 371 var spacing = intro.isEmpty ? '' : '<br/><br/>'; | 367 var spacing = intro.isEmpty ? '' : '<br/><br/>'; |
| 372 libraryMap['introduction'] = | 368 libraryMap['introduction'] = |
| 373 "$intro$spacing${readIntroductionFile(introFileName, includeSdk)}"; | 369 "$intro$spacing${_readIntroductionFile(introFileName, includeSdk)}"; |
| 374 outputToYaml = libraryMap['filetype'] == 'yaml'; | 370 outputToYaml = libraryMap['filetype'] == 'yaml'; |
| 375 } else { | 371 } else { |
| 376 libraryMap = { | 372 libraryMap = { |
| 377 'libraries' : filteredEntities.where((e) => | 373 'libraries' : filteredEntities.where((e) => |
| 378 e is Library).map((e) => e.previewMap).toList(), | 374 e is Library).map((e) => e.previewMap).toList(), |
| 379 'introduction' : readIntroductionFile(introFileName, includeSdk), | 375 'introduction' : _readIntroductionFile(introFileName, includeSdk), |
| 380 'filetype' : outputToYaml ? 'yaml' : 'json' | 376 'filetype' : outputToYaml ? 'yaml' : 'json' |
| 381 }; | 377 }; |
| 382 } | 378 } |
| 379 _writeOutputFiles(libraryMap, filteredEntities, outputToYaml, append); | |
| 380 } | |
| 381 | |
| 382 /// Output all of the libraries and classes into json or yaml files for | |
| 383 /// consumption by a viewer. | |
| 384 static void _writeOutputFiles(libraryMap, | |
| 385 Iterable<Indexable> filteredEntities, bool outputToYaml, bool append) { | |
| 383 _writeToFile(JSON.encode(libraryMap), 'library_list.json'); | 386 _writeToFile(JSON.encode(libraryMap), 'library_list.json'); |
| 384 | 387 |
| 385 // Output libraries and classes to file after all information is generated. | 388 // Output libraries and classes to file after all information is generated. |
| 386 filteredEntities.where((e) => e is Class || e is Library).forEach((output) { | 389 filteredEntities.where((e) => e is Class || e is Library).forEach((output) { |
| 387 _writeIndexableToFile(output, outputToYaml); | 390 _writeIndexableToFile(output, outputToYaml); |
| 388 }); | 391 }); |
| 389 | 392 |
| 390 // Outputs all the qualified names documented with their type. | 393 // Outputs all the qualified names documented with their type. |
| 391 // This will help generate search results. | 394 // This will help generate search results. |
| 392 _writeToFile(filteredEntities.map((e) => | 395 _writeToFile(filteredEntities.map((e) => |
| 393 '${e.qualifiedName} ${e.typeName}').join('\n') + '\n', | 396 '${e.qualifiedName} ${e.typeName}').join('\n') + '\n', |
| 394 'index.txt', append: append); | 397 'index.txt', append: append); |
| 395 var index = new Map.fromIterables( | 398 var index = new Map.fromIterables( |
| 396 filteredEntities.map((e) => e.qualifiedName), | 399 filteredEntities.map((e) => e.qualifiedName), |
| 397 filteredEntities.map((e) => e.typeName)); | 400 filteredEntities.map((e) => e.typeName)); |
| 398 if (append) { | 401 if (append) { |
| 399 var previousIndex = | 402 var previousIndex = |
| 400 JSON.decode(new File( | 403 JSON.decode(new File( |
| 401 '$_outputDirectory/index.json').readAsStringSync()); | 404 '$_outputDirectory/index.json').readAsStringSync()); |
| 402 index.addAll(previousIndex); | 405 index.addAll(previousIndex); |
| 403 } | 406 } |
| 404 _writeToFile(JSON.encode(index), 'index.json'); | 407 _writeToFile(JSON.encode(index), 'index.json'); |
| 405 } | 408 } |
| 406 | 409 |
| 410 /// Helper method to serialize the given Indexable out to a file. | |
| 407 static void _writeIndexableToFile(Indexable result, bool outputToYaml) { | 411 static void _writeIndexableToFile(Indexable result, bool outputToYaml) { |
| 408 var outputFile = result.fileName; | 412 var outputFile = result.fileName; |
| 409 var output; | 413 var output; |
| 410 if (outputToYaml) { | 414 if (outputToYaml) { |
| 411 output = getYamlString(result.toMap()); | 415 output = getYamlString(result.toMap()); |
| 412 outputFile = outputFile + '.yaml'; | 416 outputFile = outputFile + '.yaml'; |
| 413 } else { | 417 } else { |
| 414 output = JSON.encode(result.toMap()); | 418 output = JSON.encode(result.toMap()); |
| 415 outputFile = outputFile + '.json'; | 419 outputFile = outputFile + '.json'; |
| 416 } | 420 } |
| 417 _writeToFile(output, outputFile); | 421 _writeToFile(output, outputFile); |
| 418 } | 422 } |
| 419 | 423 |
| 420 /// Set the location of the ouput directory, and ensure that the location is | 424 /// Set the location of the ouput directory, and ensure that the location is |
| 421 /// available on the file system. | 425 /// available on the file system. |
| 422 static void _ensureOutputDirectory(String outputDirectory, bool append) { | 426 static void _ensureOutputDirectory(String outputDirectory, bool append) { |
| 423 _outputDirectory = outputDirectory; | 427 _outputDirectory = outputDirectory; |
| 424 if (!append) { | 428 if (!append) { |
| 425 var dir = new Directory(_outputDirectory); | 429 var dir = new Directory(_outputDirectory); |
| 426 if (dir.existsSync()) dir.deleteSync(recursive: true); | 430 if (dir.existsSync()) dir.deleteSync(recursive: true); |
| 427 } | 431 } |
| 428 } | 432 } |
| 429 | 433 |
| 430 | 434 /// Helper accessor to determine the full pathname of the root of the dart |
| 435 /// checkout. | |
| 431 static String get _rootDirectory { | 436 static String get _rootDirectory { |
| 432 var scriptDir = path.absolute(path.dirname(Platform.script.toFilePath())); | 437 var scriptDir = path.absolute(path.dirname(Platform.script.toFilePath())); |
| 433 var root = scriptDir; | 438 var root = scriptDir; |
| 434 while(path.basename(root) != 'dart') { | 439 while(path.basename(root) != 'dart') { |
| 435 root = path.dirname(root); | 440 root = path.dirname(root); |
| 436 } | 441 } |
| 437 return root; | 442 return root; |
| 438 } | 443 } |
| 439 | 444 |
| 440 /// Analyzes set of libraries and provides a mirror system which can be used | 445 /// Analyzes set of libraries and provides a mirror system which can be used |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 465 }); | 470 }); |
| 466 } | 471 } |
| 467 | 472 |
| 468 /// For this run of docgen, determine the packageRoot value. | 473 /// For this run of docgen, determine the packageRoot value. |
| 469 /// | 474 /// |
| 470 /// If packageRoot is not explicitly passed, we examine the files we're | 475 /// If packageRoot is not explicitly passed, we examine the files we're |
| 471 /// documenting to attempt to find a package root. | 476 /// documenting to attempt to find a package root. |
| 472 static String _obtainPackageRoot(String packageRoot, bool parseSdk, | 477 static String _obtainPackageRoot(String packageRoot, bool parseSdk, |
| 473 List<String> files) { | 478 List<String> files) { |
| 474 if (packageRoot == null && !parseSdk) { | 479 if (packageRoot == null && !parseSdk) { |
| 475 // TODO(efortuna): This logic seems not very robust, but it's from the | |
| 476 // original version of the code, pre-refactor, so I'm leavingt it for now. | |
| 477 // Revisit to make more robust. | |
| 478 // TODO(efortuna): See lines 303-311 in | |
| 479 // https://codereview.chromium.org/116043013/diff/390001/pkg/docgen/lib/do cgen.dart | |
| 480 var type = FileSystemEntity.typeSync(files.first); | 480 var type = FileSystemEntity.typeSync(files.first); |
| 481 if (type == FileSystemEntityType.DIRECTORY) { | 481 if (type == FileSystemEntityType.DIRECTORY) { |
| 482 var files2 = listDir(files.first, recursive: true); | 482 var files2 = listDir(files.first, recursive: true); |
| 483 // Return '' means that there was no pubspec.yaml and therefor no p | 483 // Return '' means that there was no pubspec.yaml and therefor no p |
| 484 // ackageRoot. | 484 // ackageRoot. |
| 485 packageRoot = files2.firstWhere((f) => | 485 packageRoot = files2.firstWhere((f) => |
| 486 f.endsWith('${path.separator}pubspec.yaml'), orElse: () => ''); | 486 f.endsWith('${path.separator}pubspec.yaml'), orElse: () => ''); |
| 487 if (packageRoot != '') { | 487 if (packageRoot != '') { |
| 488 packageRoot = path.join(path.dirname(packageRoot), 'packages'); | 488 packageRoot = path.join(path.dirname(packageRoot), 'packages'); |
| 489 } | 489 } |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 563 var sdk = new List<Uri>(); | 563 var sdk = new List<Uri>(); |
| 564 LIBRARIES.forEach((String name, LibraryInfo info) { | 564 LIBRARIES.forEach((String name, LibraryInfo info) { |
| 565 if (info.documented) { | 565 if (info.documented) { |
| 566 sdk.add(Uri.parse('dart:$name')); | 566 sdk.add(Uri.parse('dart:$name')); |
| 567 logger.info('Add to SDK: ${sdk.last}'); | 567 logger.info('Add to SDK: ${sdk.last}'); |
| 568 } | 568 } |
| 569 }); | 569 }); |
| 570 return sdk; | 570 return sdk; |
| 571 } | 571 } |
| 572 | 572 |
| 573 /// Return true if this item and all of its owners are all visible. | |
| 573 static bool _isFullChainVisible(Indexable item) { | 574 static bool _isFullChainVisible(Indexable item) { |
| 574 // TODO: reconcile with isVisible. | 575 return _includePrivate || (!item.isPrivate && (item.owner != null ? |
| 575 // TODO: Also should be able to take MirrorBased items in general probably. | |
| 576 var result = _includePrivate || (!item.isPrivate && (item.owner != null ? | |
| 577 _isFullChainVisible(item.owner) : true)); | 576 _isFullChainVisible(item.owner) : true)); |
| 578 return result; | |
| 579 } | 577 } |
| 580 | 578 |
| 581 /// Currently left public for testing purposes. :-/ | 579 /// Currently left public for testing purposes. :-/ |
| 582 static Library generateLibrary(dart2js.Dart2JsLibraryMirror library) { | 580 static Library generateLibrary(dart2js.Dart2JsLibraryMirror library) { |
| 583 var result = new Library(library); | 581 var result = new Library(library); |
| 584 result._findPackage(library); | 582 result._findPackage(library); |
| 585 logger.fine('Generated library for ${result.name}'); | 583 logger.fine('Generated library for ${result.name}'); |
| 586 return result; | 584 return result; |
| 587 } | 585 } |
| 588 } | 586 } |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 640 map[owner.docName] = set; | 638 map[owner.docName] = set; |
| 641 _mirrorToDocgen[this.mirror.qualifiedName] = map; | 639 _mirrorToDocgen[this.mirror.qualifiedName] = map; |
| 642 } | 640 } |
| 643 | 641 |
| 644 /** Walk up the owner chain to find the owning library. */ | 642 /** Walk up the owner chain to find the owning library. */ |
| 645 Library _getOwningLibrary(Indexable indexable) { | 643 Library _getOwningLibrary(Indexable indexable) { |
| 646 if (indexable is Library) return indexable; | 644 if (indexable is Library) return indexable; |
| 647 return _getOwningLibrary(indexable.owner); | 645 return _getOwningLibrary(indexable.owner); |
| 648 } | 646 } |
| 649 | 647 |
| 650 static initializeTopLevelLibraries(MirrorSystem mirrorSystem) { | 648 static _initializeTopLevelLibraries(MirrorSystem mirrorSystem) { |
| 651 _sdkLibraries = mirrorSystem.libraries.values.where( | 649 _sdkLibraries = mirrorSystem.libraries.values.where( |
| 652 (each) => each.uri.scheme == 'dart'); | 650 (each) => each.uri.scheme == 'dart'); |
| 653 _coreLibrary = new Library(_sdkLibraries.singleWhere((lib) => | 651 _coreLibrary = new Library(_sdkLibraries.singleWhere((lib) => |
| 654 lib.uri.toString().startsWith('dart:core'))); | 652 lib.uri.toString().startsWith('dart:core'))); |
| 655 } | 653 } |
| 656 | 654 |
| 657 /// Returns this object's qualified name, but following the conventions | 655 /// Returns this object's qualified name, but following the conventions |
| 658 /// we're using in Dartdoc, which is that library names with dots in them | 656 /// we're using in Dartdoc, which is that library names with dots in them |
| 659 /// have them replaced with hyphens. | 657 /// have them replaced with hyphens. |
| 660 String get docName; | 658 String get docName; |
| 661 | 659 |
| 662 markdown.Node fixReferenceWithScope(String name) => null; | |
| 663 | |
| 664 /// Converts all [foo] references in comments to <a>libraryName.foo</a>. | 660 /// Converts all [foo] references in comments to <a>libraryName.foo</a>. |
| 665 markdown.Node fixReference(String name) { | 661 markdown.Node fixReference(String name) { |
| 666 // Attempt the look up the whole name up in the scope. | 662 // Attempt the look up the whole name up in the scope. |
| 667 String elementName = findElementInScope(name); | 663 String elementName = findElementInScope(name); |
| 668 if (elementName != null) { | 664 if (elementName != null) { |
| 669 return new markdown.Element.text('a', elementName); | 665 return new markdown.Element.text('a', elementName); |
| 670 } | 666 } |
| 671 return _fixComplexReference(name); | 667 return _fixComplexReference(name); |
| 672 } | 668 } |
| 673 | 669 |
| 674 /// Look for the specified name starting with the current member, and | 670 /// Look for the specified name starting with the current member, and |
| 675 /// progressively working outward to the current library scope. | 671 /// progressively working outward to the current library scope. |
| 676 String findElementInScope(String name) => | 672 String findElementInScope(String name) => |
| 677 _findElementInScope(name, packagePrefix); | 673 _findElementInScope(name, packagePrefix); |
| 678 | 674 |
| 675 /// For a given name, determine if we need to resolve it as a qualified name | |
| 676 /// or a simple name in the source mirors. | |
| 679 static determineLookupFunc(name) => name.contains('.') ? | 677 static determineLookupFunc(name) => name.contains('.') ? |
| 680 dart2js_util.lookupQualifiedInScope : | 678 dart2js_util.lookupQualifiedInScope : |
| 681 (mirror, name) => mirror.lookupInScope(name); | 679 (mirror, name) => mirror.lookupInScope(name); |
| 682 | 680 |
| 683 // The qualified name (for URL purposes) and the file name are the same, | 681 /// The reference to this element based on where it is printed as a |
| 684 // of the form packageName/ClassName or packageName/ClassName.methodName. | 682 /// documentation file and also the unique URL to refer to this item. |
| 685 // This defines both the URL and the directory structure. | 683 /// |
| 686 String get fileName { | 684 /// The qualified name (for URL purposes) and the file name are the same, |
| 687 return packagePrefix + ownerPrefix + name; | 685 /// of the form packageName/ClassName or packageName/ClassName.methodName. |
| 688 } | 686 /// This defines both the URL and the directory structure. |
| 687 String get fileName => packagePrefix + ownerPrefix + name; | |
| 689 | 688 |
| 689 /// The full docName of the owner element, appended with a '.' for this | |
| 690 /// object's name to be appended. | |
| 690 String get ownerPrefix => owner.docName != '' ? owner.docName + '.' : ''; | 691 String get ownerPrefix => owner.docName != '' ? owner.docName + '.' : ''; |
| 691 | 692 |
| 693 /// The prefix String to refer to the package that this item is in, for URLs | |
| 694 /// and comment resolution. | |
| 695 /// | |
| 696 /// The prefix can be prepended to a qualified name to get a fully unique | |
| 697 /// name among all packages. | |
| 692 String get packagePrefix => ''; | 698 String get packagePrefix => ''; |
| 693 | 699 |
| 694 /// Documentation comment with converted markdown. | 700 /// Documentation comment with converted markdown and all links resolved. |
| 695 String _comment; | 701 String _comment; |
| 696 | 702 |
| 703 /// Accessor to documentation comment with markdown converted to html and all | |
| 704 /// links resolved. | |
| 697 String get comment { | 705 String get comment { |
| 698 if (_comment != null) return _comment; | 706 if (_comment != null) return _comment; |
| 699 | 707 |
| 700 _comment = _commentToHtml(); | 708 _comment = _commentToHtml(); |
| 701 if (_comment.isEmpty) { | 709 if (_comment.isEmpty) { |
| 702 _comment = _mdnComment(); | 710 _comment = _mdnComment(); |
| 703 } | 711 } |
| 704 return _comment; | 712 return _comment; |
| 705 } | 713 } |
| 706 | 714 |
| 707 set comment(x) => _comment = x; | 715 set comment(x) => _comment = x; |
| 708 | 716 |
| 717 /// The simple name to refer to this item. | |
| 709 String get name => mirror.simpleName; | 718 String get name => mirror.simpleName; |
| 710 | 719 |
| 720 /// Accessor to the parent item that owns this item. | |
| 721 /// | |
| 722 /// "Owning" is defined as the object one scope-level above which this item | |
| 723 /// is defined. Ex: The owner for a top level class, would be its enclosing | |
| 724 /// library. The owner of a local variable in a method would be the enclosing | |
| 725 /// method. | |
| 711 Indexable get owner => new DummyMirror(mirror.owner); | 726 Indexable get owner => new DummyMirror(mirror.owner); |
| 712 | 727 |
| 713 /// Generates MDN comments from database.json. | 728 /// Generates MDN comments from database.json. |
| 714 String _mdnComment() { | 729 String _mdnComment(); |
| 715 //Check if MDN is loaded. | |
| 716 if (_mdn == null) { | |
| 717 // Reading in MDN related json file. | |
| 718 var root = _Generator._rootDirectory; | |
| 719 var mdnPath = path.join(root, 'utils/apidoc/mdn/database.json'); | |
| 720 _mdn = JSON.decode(new File(mdnPath).readAsStringSync()); | |
| 721 } | |
| 722 // TODO: refactor OOP | |
| 723 if (this is Library) return ''; | |
| 724 var domAnnotation = this.annotations.firstWhere( | |
| 725 (e) => e.mirror.qualifiedName == 'metadata.DomName', | |
| 726 orElse: () => null); | |
| 727 if (domAnnotation == null) return ''; | |
| 728 var domName = domAnnotation.parameters.single; | |
| 729 var parts = domName.split('.'); | |
| 730 if (parts.length == 2) return _mdnMemberComment(parts[0], parts[1]); | |
| 731 if (parts.length == 1) return _mdnTypeComment(parts[0]); | |
| 732 } | |
| 733 | 730 |
| 734 /// Generates the MDN Comment for variables and method DOM elements. | 731 /// Generates the MDN Comment for variables and method DOM elements. |
| 735 String _mdnMemberComment(String type, String member) { | 732 String _mdnMemberComment(String type, String member) { |
| 736 var mdnType = _mdn[type]; | 733 var mdnType = _mdn[type]; |
| 737 if (mdnType == null) return ''; | 734 if (mdnType == null) return ''; |
| 738 var mdnMember = mdnType['members'].firstWhere((e) => e['name'] == member, | 735 var mdnMember = mdnType['members'].firstWhere((e) => e['name'] == member, |
| 739 orElse: () => null); | 736 orElse: () => null); |
| 740 if (mdnMember == null) return ''; | 737 if (mdnMember == null) return ''; |
| 741 if (mdnMember['help'] == null || mdnMember['help'] == '') return ''; | 738 if (mdnMember['help'] == null || mdnMember['help'] == '') return ''; |
| 742 if (mdnMember['url'] == null) return ''; | 739 if (mdnMember['url'] == null) return ''; |
| 743 return _htmlMdn(mdnMember['help'], mdnMember['url']); | 740 return _htmlifyMdn(mdnMember['help'], mdnMember['url']); |
| 744 } | 741 } |
| 745 | 742 |
| 746 /// Generates the MDN Comment for class DOM elements. | 743 /// Generates the MDN Comment for class DOM elements. |
| 747 String _mdnTypeComment(String type) { | 744 String _mdnTypeComment(String type) { |
| 748 var mdnType = _mdn[type]; | 745 var mdnType = _mdn[type]; |
| 749 if (mdnType == null) return ''; | 746 if (mdnType == null) return ''; |
| 750 if (mdnType['summary'] == null || mdnType['summary'] == "") return ''; | 747 if (mdnType['summary'] == null || mdnType['summary'] == "") return ''; |
| 751 if (mdnType['srcUrl'] == null) return ''; | 748 if (mdnType['srcUrl'] == null) return ''; |
| 752 return _htmlMdn(mdnType['summary'], mdnType['srcUrl']); | 749 return _htmlifyMdn(mdnType['summary'], mdnType['srcUrl']); |
| 753 } | 750 } |
| 754 | 751 |
| 755 String _htmlMdn(String content, String url) { | 752 /// Encloses the given content in an MDN div and the original source link. |
| 753 String _htmlifyMdn(String content, String url) { | |
| 756 return '<div class="mdn">' + content.trim() + '<p class="mdn-note">' | 754 return '<div class="mdn">' + content.trim() + '<p class="mdn-note">' |
| 757 '<a href="' + url.trim() + '">from Mdn</a></p></div>'; | 755 '<a href="' + url.trim() + '">from Mdn</a></p></div>'; |
| 758 } | 756 } |
| 759 | 757 |
| 760 /// The type of this member to be used in index.txt. | 758 /// The type of this member to be used in index.txt. |
| 761 String get typeName => ''; | 759 String get typeName => ''; |
| 762 | 760 |
| 763 /// Creates a [Map] with this [Indexable]'s name and a preview comment. | 761 /// Creates a [Map] with this [Indexable]'s name and a preview comment. |
| 764 Map get previewMap { | 762 Map get previewMap { |
| 765 var finalMap = { 'name' : name, 'qualifiedName' : qualifiedName }; | 763 var finalMap = { 'name' : name, 'qualifiedName' : qualifiedName }; |
| 766 if (comment != '') { | 764 if (comment != '') { |
| 767 var index = comment.indexOf('</p>'); | 765 var index = comment.indexOf('</p>'); |
| 768 finalMap['preview'] = '${comment.substring(0, index)}</p>'; | 766 finalMap['preview'] = '${comment.substring(0, index)}</p>'; |
| 769 } | 767 } |
| 770 return finalMap; | 768 return finalMap; |
| 771 } | 769 } |
| 772 | 770 |
| 773 String _getCommentText() { | 771 /// Accessor to obtain the raw comment text for a given item, _without_ any |
| 772 /// of the links resolved. | |
| 773 String get _commentText { | |
| 774 String commentText; | 774 String commentText; |
| 775 mirror.metadata.forEach((metadata) { | 775 mirror.metadata.forEach((metadata) { |
| 776 if (metadata is CommentInstanceMirror) { | 776 if (metadata is CommentInstanceMirror) { |
| 777 CommentInstanceMirror comment = metadata; | 777 CommentInstanceMirror comment = metadata; |
| 778 if (comment.isDocComment) { | 778 if (comment.isDocComment) { |
| 779 if (commentText == null) { | 779 if (commentText == null) { |
| 780 commentText = comment.trimmedText; | 780 commentText = comment.trimmedText; |
| 781 } else { | 781 } else { |
| 782 commentText = '$commentText\n${comment.trimmedText}'; | 782 commentText = '$commentText\n${comment.trimmedText}'; |
| 783 } | 783 } |
| 784 } | 784 } |
| 785 } | 785 } |
| 786 }); | 786 }); |
| 787 return commentText; | 787 return commentText; |
| 788 } | 788 } |
| 789 | 789 |
| 790 /// Returns any documentation comments associated with a mirror with | 790 /// Returns any documentation comments associated with a mirror with |
| 791 /// simple markdown converted to html. | 791 /// simple markdown converted to html. |
| 792 /// | 792 /// |
| 793 /// By default we resolve any comment references within our own scope. | 793 /// By default we resolve any comment references within our own scope. |
| 794 /// However, if a method is inherited, we want the inherited comments, but | 794 /// However, if a method is inherited, we want the inherited comments, but |
| 795 /// links to the subclasses's version of the methods. | 795 /// links to the subclasses's version of the methods. |
| 796 String _commentToHtml([Indexable resolvingScope]) { | 796 String _commentToHtml([Indexable resolvingScope]) { |
| 797 if (resolvingScope == null) resolvingScope = this; | 797 if (resolvingScope == null) resolvingScope = this; |
| 798 var commentText = _getCommentText(); | 798 var commentText = _commentText; |
| 799 _unresolvedComment = commentText; | 799 _unresolvedComment = commentText; |
| 800 | 800 |
| 801 var linkResolver = (name) => resolvingScope.fixReferenceWithScope(name); | 801 var linkResolver = (name) => resolvingScope.fixReference(name); |
| 802 commentText = commentText == null ? '' : | 802 commentText = commentText == null ? '' : |
| 803 markdown.markdownToHtml(commentText.trim(), linkResolver: linkResolver, | 803 markdown.markdownToHtml(commentText.trim(), linkResolver: linkResolver, |
| 804 inlineSyntaxes: _MARKDOWN_SYNTAXES); | 804 inlineSyntaxes: _MARKDOWN_SYNTAXES); |
| 805 return commentText; | 805 return commentText; |
| 806 } | 806 } |
| 807 | 807 |
| 808 /// Returns a map of [Variable] objects constructed from [mirrorMap]. | 808 /// Returns a map of [Variable] objects constructed from [mirrorMap]. |
| 809 /// The optional parameter [containingLibrary] is contains data for variables | 809 /// The optional parameter [containingLibrary] is contains data for variables |
| 810 /// defined at the top level of a library (potentially for exporting | 810 /// defined at the top level of a library (potentially for exporting |
| 811 /// purposes). | 811 /// purposes). |
| 812 Map<String, Variable> _createVariables(Map<String, VariableMirror> mirrorMap, | 812 Map<String, Variable> _createVariables(Map<String, VariableMirror> mirrorMap, |
| 813 Indexable owner) { | 813 Indexable owner) { |
| 814 var data = {}; | 814 var data = {}; |
| 815 // TODO(janicejl): When map to map feature is created, replace the below | 815 // TODO(janicejl): When map to map feature is created, replace the below |
| 816 // with a filter. Issue(#9590). | 816 // with a filter. Issue(#9590). |
| 817 mirrorMap.forEach((String mirrorName, VariableMirror mirror) { | 817 mirrorMap.forEach((String mirrorName, VariableMirror mirror) { |
| 818 if (_Generator._includePrivate || !_isHidden(mirror)) { | 818 if (_Generator._includePrivate || !_isHidden(mirror)) { |
| 819 var variable = new Variable(mirrorName, mirror, owner); | 819 data[mirrorName] = new Variable(mirrorName, mirror, owner); |
| 820 entityMap[variable.docName] = variable; | |
| 821 data[mirrorName] = entityMap[variable.docName]; | |
| 822 } | 820 } |
| 823 }); | 821 }); |
| 824 return data; | 822 return data; |
| 825 } | 823 } |
| 826 | 824 |
| 827 /// Returns a map of [Method] objects constructed from [mirrorMap]. | 825 /// Returns a map of [Method] objects constructed from [mirrorMap]. |
| 828 /// The optional parameter [containingLibrary] is contains data for variables | 826 /// The optional parameter [containingLibrary] is contains data for variables |
| 829 /// defined at the top level of a library (potentially for exporting | 827 /// defined at the top level of a library (potentially for exporting |
| 830 /// purposes). | 828 /// purposes). |
| 831 Map<String, Method> _createMethods(Map<String, MethodMirror> mirrorMap, | 829 Map<String, Method> _createMethods(Map<String, MethodMirror> mirrorMap, |
| 832 Indexable owner) { | 830 Indexable owner) { |
| 833 var group = new Map<String, Method>(); | 831 var group = new Map<String, Method>(); |
| 834 mirrorMap.forEach((String mirrorName, MethodMirror mirror) { | 832 mirrorMap.forEach((String mirrorName, MethodMirror mirror) { |
| 835 if (_Generator._includePrivate || !mirror.isPrivate) { | 833 if (_Generator._includePrivate || !mirror.isPrivate) { |
| 836 var method = new Method(mirror, owner); | 834 group[mirror.simpleName] = new Method(mirror, owner); |
| 837 entityMap[method.docName] = method; | |
| 838 group[mirror.simpleName] = method; | |
| 839 } | 835 } |
| 840 }); | 836 }); |
| 841 return group; | 837 return group; |
| 842 } | 838 } |
| 843 | 839 |
| 844 /// Returns a map of [Parameter] objects constructed from [mirrorList]. | 840 /// Returns a map of [Parameter] objects constructed from [mirrorList]. |
| 845 Map<String, Parameter> _createParameters(List<ParameterMirror> mirrorList, | 841 Map<String, Parameter> _createParameters(List<ParameterMirror> mirrorList, |
| 846 Indexable owner) { | 842 Indexable owner) { |
| 847 var data = {}; | 843 var data = {}; |
| 848 mirrorList.forEach((ParameterMirror mirror) { | 844 mirrorList.forEach((ParameterMirror mirror) { |
| 849 data[mirror.simpleName] = new Parameter(mirror, _getOwningLibrary(owner)); | 845 data[mirror.simpleName] = new Parameter(mirror, _getOwningLibrary(owner)); |
| 850 }); | 846 }); |
| 851 return data; | 847 return data; |
| 852 } | 848 } |
| 853 | 849 |
| 854 /// Returns a map of [Generic] objects constructed from the class mirror. | 850 /// Returns a map of [Generic] objects constructed from the class mirror. |
| 855 Map<String, Generic> _createGenerics(ClassMirror mirror) { | 851 Map<String, Generic> _createGenerics(ClassMirror mirror) { |
| 856 return new Map.fromIterable(mirror.typeVariables, | 852 return new Map.fromIterable(mirror.typeVariables, |
| 857 key: (e) => e.toString(), | 853 key: (e) => e.toString(), |
| 858 value: (e) => new Generic(e)); | 854 value: (e) => new Generic(e)); |
| 859 } | 855 } |
| 860 | 856 |
| 861 /// Return an informative [Object.toString] for debugging. | 857 /// Return an informative [Object.toString] for debugging. |
| 862 String toString() => "${super.toString()}(${name.toString()})"; | 858 String toString() => "${super.toString()}(${name.toString()})"; |
| 863 | 859 |
| 864 /// Return a map representation of this type. | 860 /// Return a map representation of this type. |
| 865 Map toMap() {} | 861 Map toMap(); |
| 866 | |
| 867 | 862 |
| 868 /// A declaration is private if itself is private, or the owner is private. | 863 /// A declaration is private if itself is private, or the owner is private. |
| 869 // Issue(12202) - A declaration is public even if it's owner is private. | 864 // Issue(12202) - A declaration is public even if it's owner is private. |
| 870 bool _isHidden(DeclarationMirror mirror) { | 865 bool _isHidden(DeclarationMirror mirror) { |
| 871 if (mirror is LibraryMirror) { | 866 if (mirror is LibraryMirror) { |
| 872 return _isLibraryPrivate(mirror); | 867 return _isLibraryPrivate(mirror); |
| 873 } else if (mirror.owner is LibraryMirror) { | 868 } else if (mirror.owner is LibraryMirror) { |
| 874 return (mirror.isPrivate || _isLibraryPrivate(mirror.owner) | 869 return (mirror.isPrivate || _isLibraryPrivate(mirror.owner) |
| 875 || mirror.isNameSynthetic); | 870 || mirror.isNameSynthetic); |
| 876 } else { | 871 } else { |
| 877 return (mirror.isPrivate || _isHidden(mirror.owner) | 872 return (mirror.isPrivate || _isHidden(mirror.owner) |
| 878 || owner.mirror.isNameSynthetic); | 873 || owner.mirror.isNameSynthetic); |
| 879 } | 874 } |
| 880 } | 875 } |
| 881 | 876 |
| 882 /// Returns true if a library name starts with an underscore, and false | 877 /// Returns true if a library name starts with an underscore, and false |
| 883 /// otherwise. | 878 /// otherwise. |
| 884 /// | 879 /// |
| 885 /// An example that starts with _ is _js_helper. | 880 /// An example that starts with _ is _js_helper. |
| 886 /// An example that contains ._ is dart._collection.dev | 881 /// An example that contains ._ is dart._collection.dev |
| 887 // This is because LibraryMirror.isPrivate returns `false` all the time. | |
| 888 bool _isLibraryPrivate(LibraryMirror mirror) { | 882 bool _isLibraryPrivate(LibraryMirror mirror) { |
| 883 // This method is needed because LibraryMirror.isPrivate returns `false` all | |
| 884 // the time. | |
| 889 var sdkLibrary = LIBRARIES[mirror.simpleName]; | 885 var sdkLibrary = LIBRARIES[mirror.simpleName]; |
| 890 if (sdkLibrary != null) { | 886 if (sdkLibrary != null) { |
| 891 return !sdkLibrary.documented; | 887 return !sdkLibrary.documented; |
| 892 } else if (mirror.simpleName.startsWith('_') || | 888 } else if (mirror.simpleName.startsWith('_') || |
| 893 mirror.simpleName.contains('._')) { | 889 mirror.simpleName.contains('._')) { |
| 894 return true; | 890 return true; |
| 895 } | 891 } |
| 896 return false; | 892 return false; |
| 897 } | 893 } |
| 898 | 894 |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1004 return packagePrefix + result.docName; | 1000 return packagePrefix + result.docName; |
| 1005 } else { | 1001 } else { |
| 1006 return result.packagePrefix + result.docName; | 1002 return result.packagePrefix + result.docName; |
| 1007 } | 1003 } |
| 1008 } | 1004 } |
| 1009 } | 1005 } |
| 1010 } | 1006 } |
| 1011 return null; | 1007 return null; |
| 1012 } | 1008 } |
| 1013 | 1009 |
| 1014 Map expandMethodMap(Map<String, Method> mapToExpand) => { | 1010 /// Expand the method map [mapToExpand] into a more detailed map that |
| 1015 'setters': recurseMap(_filterMap(new Map(), mapToExpand, | 1011 /// separates out setters, getters, constructors, operators, and methods. |
| 1012 Map _expandMethodMap(Map<String, Method> mapToExpand) => { | |
| 1013 'setters': recurseMap(_filterMap(mapToExpand, | |
| 1016 (key, val) => val.mirror.isSetter)), | 1014 (key, val) => val.mirror.isSetter)), |
| 1017 'getters': recurseMap(_filterMap(new Map(), mapToExpand, | 1015 'getters': recurseMap(_filterMap(mapToExpand, |
| 1018 (key, val) => val.mirror.isGetter)), | 1016 (key, val) => val.mirror.isGetter)), |
| 1019 'constructors': recurseMap(_filterMap(new Map(), mapToExpand, | 1017 'constructors': recurseMap(_filterMap(mapToExpand, |
| 1020 (key, val) => val.mirror.isConstructor)), | 1018 (key, val) => val.mirror.isConstructor)), |
| 1021 'operators': recurseMap(_filterMap(new Map(), mapToExpand, | 1019 'operators': recurseMap(_filterMap(mapToExpand, |
| 1022 (key, val) => val.mirror.isOperator)), | 1020 (key, val) => val.mirror.isOperator)), |
| 1023 'methods': recurseMap(_filterMap(new Map(), mapToExpand, | 1021 'methods': recurseMap(_filterMap(mapToExpand, |
| 1024 (key, val) => val.mirror.isRegularMethod && !val.mirror.isOperator)) | 1022 (key, val) => val.mirror.isRegularMethod && !val.mirror.isOperator)) |
| 1025 }; | 1023 }; |
| 1026 | 1024 |
| 1027 /// Transforms the map by calling toMap on each value in it. | 1025 /// Transforms the map by calling toMap on each value in it. |
| 1028 Map recurseMap(Map inputMap) { | 1026 Map recurseMap(Map inputMap) { |
| 1029 var outputMap = {}; | 1027 var outputMap = {}; |
| 1030 inputMap.forEach((key, value) { | 1028 inputMap.forEach((key, value) { |
| 1031 if (value is Map) { | 1029 if (value is Map) { |
| 1032 outputMap[key] = recurseMap(value); | 1030 outputMap[key] = recurseMap(value); |
| 1033 } else { | 1031 } else { |
| 1034 outputMap[key] = value.toMap(); | 1032 outputMap[key] = value.toMap(); |
| 1035 } | 1033 } |
| 1036 }); | 1034 }); |
| 1037 return outputMap; | 1035 return outputMap; |
| 1038 } | 1036 } |
| 1039 | 1037 |
| 1040 Map _filterMap(exported, map, test) { | 1038 Map _filterMap(Map map, Function test) { |
| 1039 var exported = new Map(); | |
| 1041 map.forEach((key, value) { | 1040 map.forEach((key, value) { |
| 1042 if (test(key, value)) exported[key] = value; | 1041 if (test(key, value)) exported[key] = value; |
| 1043 }); | 1042 }); |
| 1044 return exported; | 1043 return exported; |
| 1045 } | 1044 } |
| 1046 | 1045 |
| 1047 bool get _isVisible => _Generator._includePrivate || !isPrivate; | 1046 /// Accessor to determine if this item and all of its owners are visible. |
| 1047 bool get _isVisible => _Generator._isFullChainVisible(this); | |
| 1048 | 1048 |
| 1049 /// Given a Dart2jsMirror, find the corresponding Docgen [MirrorBased] object. | 1049 /// Given a Dart2jsMirror, find the corresponding Docgen [MirrorBased] object. |
| 1050 /// | 1050 /// |
| 1051 /// We have this global lookup function to avoid re-implementing looking up | 1051 /// We have this global lookup function to avoid re-implementing looking up |
| 1052 /// the scoping rules for comment resolution here (it is currently done in | 1052 /// the scoping rules for comment resolution here (it is currently done in |
| 1053 /// mirrors). If no corresponding MirrorBased object is found, we return a | 1053 /// mirrors). If no corresponding MirrorBased object is found, we return a |
| 1054 /// [DummyMirror] that simply returns the original mirror's qualifiedName | 1054 /// [DummyMirror] that simply returns the original mirror's qualifiedName |
| 1055 /// while behaving like a MirrorBased object. | 1055 /// while behaving like a MirrorBased object. |
| 1056 static Indexable getDocgenObject(DeclarationMirror mirror, | 1056 static Indexable getDocgenObject(DeclarationMirror mirror, |
| 1057 [Indexable owner]) { | 1057 [Indexable owner]) { |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 1083 } | 1083 } |
| 1084 } | 1084 } |
| 1085 | 1085 |
| 1086 if (results.length > 0) { | 1086 if (results.length > 0) { |
| 1087 // This might occur if we didn't specify an "owner." | 1087 // This might occur if we didn't specify an "owner." |
| 1088 return results.first; | 1088 return results.first; |
| 1089 } | 1089 } |
| 1090 return new DummyMirror(mirror, owner); | 1090 return new DummyMirror(mirror, owner); |
| 1091 } | 1091 } |
| 1092 | 1092 |
| 1093 /// Returns true if [mirror] is the correct type of mirror that this Docgen | |
| 1094 /// object wraps. (Workaround for the fact that Types are not first class.) | |
| 1093 bool _isValidMirror(DeclarationMirror mirror); | 1095 bool _isValidMirror(DeclarationMirror mirror); |
| 1094 } | 1096 } |
| 1095 | 1097 |
| 1096 /// A class containing contents of a Dart library. | 1098 /// A class containing contents of a Dart library. |
| 1097 class Library extends Indexable { | 1099 class Library extends Indexable { |
| 1098 | 1100 |
| 1099 /// Top-level variables in the library. | 1101 /// Top-level variables in the library. |
| 1100 Map<String, Variable> variables; | 1102 Map<String, Variable> variables; |
| 1101 | 1103 |
| 1102 /// Top-level functions in the library. | 1104 /// Top-level functions in the library. |
| 1103 Map<String, Method> functions; | 1105 Map<String, Method> functions; |
| 1104 | 1106 |
| 1105 Map<String, Class> classes = {}; | 1107 Map<String, Class> classes = {}; |
| 1106 Map<String, Typedef> typedefs = {}; | 1108 Map<String, Typedef> typedefs = {}; |
| 1107 Map<String, Class> errors = {}; | 1109 Map<String, Class> errors = {}; |
| 1108 | 1110 |
| 1109 String packageName = ''; | 1111 String packageName = ''; |
| 1110 bool hasBeenCheckedForPackage = false; | 1112 bool _hasBeenCheckedForPackage = false; |
| 1111 String packageIntro; | 1113 String packageIntro; |
| 1112 | 1114 |
| 1113 /// Returns the [Library] for the given [mirror] if it has already been | 1115 /// Returns the [Library] for the given [mirror] if it has already been |
| 1114 /// created, else creates it. | 1116 /// created, else creates it. |
| 1115 factory Library(LibraryMirror mirror) { | 1117 factory Library(LibraryMirror mirror) { |
| 1116 var library = Indexable.getDocgenObject(mirror); | 1118 var library = Indexable.getDocgenObject(mirror); |
| 1117 if (library is DummyMirror) { | 1119 if (library is DummyMirror) { |
| 1118 library = new Library._(mirror); | 1120 library = new Library._(mirror); |
| 1119 } | 1121 } |
| 1120 return library; | 1122 return library; |
| 1121 } | 1123 } |
| 1122 | 1124 |
| 1123 Library._(LibraryMirror libraryMirror) : super(libraryMirror) { | 1125 Library._(LibraryMirror libraryMirror) : super(libraryMirror) { |
| 1124 var exported = _calcExportedItems(libraryMirror); | 1126 var exported = _calcExportedItems(libraryMirror); |
| 1125 var exportedClasses = exported['classes']..addAll(libraryMirror.classes); | 1127 var exportedClasses = exported['classes']..addAll(libraryMirror.classes); |
| 1126 _findPackage(mirror); | 1128 _findPackage(mirror); |
| 1127 classes = {}; | 1129 classes = {}; |
| 1128 typedefs = {}; | 1130 typedefs = {}; |
| 1129 errors = {}; | 1131 errors = {}; |
| 1130 exportedClasses.forEach((String mirrorName, ClassMirror classMirror) { | 1132 exportedClasses.forEach((String mirrorName, ClassMirror classMirror) { |
| 1131 if (classMirror.isTypedef) { | 1133 if (classMirror.isTypedef) { |
| 1132 // This is actually a Dart2jsTypedefMirror, and it does define value, | 1134 // This is actually a Dart2jsTypedefMirror, and it does define value, |
| 1133 // but we don't have visibility to that type. | 1135 // but we don't have visibility to that type. |
| 1134 var mirror = classMirror; | 1136 var mirror = classMirror; |
| 1135 if (_Generator._includePrivate || !mirror.isPrivate) { | 1137 if (_Generator._includePrivate || !mirror.isPrivate) { |
| 1136 var aTypedef = new Typedef(mirror, this); | 1138 typedefs[mirror.simpleName] = new Typedef(mirror, this); |
| 1137 entityMap[Indexable.getDocgenObject(mirror).docName] = aTypedef; | |
| 1138 typedefs[mirror.simpleName] = aTypedef; | |
| 1139 } | 1139 } |
| 1140 } else { | 1140 } else { |
| 1141 var clazz = new Class(classMirror, this); | 1141 var clazz = new Class(classMirror, this); |
| 1142 | 1142 |
| 1143 if (clazz.isError()) { | 1143 if (clazz.isError()) { |
| 1144 errors[classMirror.simpleName] = clazz; | 1144 errors[classMirror.simpleName] = clazz; |
| 1145 } else if (classMirror.isClass) { | 1145 } else if (classMirror.isClass) { |
| 1146 classes[classMirror.simpleName] = clazz; | 1146 classes[classMirror.simpleName] = clazz; |
| 1147 } else { | 1147 } else { |
| 1148 throw new ArgumentError( | 1148 throw new ArgumentError( |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 1162 var lookupFunc = Indexable.determineLookupFunc(name); | 1162 var lookupFunc = Indexable.determineLookupFunc(name); |
| 1163 var libraryScope = lookupFunc(mirror, name); | 1163 var libraryScope = lookupFunc(mirror, name); |
| 1164 if (libraryScope != null) { | 1164 if (libraryScope != null) { |
| 1165 var result = Indexable.getDocgenObject(libraryScope, this); | 1165 var result = Indexable.getDocgenObject(libraryScope, this); |
| 1166 if (result is DummyMirror) return packagePrefix + result.docName; | 1166 if (result is DummyMirror) return packagePrefix + result.docName; |
| 1167 return result.packagePrefix + result.docName; | 1167 return result.packagePrefix + result.docName; |
| 1168 } | 1168 } |
| 1169 return super.findElementInScope(name); | 1169 return super.findElementInScope(name); |
| 1170 } | 1170 } |
| 1171 | 1171 |
| 1172 String _mdnComment() => ''; | |
| 1173 | |
| 1172 /// For a library's [mirror], determine the name of the package (if any) we | 1174 /// For a library's [mirror], determine the name of the package (if any) we |
| 1173 /// believe it came from (because of its file URI). | 1175 /// believe it came from (because of its file URI). |
| 1174 /// | 1176 /// |
| 1175 /// If no package could be determined, we return an empty string. | 1177 /// If no package could be determined, we return an empty string. |
| 1176 String _findPackage(LibraryMirror mirror) { | 1178 String _findPackage(LibraryMirror mirror) { |
| 1177 if (mirror == null) return ''; | 1179 if (mirror == null) return ''; |
| 1178 if (hasBeenCheckedForPackage) return packageName; | 1180 if (_hasBeenCheckedForPackage) return packageName; |
| 1179 hasBeenCheckedForPackage = true; | 1181 _hasBeenCheckedForPackage = true; |
| 1180 if (mirror.uri.scheme != 'file') return ''; | 1182 if (mirror.uri.scheme != 'file') return ''; |
| 1181 // We assume that we are documenting only libraries under package/lib | 1183 // We assume that we are documenting only libraries under package/lib |
| 1182 packageName = _packageName(mirror); | 1184 packageName = _packageName(mirror); |
| 1183 // Associate the package readme with all the libraries. This is a bit | 1185 // Associate the package readme with all the libraries. This is a bit |
| 1184 // wasteful, but easier than trying to figure out which partial match | 1186 // wasteful, but easier than trying to figure out which partial match |
| 1185 // is best. | 1187 // is best. |
| 1186 packageIntro = _packageIntro(_getRootdir(mirror)); | 1188 packageIntro = _packageIntro(_getRootdir(mirror)); |
| 1187 return packageName; | 1189 return packageName; |
| 1188 } | 1190 } |
| 1189 | 1191 |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 1214 if (mirror.uri.scheme != 'file') return ''; | 1216 if (mirror.uri.scheme != 'file') return ''; |
| 1215 var rootdir = _getRootdir(mirror); | 1217 var rootdir = _getRootdir(mirror); |
| 1216 var pubspecName = path.join(rootdir, 'pubspec.yaml'); | 1218 var pubspecName = path.join(rootdir, 'pubspec.yaml'); |
| 1217 File pubspec = new File(pubspecName); | 1219 File pubspec = new File(pubspecName); |
| 1218 if (!pubspec.existsSync()) return ''; | 1220 if (!pubspec.existsSync()) return ''; |
| 1219 var contents = pubspec.readAsStringSync(); | 1221 var contents = pubspec.readAsStringSync(); |
| 1220 var spec = loadYaml(contents); | 1222 var spec = loadYaml(contents); |
| 1221 return spec["name"]; | 1223 return spec["name"]; |
| 1222 } | 1224 } |
| 1223 | 1225 |
| 1224 markdown.Node fixReferenceWithScope(String name) => fixReference(name); | |
| 1225 | |
| 1226 String get packagePrefix => packageName == null || packageName.isEmpty ? | 1226 String get packagePrefix => packageName == null || packageName.isEmpty ? |
| 1227 '' : '$packageName/'; | 1227 '' : '$packageName/'; |
| 1228 | 1228 |
| 1229 Map get previewMap { | 1229 Map get previewMap { |
| 1230 var basic = super.previewMap; | 1230 var basic = super.previewMap; |
| 1231 basic['packageName'] = packageName; | 1231 basic['packageName'] = packageName; |
| 1232 if (packageIntro != null) { | 1232 if (packageIntro != null) { |
| 1233 basic['packageIntro'] = packageIntro; | 1233 basic['packageIntro'] = packageIntro; |
| 1234 } | 1234 } |
| 1235 return basic; | 1235 return basic; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1295 // library. Ex: "export foo show bar" | 1295 // library. Ex: "export foo show bar" |
| 1296 // Otherwise, add all items, and then remove the hidden ones. | 1296 // Otherwise, add all items, and then remove the hidden ones. |
| 1297 // Ex: "export foo hide bar" | 1297 // Ex: "export foo hide bar" |
| 1298 _populateExports(export, | 1298 _populateExports(export, |
| 1299 export.combinators.any((combinator) => combinator.isShow)); | 1299 export.combinators.any((combinator) => combinator.isShow)); |
| 1300 } | 1300 } |
| 1301 return exports; | 1301 return exports; |
| 1302 } | 1302 } |
| 1303 | 1303 |
| 1304 /// Checks if the given name is a key for any of the Class Maps. | 1304 /// Checks if the given name is a key for any of the Class Maps. |
| 1305 bool containsKey(String name) { | 1305 bool containsKey(String name) => |
| 1306 return classes.containsKey(name) || errors.containsKey(name); | 1306 classes.containsKey(name) || errors.containsKey(name); |
| 1307 } | |
| 1308 | 1307 |
| 1309 /// Generates a map describing the [Library] object. | 1308 /// Generates a map describing the [Library] object. |
| 1310 Map toMap() => { | 1309 Map toMap() => { |
| 1311 'name': name, | 1310 'name': name, |
| 1312 'qualifiedName': qualifiedName, | 1311 'qualifiedName': qualifiedName, |
| 1313 'comment': comment, | 1312 'comment': comment, |
| 1314 'variables': recurseMap(variables), | 1313 'variables': recurseMap(variables), |
| 1315 'functions': expandMethodMap(functions), | 1314 'functions': _expandMethodMap(functions), |
| 1316 'classes': { | 1315 'classes': { |
| 1317 'class': classes.values.where((c) => c._isVisible) | 1316 'class': classes.values.where((c) => c._isVisible) |
| 1318 .map((e) => e.previewMap).toList(), | 1317 .map((e) => e.previewMap).toList(), |
| 1319 'typedef': recurseMap(typedefs), | 1318 'typedef': recurseMap(typedefs), |
| 1320 'error': errors.values.where((e) => e._isVisible) | 1319 'error': errors.values.where((e) => e._isVisible) |
| 1321 .map((e) => e.previewMap).toList() | 1320 .map((e) => e.previewMap).toList() |
| 1322 }, | 1321 }, |
| 1323 'packageName': packageName, | 1322 'packageName': packageName, |
| 1324 'packageIntro' : packageIntro | 1323 'packageIntro' : packageIntro |
| 1325 }; | 1324 }; |
| 1326 | 1325 |
| 1327 String get typeName => 'library'; | 1326 String get typeName => 'library'; |
| 1328 | 1327 |
| 1329 bool _isValidMirror(DeclarationMirror mirror) => mirror is LibraryMirror; | 1328 bool _isValidMirror(DeclarationMirror mirror) => mirror is LibraryMirror; |
| 1330 } | 1329 } |
| 1331 | 1330 |
| 1332 abstract class OwnedIndexable extends Indexable { | 1331 abstract class OwnedIndexable extends Indexable { |
| 1332 /// The object one scope-level above which this item is defined. | |
| 1333 /// | |
| 1334 /// Ex: The owner for a top level class, would be its enclosing library. | |
| 1335 /// The owner of a local variable in a method would be the enclosing method. | |
| 1333 Indexable owner; | 1336 Indexable owner; |
| 1334 | 1337 |
| 1338 /// List of the meta annotations on this item. | |
| 1339 List<Annotation> annotations; | |
| 1340 | |
| 1335 /// Returns this object's qualified name, but following the conventions | 1341 /// Returns this object's qualified name, but following the conventions |
| 1336 /// we're using in Dartdoc, which is that library names with dots in them | 1342 /// we're using in Dartdoc, which is that library names with dots in them |
| 1337 /// have them replaced with hyphens. | 1343 /// have them replaced with hyphens. |
| 1338 String get docName => owner.docName + '.' + mirror.simpleName; | 1344 String get docName => owner.docName + '.' + mirror.simpleName; |
| 1339 | 1345 |
| 1340 OwnedIndexable(DeclarationMirror mirror, this.owner) : super(mirror); | 1346 OwnedIndexable(DeclarationMirror mirror, this.owner) : super(mirror); |
| 1347 | |
| 1348 /// Generates MDN comments from database.json. | |
| 1349 String _mdnComment() { | |
| 1350 //Check if MDN is loaded. | |
| 1351 if (Indexable._mdn == null) { | |
| 1352 // Reading in MDN related json file. | |
| 1353 var root = _Generator._rootDirectory; | |
| 1354 var mdnPath = path.join(root, 'utils/apidoc/mdn/database.json'); | |
| 1355 Indexable._mdn = JSON.decode(new File(mdnPath).readAsStringSync()); | |
| 1356 } | |
| 1357 var domAnnotation = this.annotations.firstWhere( | |
| 1358 (e) => e.mirror.qualifiedName == 'metadata.DomName', | |
| 1359 orElse: () => null); | |
| 1360 if (domAnnotation == null) return ''; | |
| 1361 var domName = domAnnotation.parameters.single; | |
| 1362 var parts = domName.split('.'); | |
| 1363 if (parts.length == 2) return _mdnMemberComment(parts[0], parts[1]); | |
| 1364 if (parts.length == 1) return _mdnTypeComment(parts[0]); | |
| 1365 } | |
| 1341 } | 1366 } |
| 1342 | 1367 |
| 1343 /// A class containing contents of a Dart class. | 1368 /// A class containing contents of a Dart class. |
| 1344 class Class extends OwnedIndexable implements Comparable { | 1369 class Class extends OwnedIndexable implements Comparable { |
| 1345 | 1370 |
| 1346 /// List of the names of interfaces that this class implements. | 1371 /// List of the names of interfaces that this class implements. |
| 1347 List<Class> interfaces = []; | 1372 List<Class> interfaces = []; |
| 1348 | 1373 |
| 1349 /// Names of classes that extends or implements this class. | 1374 /// Names of classes that extends or implements this class. |
| 1350 Set<Class> subclasses = new Set<Class>(); | 1375 Set<Class> subclasses = new Set<Class>(); |
| 1351 | 1376 |
| 1352 /// Top-level variables in the class. | 1377 /// Top-level variables in the class. |
| 1353 Map<String, Variable> variables; | 1378 Map<String, Variable> variables; |
| 1354 | 1379 |
| 1355 /// Inherited variables in the class. | 1380 /// Inherited variables in the class. |
| 1356 Map<String, Variable> inheritedVariables; | 1381 Map<String, Variable> inheritedVariables; |
| 1357 | 1382 |
| 1358 /// Methods in the class. | 1383 /// Methods in the class. |
| 1359 Map<String, Method> methods; | 1384 Map<String, Method> methods; |
| 1360 | 1385 |
| 1361 Map<String, Method> inheritedMethods; | 1386 Map<String, Method> inheritedMethods; |
| 1362 | 1387 |
| 1363 /// Generic infomation about the class. | 1388 /// Generic infomation about the class. |
| 1364 Map<String, Generic> generics; | 1389 Map<String, Generic> generics; |
| 1365 | 1390 |
| 1366 Class superclass; | 1391 Class superclass; |
| 1367 bool isAbstract; | 1392 bool isAbstract; |
| 1368 | 1393 |
| 1369 /// List of the meta annotations on the class. | |
| 1370 List<Annotation> annotations; | |
| 1371 | |
| 1372 /// Make sure that we don't check for inherited comments more than once. | 1394 /// Make sure that we don't check for inherited comments more than once. |
| 1373 bool _commentsEnsured = false; | 1395 bool _commentsEnsured = false; |
| 1374 | 1396 |
| 1375 /// Returns the [Class] for the given [mirror] if it has already been created, | 1397 /// Returns the [Class] for the given [mirror] if it has already been created, |
| 1376 /// else creates it. | 1398 /// else creates it. |
| 1377 factory Class(ClassMirror mirror, Library owner) { | 1399 factory Class(ClassMirror mirror, Library owner) { |
| 1378 var clazz = Indexable.getDocgenObject(mirror, owner); | 1400 var clazz = Indexable.getDocgenObject(mirror, owner); |
| 1379 if (clazz is DummyMirror) { | 1401 if (clazz is DummyMirror) { |
| 1380 clazz = new Class._(mirror, owner); | 1402 clazz = new Class._(mirror, owner); |
| 1381 entityMap[clazz.docName] = clazz; | |
| 1382 } | 1403 } |
| 1383 return clazz; | 1404 return clazz; |
| 1384 } | 1405 } |
| 1385 | 1406 |
| 1386 /// Called when we are constructing a superclass or interface class, but it | 1407 /// Called when we are constructing a superclass or interface class, but it |
| 1387 /// is not known if it belongs to the same owner as the original class. In | 1408 /// is not known if it belongs to the same owner as the original class. In |
| 1388 /// this case, we create an object whose owner is what the original mirror | 1409 /// this case, we create an object whose owner is what the original mirror |
| 1389 /// says it is. | 1410 /// says it is. |
| 1390 factory Class._possiblyDifferentOwner(ClassMirror mirror, | 1411 factory Class._possiblyDifferentOwner(ClassMirror mirror, |
| 1391 Library originalOwner) { | 1412 Library originalOwner) { |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 1413 new Class._possiblyDifferentOwner(classMirror.superclass, owner); | 1434 new Class._possiblyDifferentOwner(classMirror.superclass, owner); |
| 1414 | 1435 |
| 1415 interfaces = superinterfaces.toList(); | 1436 interfaces = superinterfaces.toList(); |
| 1416 variables = _createVariables(classMirror.variables, this); | 1437 variables = _createVariables(classMirror.variables, this); |
| 1417 methods = _createMethods(classMirror.methods, this); | 1438 methods = _createMethods(classMirror.methods, this); |
| 1418 annotations = _createAnnotations(classMirror, _getOwningLibrary(owner)); | 1439 annotations = _createAnnotations(classMirror, _getOwningLibrary(owner)); |
| 1419 generics = _createGenerics(classMirror); | 1440 generics = _createGenerics(classMirror); |
| 1420 isAbstract = classMirror.isAbstract; | 1441 isAbstract = classMirror.isAbstract; |
| 1421 inheritedMethods = new Map<String, Method>(); | 1442 inheritedMethods = new Map<String, Method>(); |
| 1422 | 1443 |
| 1423 // Tell all superclasses that you are a subclass, unless you are not | 1444 // Tell superclass that you are a subclass, unless you are not |
| 1424 // visible or an intermediary mixin class. | 1445 // visible or an intermediary mixin class. |
| 1425 if (!classMirror.isNameSynthetic && _isVisible) { | 1446 if (!classMirror.isNameSynthetic && _isVisible && superclass != null) { |
| 1426 parentChain().forEach((parentClass) { | 1447 superclass.addSubclass(this); |
| 1427 parentClass.addSubclass(this); | |
| 1428 }); | |
| 1429 } | 1448 } |
| 1430 | 1449 |
| 1431 if (this.superclass != null) addInherited(superclass); | 1450 if (this.superclass != null) addInherited(superclass); |
| 1432 interfaces.forEach((interface) => addInherited(interface)); | 1451 interfaces.forEach((interface) => addInherited(interface)); |
| 1433 } | 1452 } |
| 1434 | 1453 |
| 1435 String get packagePrefix => owner.packagePrefix; | 1454 String get packagePrefix => owner.packagePrefix; |
| 1436 | 1455 |
| 1437 String _lookupInClassAndSuperclasses(String name) { | 1456 String _lookupInClassAndSuperclasses(String name) { |
| 1438 var lookupFunc = Indexable.determineLookupFunc(name); | 1457 var lookupFunc = Indexable.determineLookupFunc(name); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 1452 String findElementInScope(String name) { | 1471 String findElementInScope(String name) { |
| 1453 var lookupFunc = Indexable.determineLookupFunc(name); | 1472 var lookupFunc = Indexable.determineLookupFunc(name); |
| 1454 var result = _lookupInClassAndSuperclasses(name); | 1473 var result = _lookupInClassAndSuperclasses(name); |
| 1455 if (result != null) { | 1474 if (result != null) { |
| 1456 return result; | 1475 return result; |
| 1457 } | 1476 } |
| 1458 result = owner.findElementInScope(name); | 1477 result = owner.findElementInScope(name); |
| 1459 return result == null ? super.findElementInScope(name) : result; | 1478 return result == null ? super.findElementInScope(name) : result; |
| 1460 } | 1479 } |
| 1461 | 1480 |
| 1462 markdown.Node fixReferenceWithScope(String name) => fixReference(name); | |
| 1463 | |
| 1464 String get typeName => 'class'; | 1481 String get typeName => 'class'; |
| 1465 | 1482 |
| 1466 /// Returns a list of all the parent classes. | |
| 1467 List<Class> parentChain() { | |
| 1468 // TODO(efortuna): Seems like we can get rid of this method. | |
| 1469 var parent = superclass == null ? [] : [superclass]; | |
| 1470 return parent; | |
| 1471 } | |
| 1472 | |
| 1473 /// Add all inherited variables and methods from the provided superclass. | 1483 /// Add all inherited variables and methods from the provided superclass. |
| 1474 /// If [_includePrivate] is true, it also adds the variables and methods from | 1484 /// If [_includePrivate] is true, it also adds the variables and methods from |
| 1475 /// the superclass. | 1485 /// the superclass. |
| 1476 void addInherited(Class superclass) { | 1486 void addInherited(Class superclass) { |
| 1477 inheritedVariables.addAll(superclass.inheritedVariables); | 1487 inheritedVariables.addAll(superclass.inheritedVariables); |
| 1478 inheritedVariables.addAll(_allButStatics(superclass.variables)); | 1488 inheritedVariables.addAll(_allButStatics(superclass.variables)); |
| 1479 addInheritedMethod(superclass, this); | 1489 addInheritedMethod(superclass, this); |
| 1480 } | 1490 } |
| 1481 | 1491 |
| 1482 /** [newParent] refers to the actual class is currently using these methods. | 1492 /** [newParent] refers to the actual class is currently using these methods. |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1570 'qualifiedName': qualifiedName, | 1580 'qualifiedName': qualifiedName, |
| 1571 'comment': comment, | 1581 'comment': comment, |
| 1572 'isAbstract' : isAbstract, | 1582 'isAbstract' : isAbstract, |
| 1573 'superclass': validSuperclass(), | 1583 'superclass': validSuperclass(), |
| 1574 'implements': interfaces.where((i) => i._isVisible) | 1584 'implements': interfaces.where((i) => i._isVisible) |
| 1575 .map((e) => e.qualifiedName).toList(), | 1585 .map((e) => e.qualifiedName).toList(), |
| 1576 'subclass': (subclasses.toList()..sort()) | 1586 'subclass': (subclasses.toList()..sort()) |
| 1577 .map((x) => x.qualifiedName).toList(), | 1587 .map((x) => x.qualifiedName).toList(), |
| 1578 'variables': recurseMap(variables), | 1588 'variables': recurseMap(variables), |
| 1579 'inheritedVariables': recurseMap(inheritedVariables), | 1589 'inheritedVariables': recurseMap(inheritedVariables), |
| 1580 'methods': expandMethodMap(methods), | 1590 'methods': _expandMethodMap(methods), |
| 1581 'inheritedMethods': expandMethodMap(inheritedMethods), | 1591 'inheritedMethods': _expandMethodMap(inheritedMethods), |
| 1582 'annotations': annotations.map((a) => a.toMap()).toList(), | 1592 'annotations': annotations.map((a) => a.toMap()).toList(), |
| 1583 'generics': recurseMap(generics) | 1593 'generics': recurseMap(generics) |
| 1584 }; | 1594 }; |
| 1585 | 1595 |
| 1586 int compareTo(aClass) => name.compareTo(aClass.name); | 1596 int compareTo(aClass) => name.compareTo(aClass.name); |
| 1587 | 1597 |
| 1588 bool _isValidMirror(DeclarationMirror mirror) => mirror is ClassMirror; | 1598 bool _isValidMirror(DeclarationMirror mirror) => mirror is ClassMirror; |
| 1589 } | 1599 } |
| 1590 | 1600 |
| 1591 class Typedef extends OwnedIndexable { | 1601 class Typedef extends OwnedIndexable { |
| 1592 String returnType; | 1602 String returnType; |
| 1593 | 1603 |
| 1594 Map<String, Parameter> parameters; | 1604 Map<String, Parameter> parameters; |
| 1595 | 1605 |
| 1596 /// Generic information about the typedef. | 1606 /// Generic information about the typedef. |
| 1597 Map<String, Generic> generics; | 1607 Map<String, Generic> generics; |
| 1598 | 1608 |
| 1599 /// List of the meta annotations on the typedef. | |
| 1600 List<Annotation> annotations; | |
| 1601 | |
| 1602 /// Returns the [Library] for the given [mirror] if it has already been | 1609 /// Returns the [Library] for the given [mirror] if it has already been |
| 1603 /// created, else creates it. | 1610 /// created, else creates it. |
| 1604 factory Typedef(TypedefMirror mirror, Library owningLibrary) { | 1611 factory Typedef(TypedefMirror mirror, Library owningLibrary) { |
| 1605 var aTypedef = Indexable.getDocgenObject(mirror, owningLibrary); | 1612 var aTypedef = Indexable.getDocgenObject(mirror, owningLibrary); |
| 1606 if (aTypedef is DummyMirror) { | 1613 if (aTypedef is DummyMirror) { |
| 1607 aTypedef = new Typedef._(mirror, owningLibrary); | 1614 aTypedef = new Typedef._(mirror, owningLibrary); |
| 1608 } | 1615 } |
| 1609 return aTypedef; | 1616 return aTypedef; |
| 1610 } | 1617 } |
| 1611 | 1618 |
| 1612 Typedef._(TypedefMirror mirror, Library owningLibrary) : | 1619 Typedef._(TypedefMirror mirror, Library owningLibrary) : |
| 1613 super(mirror, owningLibrary) { | 1620 super(mirror, owningLibrary) { |
| 1614 returnType = Indexable.getDocgenObject(mirror.value.returnType).docName; | 1621 returnType = Indexable.getDocgenObject(mirror.value.returnType).docName; |
| 1615 generics = _createGenerics(mirror); | 1622 generics = _createGenerics(mirror); |
| 1616 parameters = _createParameters(mirror.value.parameters, owningLibrary); | 1623 parameters = _createParameters(mirror.value.parameters, owningLibrary); |
| 1617 annotations = _createAnnotations(mirror, owningLibrary); | 1624 annotations = _createAnnotations(mirror, owningLibrary); |
| 1618 } | 1625 } |
| 1619 | 1626 |
| 1620 Map toMap() => { | 1627 Map toMap() => { |
| 1621 'name': name, | 1628 'name': name, |
| 1622 'qualifiedName': qualifiedName, | 1629 'qualifiedName': qualifiedName, |
| 1623 'comment': comment, | 1630 'comment': comment, |
| 1624 'return': returnType, | 1631 'return': returnType, |
| 1625 'parameters': recurseMap(parameters), | 1632 'parameters': recurseMap(parameters), |
| 1626 'annotations': annotations.map((a) => a.toMap()).toList(), | 1633 'annotations': annotations.map((a) => a.toMap()).toList(), |
| 1627 'generics': recurseMap(generics) | 1634 'generics': recurseMap(generics) |
| 1628 }; | 1635 }; |
| 1629 | 1636 |
| 1637 markdown.Node fixReference(String name) => null; | |
| 1638 | |
| 1630 String get typeName => 'typedef'; | 1639 String get typeName => 'typedef'; |
| 1631 | 1640 |
| 1632 bool _isValidMirror(DeclarationMirror mirror) => mirror is TypedefMirror; | 1641 bool _isValidMirror(DeclarationMirror mirror) => mirror is TypedefMirror; |
| 1633 } | 1642 } |
| 1634 | 1643 |
| 1635 /// A class containing properties of a Dart variable. | 1644 /// A class containing properties of a Dart variable. |
| 1636 class Variable extends OwnedIndexable { | 1645 class Variable extends OwnedIndexable { |
| 1637 | 1646 |
| 1638 bool isFinal; | 1647 bool isFinal; |
| 1639 bool isStatic; | 1648 bool isStatic; |
| 1640 bool isConst; | 1649 bool isConst; |
| 1641 Type type; | 1650 Type type; |
| 1642 String _variableName; | 1651 String _variableName; |
| 1643 | 1652 |
| 1644 /// List of the meta annotations on the variable. | |
| 1645 List<Annotation> annotations; | |
| 1646 | |
| 1647 factory Variable(String variableName, VariableMirror mirror, | 1653 factory Variable(String variableName, VariableMirror mirror, |
| 1648 Indexable owner) { | 1654 Indexable owner) { |
| 1649 var variable = Indexable.getDocgenObject(mirror); | 1655 var variable = Indexable.getDocgenObject(mirror); |
| 1650 if (variable is DummyMirror) { | 1656 if (variable is DummyMirror) { |
| 1651 return new Variable._(variableName, mirror, owner); | 1657 return new Variable._(variableName, mirror, owner); |
| 1652 } | 1658 } |
| 1653 return variable; | 1659 return variable; |
| 1654 } | 1660 } |
| 1655 | 1661 |
| 1656 Variable._(this._variableName, VariableMirror mirror, Indexable owner) : | 1662 Variable._(this._variableName, VariableMirror mirror, Indexable owner) : |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 1681 String get typeName => 'property'; | 1687 String get typeName => 'property'; |
| 1682 | 1688 |
| 1683 get comment { | 1689 get comment { |
| 1684 if (_comment != null) return _comment; | 1690 if (_comment != null) return _comment; |
| 1685 if (owner is Class) { | 1691 if (owner is Class) { |
| 1686 (owner as Class).ensureComments(); | 1692 (owner as Class).ensureComments(); |
| 1687 } | 1693 } |
| 1688 return super.comment; | 1694 return super.comment; |
| 1689 } | 1695 } |
| 1690 | 1696 |
| 1691 markdown.Node fixReferenceWithScope(String name) => fixReference(name); | |
| 1692 | |
| 1693 String findElementInScope(String name) { | 1697 String findElementInScope(String name) { |
| 1694 var lookupFunc = Indexable.determineLookupFunc(name); | 1698 var lookupFunc = Indexable.determineLookupFunc(name); |
| 1695 var result = lookupFunc(mirror, name); | 1699 var result = lookupFunc(mirror, name); |
| 1696 if (result != null) { | 1700 if (result != null) { |
| 1697 result = Indexable.getDocgenObject(result); | 1701 result = Indexable.getDocgenObject(result); |
| 1698 if (result is DummyMirror) return packagePrefix + result.docName; | 1702 if (result is DummyMirror) return packagePrefix + result.docName; |
| 1699 return result.packagePrefix + result.docName; | 1703 return result.packagePrefix + result.docName; |
| 1700 } | 1704 } |
| 1701 | 1705 |
| 1702 if (owner != null) { | 1706 if (owner != null) { |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 1719 | 1723 |
| 1720 bool isStatic; | 1724 bool isStatic; |
| 1721 bool isAbstract; | 1725 bool isAbstract; |
| 1722 bool isConst; | 1726 bool isConst; |
| 1723 Type returnType; | 1727 Type returnType; |
| 1724 Method methodInheritedFrom; | 1728 Method methodInheritedFrom; |
| 1725 | 1729 |
| 1726 /// Qualified name to state where the comment is inherited from. | 1730 /// Qualified name to state where the comment is inherited from. |
| 1727 String commentInheritedFrom = ""; | 1731 String commentInheritedFrom = ""; |
| 1728 | 1732 |
| 1729 /// List of the meta annotations on the method. | 1733 factory Method(MethodMirror mirror, Indexable owner, |
| 1730 List<Annotation> annotations; | |
| 1731 | |
| 1732 factory Method(MethodMirror mirror, Indexable owner, // Indexable newOwner. | |
| 1733 [Method methodInheritedFrom]) { | 1734 [Method methodInheritedFrom]) { |
| 1734 var method = Indexable.getDocgenObject(mirror, owner); | 1735 var method = Indexable.getDocgenObject(mirror, owner); |
| 1735 if (method is DummyMirror) { | 1736 if (method is DummyMirror) { |
| 1736 method = new Method._(mirror, owner, methodInheritedFrom); | 1737 method = new Method._(mirror, owner, methodInheritedFrom); |
| 1737 } | 1738 } |
| 1738 return method; | 1739 return method; |
| 1739 } | 1740 } |
| 1740 | 1741 |
| 1741 Method._(MethodMirror mirror, Indexable owner, this.methodInheritedFrom) | 1742 Method._(MethodMirror mirror, Indexable owner, this.methodInheritedFrom) |
| 1742 : super(mirror, owner) { | 1743 : super(mirror, owner) { |
| 1743 isStatic = mirror.isStatic; | 1744 isStatic = mirror.isStatic; |
| 1744 isAbstract = mirror.isAbstract; | 1745 isAbstract = mirror.isAbstract; |
| 1745 isConst = mirror.isConstConstructor; | 1746 isConst = mirror.isConstConstructor; |
| 1746 returnType = new Type(mirror.returnType, _getOwningLibrary(owner)); | 1747 returnType = new Type(mirror.returnType, _getOwningLibrary(owner)); |
| 1747 parameters = _createParameters(mirror.parameters, owner); | 1748 parameters = _createParameters(mirror.parameters, owner); |
| 1748 annotations = _createAnnotations(mirror, _getOwningLibrary(owner)); | 1749 annotations = _createAnnotations(mirror, _getOwningLibrary(owner)); |
| 1749 } | 1750 } |
| 1750 | 1751 |
| 1751 String get packagePrefix => owner.packagePrefix; | 1752 String get packagePrefix => owner.packagePrefix; |
| 1752 | 1753 |
| 1753 Method get originallyInheritedFrom => methodInheritedFrom == null ? | 1754 Method get originallyInheritedFrom => methodInheritedFrom == null ? |
| 1754 this : methodInheritedFrom.originallyInheritedFrom; | 1755 this : methodInheritedFrom.originallyInheritedFrom; |
| 1755 | 1756 |
| 1756 markdown.Node fixReferenceWithScope(String name) => fixReference(name); | |
| 1757 | |
| 1758 /// Look for the specified name starting with the current member, and | 1757 /// Look for the specified name starting with the current member, and |
| 1759 /// progressively working outward to the current library scope. | 1758 /// progressively working outward to the current library scope. |
| 1760 String findElementInScope(String name) { | 1759 String findElementInScope(String name) { |
| 1761 var lookupFunc = Indexable.determineLookupFunc(name); | 1760 var lookupFunc = Indexable.determineLookupFunc(name); |
| 1762 | 1761 |
| 1763 var memberScope = lookupFunc(this.mirror, name); | 1762 var memberScope = lookupFunc(this.mirror, name); |
| 1764 if (memberScope != null) { | 1763 if (memberScope != null) { |
| 1765 // do we check for a dummy mirror returned here and look up with an owner | 1764 // do we check for a dummy mirror returned here and look up with an owner |
| 1766 // higher ooooor in getDocgenObject do we include more things in our | 1765 // higher ooooor in getDocgenObject do we include more things in our |
| 1767 // lookup | 1766 // lookup |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1831 return 'method'; | 1830 return 'method'; |
| 1832 } | 1831 } |
| 1833 | 1832 |
| 1834 get comment { | 1833 get comment { |
| 1835 if (_comment != null) return _comment; | 1834 if (_comment != null) return _comment; |
| 1836 if (owner is Class) { | 1835 if (owner is Class) { |
| 1837 (owner as Class).ensureComments(); | 1836 (owner as Class).ensureComments(); |
| 1838 } | 1837 } |
| 1839 var result = super.comment; | 1838 var result = super.comment; |
| 1840 if (result == '' && methodInheritedFrom != null) { | 1839 if (result == '' && methodInheritedFrom != null) { |
| 1841 // this should be NOT from the MIRROR, but from the COMMENT | 1840 // This should be NOT from the MIRROR, but from the COMMENT. |
| 1841 methodInheritedFrom.comment; // Ensure comment field has been populated. | |
| 1842 _unresolvedComment = methodInheritedFrom._unresolvedComment; | 1842 _unresolvedComment = methodInheritedFrom._unresolvedComment; |
| 1843 | 1843 |
| 1844 var linkResolver = (name) => fixReferenceWithScope(name); | 1844 var linkResolver = (name) => fixReference(name); |
| 1845 comment = _unresolvedComment == null ? '' : | 1845 comment = _unresolvedComment == null ? '' : |
| 1846 markdown.markdownToHtml(_unresolvedComment.trim(), | 1846 markdown.markdownToHtml(_unresolvedComment.trim(), |
| 1847 linkResolver: linkResolver, inlineSyntaxes: _MARKDOWN_SYNTAXES); | 1847 linkResolver: linkResolver, inlineSyntaxes: _MARKDOWN_SYNTAXES); |
| 1848 commentInheritedFrom = methodInheritedFrom.commentInheritedFrom; | 1848 commentInheritedFrom = comment != '' ? |
| 1849 methodInheritedFrom.commentInheritedFrom : ''; | |
| 1849 result = comment; | 1850 result = comment; |
| 1850 } | 1851 } |
| 1851 return result; | 1852 return result; |
| 1852 } | 1853 } |
| 1853 | 1854 |
| 1854 bool _isValidMirror(DeclarationMirror mirror) => mirror is MethodMirror; | 1855 bool _isValidMirror(DeclarationMirror mirror) => mirror is MethodMirror; |
| 1855 } | 1856 } |
| 1856 | 1857 |
| 1857 /// Docgen wrapper around the dart2js mirror for a Dart | 1858 /// Docgen wrapper around the dart2js mirror for a Dart |
| 1858 /// method/function parameter. | 1859 /// method/function parameter. |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1971 .map((e) => originalMirror.getField(e.simpleName).reflectee) | 1972 .map((e) => originalMirror.getField(e.simpleName).reflectee) |
| 1972 .where((e) => e != null) | 1973 .where((e) => e != null) |
| 1973 .toList(); | 1974 .toList(); |
| 1974 } | 1975 } |
| 1975 | 1976 |
| 1976 Map toMap() => { | 1977 Map toMap() => { |
| 1977 'name': Indexable.getDocgenObject(mirror, owningLibrary).docName, | 1978 'name': Indexable.getDocgenObject(mirror, owningLibrary).docName, |
| 1978 'parameters': parameters | 1979 'parameters': parameters |
| 1979 }; | 1980 }; |
| 1980 } | 1981 } |
| OLD | NEW |