| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * **docgen** is a tool for creating machine readable representations of Dart | 6 * **docgen** is a tool for creating machine readable representations of Dart |
| 7 * code metadata, including: classes, members, comments and annotations. | 7 * code metadata, including: classes, members, comments and annotations. |
| 8 * | 8 * |
| 9 * docgen is run on a `.dart` file or a directory containing `.dart` files. | 9 * docgen is run on a `.dart` file or a directory containing `.dart` files. |
| 10 * | 10 * |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 125 _documentLibraries(librariesToDocument, includeSdk: includeSdk, | 125 _documentLibraries(librariesToDocument, includeSdk: includeSdk, |
| 126 outputToYaml: outputToYaml, append: append, parseSdk: parseSdk, | 126 outputToYaml: outputToYaml, append: append, parseSdk: parseSdk, |
| 127 introduction: introduction); | 127 introduction: introduction); |
| 128 return true; | 128 return true; |
| 129 }); | 129 }); |
| 130 } | 130 } |
| 131 | 131 |
| 132 /// For a [library] and its corresponding [mirror] that we believe come | 132 /// For a [library] and its corresponding [mirror] that we believe come |
| 133 /// from a package (because it has a file | 133 /// from a package (because it has a file |
| 134 /// URI) look for the package name and set it on [library]. | 134 /// URI) look for the package name and set it on [library]. |
| 135 _findPackage(Library library, LibraryMirror mirror) { | 135 void _findPackage(Library library, LibraryMirror mirror) { |
| 136 if (mirror.uri.scheme != 'file') return; | 136 if (mirror.uri.scheme != 'file') return; |
| 137 var filePath = mirror.uri.toFilePath(); | 137 var filePath = mirror.uri.toFilePath(); |
| 138 // We assume that we are documenting only libraries under package/lib | 138 // We assume that we are documenting only libraries under package/lib |
| 139 var rootdir = path.dirname((path.dirname(filePath))); | 139 var rootdir = path.dirname((path.dirname(filePath))); |
| 140 var pubspec = path.join(rootdir, 'pubspec.yaml'); | 140 var pubspec = path.join(rootdir, 'pubspec.yaml'); |
| 141 library.packageName = _packageName(pubspec); | 141 library.packageName = _packageName(pubspec); |
| 142 // If we are the main library in a package, associate the package readme |
| 143 // with us. |
| 144 // TODO(alanknight): We can't really rely on all packages having a library |
| 145 // that matches the package name. Need a better way to store this. |
| 146 if (library.packageName == library.name) { |
| 147 library.packageIntro = _packageIntro(rootdir); |
| 148 } |
| 142 } | 149 } |
| 143 | 150 |
| 151 String _packageIntro(packageDir) { |
| 152 var dir = new Directory(packageDir); |
| 153 var files = dir.listSync(); |
| 154 var readmes = files.where((FileSystemEntity each) => (each is File && |
| 155 each.path.substring(packageDir.length + 1, each.path.length) |
| 156 .startsWith('README'))).toList(); |
| 157 if (readmes.isEmpty) return ''; |
| 158 // If there are multiples, pick the shortest name. |
| 159 readmes.sort((a, b) => a.length.compareTo(b.length)); |
| 160 var readme = readmes.first; |
| 161 var contents = markdown.markdownToHtml(readme |
| 162 .readAsStringSync(), linkResolver: linkResolver, |
| 163 inlineSyntaxes: markdownSyntaxes); |
| 164 return contents; |
| 165 } |
| 166 |
| 167 |
| 144 List<String> _listLibraries(List<String> args) { | 168 List<String> _listLibraries(List<String> args) { |
| 145 var libraries = new List<String>(); | 169 var libraries = new List<String>(); |
| 146 for (var arg in args) { | 170 for (var arg in args) { |
| 147 var type = FileSystemEntity.typeSync(arg); | 171 var type = FileSystemEntity.typeSync(arg); |
| 148 | 172 |
| 149 if (type == FileSystemEntityType.FILE) { | 173 if (type == FileSystemEntityType.FILE) { |
| 150 if (arg.endsWith('.dart')) { | 174 if (arg.endsWith('.dart')) { |
| 151 libraries.add(path.absolute(arg)); | 175 libraries.add(path.absolute(arg)); |
| 152 logger.info('Added to libraries: ${libraries.last}'); | 176 logger.info('Added to libraries: ${libraries.last}'); |
| 153 } | 177 } |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 268 /** | 292 /** |
| 269 * Creates documentation for filtered libraries. | 293 * Creates documentation for filtered libraries. |
| 270 */ | 294 */ |
| 271 void _documentLibraries(List<LibraryMirror> libs, {bool includeSdk: false, | 295 void _documentLibraries(List<LibraryMirror> libs, {bool includeSdk: false, |
| 272 bool outputToYaml: true, bool append: false, bool parseSdk: false, | 296 bool outputToYaml: true, bool append: false, bool parseSdk: false, |
| 273 String introduction: ''}) { | 297 String introduction: ''}) { |
| 274 libs.forEach((lib) { | 298 libs.forEach((lib) { |
| 275 // Files belonging to the SDK have a uri that begins with 'dart:'. | 299 // Files belonging to the SDK have a uri that begins with 'dart:'. |
| 276 if (includeSdk || !lib.uri.toString().startsWith('dart:')) { | 300 if (includeSdk || !lib.uri.toString().startsWith('dart:')) { |
| 277 var library = generateLibrary(lib); | 301 var library = generateLibrary(lib); |
| 278 entityMap[library.qualifiedName] = library; | 302 entityMap[library.name] = library; |
| 279 } | 303 } |
| 280 }); | 304 }); |
| 281 // After everything is created, do a pass through all classes to make sure no | 305 // After everything is created, do a pass through all classes to make sure no |
| 282 // intermediate classes created by mixins are included. | 306 // intermediate classes created by mixins are included. |
| 283 entityMap.values.where((e) => e is Class).forEach((c) => c.makeValid()); | 307 entityMap.values.where((e) => e is Class).forEach((c) => c.makeValid()); |
| 284 // Everything is a subclass of Object, therefore empty the list to avoid a | 308 // Everything is a subclass of Object, therefore empty the list to avoid a |
| 285 // giant list of subclasses to be printed out. | 309 // giant list of subclasses to be printed out. |
| 286 if (parseSdk) entityMap['dart.core.Object'].subclasses.clear(); | 310 if (parseSdk) (entityMap['dart-core.Object'] as Class).subclasses.clear(); |
| 287 | 311 |
| 288 var filteredEntities = entityMap.values.where(_isVisible); | 312 var filteredEntities = entityMap.values.where(_isVisible); |
| 289 | 313 |
| 290 // Outputs a JSON file with all libraries and their preview comments. | 314 // Outputs a JSON file with all libraries and their preview comments. |
| 291 // This will help the viewer know what libraries are available to read in. | 315 // This will help the viewer know what libraries are available to read in. |
| 292 var libraryMap; | 316 var libraryMap; |
| 293 if (append) { | 317 if (append) { |
| 294 var docsDir = listDir('docs'); | 318 var docsDir = listDir('docs'); |
| 295 if (!docsDir.contains('docs/library_list.json')) { | 319 if (!docsDir.contains('docs/library_list.json')) { |
| 296 throw new StateError('No library_list.json'); | 320 throw new StateError('No library_list.json'); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 336 if (append) { | 360 if (append) { |
| 337 var previousIndex = | 361 var previousIndex = |
| 338 JSON.decode(new File('docs/index.json').readAsStringSync()); | 362 JSON.decode(new File('docs/index.json').readAsStringSync()); |
| 339 index.addAll(previousIndex); | 363 index.addAll(previousIndex); |
| 340 } | 364 } |
| 341 _writeToFile(JSON.encode(index), 'index.json'); | 365 _writeToFile(JSON.encode(index), 'index.json'); |
| 342 } | 366 } |
| 343 | 367 |
| 344 Library generateLibrary(dart2js.Dart2JsLibraryMirror library) { | 368 Library generateLibrary(dart2js.Dart2JsLibraryMirror library) { |
| 345 _currentLibrary = library; | 369 _currentLibrary = library; |
| 346 var result = new Library(library.qualifiedName, _commentToHtml(library), | 370 var result = new Library(docName(library), _commentToHtml(library), |
| 347 _variables(library.variables), | 371 _variables(library.variables), |
| 348 _methods(library.functions), | 372 _methods(library.functions), |
| 349 _classes(library.classes), _isHidden(library)); | 373 _classes(library.classes), _isHidden(library)); |
| 350 _findPackage(result, library); | 374 _findPackage(result, library); |
| 351 logger.fine('Generated library for ${result.name}'); | 375 logger.fine('Generated library for ${result.name}'); |
| 352 return result; | 376 return result; |
| 353 } | 377 } |
| 354 | 378 |
| 355 void _writeIndexableToFile(Indexable result, bool outputToYaml) { | 379 void _writeIndexableToFile(Indexable result, bool outputToYaml) { |
| 380 var outputFile = result.fileName; |
| 381 var output; |
| 356 if (outputToYaml) { | 382 if (outputToYaml) { |
| 357 _writeToFile(getYamlString(result.toMap()), '${result.qualifiedName}.yaml'); | 383 output = getYamlString(result.toMap()); |
| 384 outputFile = outputFile + '.yaml'; |
| 358 } else { | 385 } else { |
| 359 _writeToFile(JSON.encode(result.toMap()), '${result.qualifiedName}.json'); | 386 output = JSON.encode(result.toMap()); |
| 387 outputFile = outputFile + '.json'; |
| 360 } | 388 } |
| 389 _writeToFile(output, outputFile); |
| 361 } | 390 } |
| 362 | 391 |
| 363 /** | 392 /** |
| 364 * Returns true if a library name starts with an underscore, and false | 393 * Returns true if a library name starts with an underscore, and false |
| 365 * otherwise. | 394 * otherwise. |
| 366 * | 395 * |
| 367 * An example that starts with _ is _js_helper. | 396 * An example that starts with _ is _js_helper. |
| 368 * An example that contains ._ is dart._collection.dev | 397 * An example that contains ._ is dart._collection.dev |
| 369 */ | 398 */ |
| 370 // This is because LibraryMirror.isPrivate returns `false` all the time. | 399 // This is because LibraryMirror.isPrivate returns `false` all the time. |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 403 List<Annotation> _annotations(DeclarationMirror mirror) { | 432 List<Annotation> _annotations(DeclarationMirror mirror) { |
| 404 var annotationMirrors = mirror.metadata.where((e) => | 433 var annotationMirrors = mirror.metadata.where((e) => |
| 405 e is dart2js.Dart2JsConstructedConstantMirror); | 434 e is dart2js.Dart2JsConstructedConstantMirror); |
| 406 var annotations = []; | 435 var annotations = []; |
| 407 annotationMirrors.forEach((annotation) { | 436 annotationMirrors.forEach((annotation) { |
| 408 var parameterList = annotation.type.variables.values | 437 var parameterList = annotation.type.variables.values |
| 409 .where((e) => e.isFinal) | 438 .where((e) => e.isFinal) |
| 410 .map((e) => annotation.getField(e.simpleName).reflectee) | 439 .map((e) => annotation.getField(e.simpleName).reflectee) |
| 411 .where((e) => e != null) | 440 .where((e) => e != null) |
| 412 .toList(); | 441 .toList(); |
| 413 if (validAnnotations.contains(annotation.type.qualifiedName)) { | 442 if (validAnnotations.contains(docName(annotation.type))) { |
| 414 annotations.add(new Annotation(annotation.type.qualifiedName, | 443 annotations.add(new Annotation(docName(annotation.type), |
| 415 parameterList)); | 444 parameterList)); |
| 416 } | 445 } |
| 417 }); | 446 }); |
| 418 return annotations; | 447 return annotations; |
| 419 } | 448 } |
| 420 | 449 |
| 421 /** | 450 /** |
| 422 * Returns any documentation comments associated with a mirror with | 451 * Returns any documentation comments associated with a mirror with |
| 423 * simple markdown converted to html. | 452 * simple markdown converted to html. |
| 424 */ | 453 */ |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 497 | 526 |
| 498 /** | 527 /** |
| 499 * Converts all [foo] references in comments to <a>libraryName.foo</a>. | 528 * Converts all [foo] references in comments to <a>libraryName.foo</a>. |
| 500 */ | 529 */ |
| 501 markdown.Node fixReference(String name, LibraryMirror currentLibrary, | 530 markdown.Node fixReference(String name, LibraryMirror currentLibrary, |
| 502 ClassMirror currentClass, MemberMirror currentMember) { | 531 ClassMirror currentClass, MemberMirror currentMember) { |
| 503 var reference; | 532 var reference; |
| 504 var memberScope = currentMember == null ? | 533 var memberScope = currentMember == null ? |
| 505 null : currentMember.lookupInScope(name); | 534 null : currentMember.lookupInScope(name); |
| 506 if (memberScope != null) { | 535 if (memberScope != null) { |
| 507 reference = memberScope.qualifiedName; | 536 reference = docName(memberScope); |
| 508 } else { | 537 } else { |
| 509 var classScope = currentClass == null ? | 538 var classScope = currentClass == null ? |
| 510 null : currentClass.lookupInScope(name); | 539 null : currentClass.lookupInScope(name); |
| 511 if (classScope != null) { | 540 if (classScope != null) { |
| 512 reference = classScope.qualifiedName; | 541 reference = docName(classScope); |
| 513 } else { | 542 } else { |
| 514 var libraryScope = currentLibrary == null ? | 543 var libraryScope = currentLibrary == null ? |
| 515 null : currentLibrary.lookupInScope(name); | 544 null : currentLibrary.lookupInScope(name); |
| 516 reference = libraryScope != null ? libraryScope.qualifiedName : name; | 545 reference = libraryScope != null ? docName(libraryScope) : name; |
| 517 } | 546 } |
| 518 } | 547 } |
| 519 return new markdown.Element.text('a', reference); | 548 return new markdown.Element.text('a', reference); |
| 520 } | 549 } |
| 521 | 550 |
| 522 /** | 551 /** |
| 523 * Returns a map of [Variable] objects constructed from [mirrorMap]. | 552 * Returns a map of [Variable] objects constructed from [mirrorMap]. |
| 524 */ | 553 */ |
| 525 Map<String, Variable> _variables(Map<String, VariableMirror> mirrorMap) { | 554 Map<String, Variable> _variables(Map<String, VariableMirror> mirrorMap) { |
| 526 var data = {}; | 555 var data = {}; |
| 527 // TODO(janicejl): When map to map feature is created, replace the below with | 556 // TODO(janicejl): When map to map feature is created, replace the below with |
| 528 // a filter. Issue(#9590). | 557 // a filter. Issue(#9590). |
| 529 mirrorMap.forEach((String mirrorName, VariableMirror mirror) { | 558 mirrorMap.forEach((String mirrorName, VariableMirror mirror) { |
| 530 _currentMember = mirror; | 559 _currentMember = mirror; |
| 531 if (_includePrivate || !_isHidden(mirror)) { | 560 if (_includePrivate || !_isHidden(mirror)) { |
| 532 entityMap[mirror.qualifiedName] = new Variable(mirrorName, mirror.isFinal, | 561 entityMap[docName(mirror)] = new Variable(mirrorName, mirror.isFinal, |
| 533 mirror.isStatic, mirror.isConst, _type(mirror.type), | 562 mirror.isStatic, mirror.isConst, _type(mirror.type), |
| 534 _commentToHtml(mirror), _annotations(mirror), mirror.qualifiedName, | 563 _commentToHtml(mirror), _annotations(mirror), docName(mirror), |
| 535 _isHidden(mirror), mirror.owner.qualifiedName); | 564 _isHidden(mirror), docName(mirror.owner)); |
| 536 data[mirrorName] = entityMap[mirror.qualifiedName]; | 565 data[mirrorName] = entityMap[docName(mirror)]; |
| 537 } | 566 } |
| 538 }); | 567 }); |
| 539 return data; | 568 return data; |
| 540 } | 569 } |
| 541 | 570 |
| 542 /** | 571 /** |
| 543 * Returns a map of [Method] objects constructed from [mirrorMap]. | 572 * Returns a map of [Method] objects constructed from [mirrorMap]. |
| 544 */ | 573 */ |
| 545 MethodGroup _methods(Map<String, MethodMirror> mirrorMap) { | 574 MethodGroup _methods(Map<String, MethodMirror> mirrorMap) { |
| 546 var group = new MethodGroup(); | 575 var group = new MethodGroup(); |
| 547 mirrorMap.forEach((String mirrorName, MethodMirror mirror) { | 576 mirrorMap.forEach((String mirrorName, MethodMirror mirror) { |
| 548 if (_includePrivate || !mirror.isPrivate) { | 577 if (_includePrivate || !mirror.isPrivate) { |
| 549 group.addMethod(mirror); | 578 group.addMethod(mirror); |
| 550 } | 579 } |
| 551 }); | 580 }); |
| 552 return group; | 581 return group; |
| 553 } | 582 } |
| 554 | 583 |
| 555 /** | 584 /** |
| 556 * Returns the [Class] for the given [mirror] has already been created, and if | 585 * Returns the [Class] for the given [mirror] has already been created, and if |
| 557 * it does not exist, creates it. | 586 * it does not exist, creates it. |
| 558 */ | 587 */ |
| 559 Class _class(ClassMirror mirror) { | 588 Class _class(ClassMirror mirror) { |
| 560 var clazz = entityMap[mirror.qualifiedName]; | 589 var clazz = entityMap[docName(mirror)]; |
| 561 if (clazz == null) { | 590 if (clazz == null) { |
| 562 var superclass = mirror.superclass != null ? | 591 var superclass = mirror.superclass != null ? |
| 563 _class(mirror.superclass) : null; | 592 _class(mirror.superclass) : null; |
| 564 var interfaces = | 593 var interfaces = |
| 565 mirror.superinterfaces.map((interface) => _class(interface)); | 594 mirror.superinterfaces.map((interface) => _class(interface)); |
| 566 clazz = new Class(mirror.simpleName, superclass, _commentToHtml(mirror), | 595 clazz = new Class(mirror.simpleName, superclass, _commentToHtml(mirror), |
| 567 interfaces.toList(), _variables(mirror.variables), | 596 interfaces.toList(), _variables(mirror.variables), |
| 568 _methods(mirror.methods), _annotations(mirror), _generics(mirror), | 597 _methods(mirror.methods), _annotations(mirror), _generics(mirror), |
| 569 mirror.qualifiedName, _isHidden(mirror), mirror.owner.qualifiedName, | 598 docName(mirror), _isHidden(mirror), docName(mirror.owner), |
| 570 mirror.isAbstract); | 599 mirror.isAbstract); |
| 571 if (superclass != null) clazz.addInherited(superclass); | 600 if (superclass != null) clazz.addInherited(superclass); |
| 572 interfaces.forEach((interface) => clazz.addInherited(interface)); | 601 interfaces.forEach((interface) => clazz.addInherited(interface)); |
| 573 entityMap[mirror.qualifiedName] = clazz; | 602 entityMap[docName(mirror)] = clazz; |
| 574 } | 603 } |
| 575 return clazz; | 604 return clazz; |
| 576 } | 605 } |
| 577 | 606 |
| 578 /** | 607 /** |
| 579 * Returns a map of [Class] objects constructed from [mirrorMap]. | 608 * Returns a map of [Class] objects constructed from [mirrorMap]. |
| 580 */ | 609 */ |
| 581 ClassGroup _classes(Map<String, ClassMirror> mirrorMap) { | 610 ClassGroup _classes(Map<String, ClassMirror> mirrorMap) { |
| 582 var group = new ClassGroup(); | 611 var group = new ClassGroup(); |
| 583 mirrorMap.forEach((String mirrorName, ClassMirror mirror) { | 612 mirrorMap.forEach((String mirrorName, ClassMirror mirror) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 608 return new Map.fromIterable(mirror.typeVariables, | 637 return new Map.fromIterable(mirror.typeVariables, |
| 609 key: (e) => e.toString(), | 638 key: (e) => e.toString(), |
| 610 value: (e) => new Generic(e.toString(), e.upperBound.qualifiedName)); | 639 value: (e) => new Generic(e.toString(), e.upperBound.qualifiedName)); |
| 611 } | 640 } |
| 612 | 641 |
| 613 /** | 642 /** |
| 614 * Returns a single [Type] object constructed from the Method.returnType | 643 * Returns a single [Type] object constructed from the Method.returnType |
| 615 * Type mirror. | 644 * Type mirror. |
| 616 */ | 645 */ |
| 617 Type _type(TypeMirror mirror) { | 646 Type _type(TypeMirror mirror) { |
| 618 return new Type(mirror.qualifiedName, _typeGenerics(mirror)); | 647 return new Type(docName(mirror), _typeGenerics(mirror)); |
| 619 } | 648 } |
| 620 | 649 |
| 621 /** | 650 /** |
| 622 * Returns a list of [Type] objects constructed from TypeMirrors. | 651 * Returns a list of [Type] objects constructed from TypeMirrors. |
| 623 */ | 652 */ |
| 624 List<Type> _typeGenerics(TypeMirror mirror) { | 653 List<Type> _typeGenerics(TypeMirror mirror) { |
| 625 if (mirror is ClassMirror && !mirror.isTypedef) { | 654 if (mirror is ClassMirror && !mirror.isTypedef) { |
| 626 var innerList = []; | 655 var innerList = []; |
| 627 mirror.typeArguments.forEach((e) { | 656 mirror.typeArguments.forEach((e) { |
| 628 innerList.add(new Type(e.qualifiedName, _typeGenerics(e))); | 657 innerList.add(new Type(docName(e), _typeGenerics(e))); |
| 629 }); | 658 }); |
| 630 return innerList; | 659 return innerList; |
| 631 } | 660 } |
| 632 return []; | 661 return []; |
| 633 } | 662 } |
| 634 | 663 |
| 635 /** | 664 /** |
| 636 * Writes text to a file in the 'docs' directory. | 665 * Writes text to a file in the 'docs' directory. |
| 637 */ | 666 */ |
| 638 void _writeToFile(String text, String filename, {bool append: false}) { | 667 void _writeToFile(String text, String filename, {bool append: false}) { |
| 639 Directory dir = new Directory('docs'); | 668 Directory dir = new Directory('docs'); |
| 640 if (!dir.existsSync()) { | 669 if (!dir.existsSync()) { |
| 641 dir.createSync(); | 670 dir.createSync(); |
| 642 } | 671 } |
| 672 // We assume there's a single extra level of directory structure for packages. |
| 673 if (path.split(filename).length > 1) { |
| 674 var subdir = new Directory(path.join('docs', path.dirname(filename))); |
| 675 if (!subdir.existsSync()) { |
| 676 subdir.createSync(); |
| 677 } |
| 678 } |
| 679 |
| 643 File file = new File('docs/$filename'); | 680 File file = new File('docs/$filename'); |
| 644 if (!file.existsSync()) { | 681 if (!file.existsSync()) { |
| 645 file.createSync(); | 682 file.createSync(); |
| 646 } | 683 } |
| 647 file.writeAsStringSync(text, mode: append ? FileMode.APPEND : FileMode.WRITE); | 684 file.writeAsStringSync(text, mode: append ? FileMode.APPEND : FileMode.WRITE); |
| 648 } | 685 } |
| 649 | 686 |
| 650 /** | 687 /** |
| 651 * Transforms the map by calling toMap on each value in it. | 688 * Transforms the map by calling toMap on each value in it. |
| 652 */ | 689 */ |
| 653 Map recurseMap(Map inputMap) { | 690 Map recurseMap(Map inputMap) { |
| 654 var outputMap = {}; | 691 var outputMap = {}; |
| 655 inputMap.forEach((key, value) { | 692 inputMap.forEach((key, value) { |
| 656 if (value is Map) { | 693 if (value is Map) { |
| 657 outputMap[key] = recurseMap(value); | 694 outputMap[key] = recurseMap(value); |
| 658 } else { | 695 } else { |
| 659 outputMap[key] = value.toMap(); | 696 outputMap[key] = value.toMap(); |
| 660 } | 697 } |
| 661 }); | 698 }); |
| 662 return outputMap; | 699 return outputMap; |
| 663 } | 700 } |
| 664 | 701 |
| 665 /** | 702 /** |
| 666 * A class representing all programming constructs, like library or class. | 703 * A class representing all programming constructs, like library or class. |
| 667 */ | 704 */ |
| 668 class Indexable { | 705 class Indexable { |
| 669 String name; | 706 String name; |
| 670 String qualifiedName; | 707 String get qualifiedName => fileName; |
| 671 bool isPrivate; | 708 bool isPrivate; |
| 672 | 709 |
| 710 // The qualified name (for URL purposes) and the file name are the same, |
| 711 // of the form packageName/ClassName or packageName/ClassName.methodName. |
| 712 // This defines both the URL and the directory structure. |
| 713 String get fileName => packagePrefix + ownerPrefix + name; |
| 714 |
| 715 Indexable get owningEntity { |
| 716 var result = entityMap[owner]; |
| 717 return result; |
| 718 } |
| 719 String get ownerPrefix => owningEntity == null |
| 720 ? (owner == null || owner.isEmpty ? '' : owner + '.') |
| 721 : owningEntity.qualifiedName + '.'; |
| 722 |
| 723 String get packagePrefix => ''; |
| 673 /// Documentation comment with converted markdown. | 724 /// Documentation comment with converted markdown. |
| 674 String comment; | 725 String comment; |
| 675 | 726 |
| 676 /// Qualified Name of the owner of this Indexable Item. | 727 /// Qualified Name of the owner of this Indexable Item. |
| 677 /// For Library, owner will be ""; | 728 /// For Library, owner will be ""; |
| 678 String owner; | 729 String owner; |
| 679 | 730 |
| 680 Indexable(this.name, this.comment, this.qualifiedName, this.isPrivate, | 731 Indexable(this.name, this.comment, this.isPrivate, this.owner); |
| 681 this.owner); | |
| 682 | 732 |
| 683 /// The type of this member to be used in index.txt. | 733 /// The type of this member to be used in index.txt. |
| 684 String get typeName => ''; | 734 String get typeName => ''; |
| 685 | 735 |
| 686 /** | 736 /** |
| 687 * Creates a [Map] with this [Indexable]'s name and a preview comment. | 737 * Creates a [Map] with this [Indexable]'s name and a preview comment. |
| 688 */ | 738 */ |
| 689 Map get previewMap { | 739 Map get previewMap { |
| 690 var finalMap = { 'name' : qualifiedName }; | 740 var finalMap = { 'name' : name, 'qualifiedName' : qualifiedName }; |
| 691 if (comment != '') { | 741 if (comment != '') { |
| 692 var index = comment.indexOf('</p>'); | 742 var index = comment.indexOf('</p>'); |
| 693 finalMap['preview'] = '${comment.substring(0, index)}</p>'; | 743 finalMap['preview'] = '${comment.substring(0, index)}</p>'; |
| 694 } | 744 } |
| 695 return finalMap; | 745 return finalMap; |
| 696 } | 746 } |
| 747 |
| 748 /// Return an informative [Object.toString] for debugging. |
| 749 String toString() => "${super.toString()}(${name.toString()})"; |
| 750 |
| 751 /// Return a map representation of this type. |
| 752 Map toMap() {} |
| 697 } | 753 } |
| 698 | 754 |
| 699 /** | 755 /** |
| 700 * A class containing contents of a Dart library. | 756 * A class containing contents of a Dart library. |
| 701 */ | 757 */ |
| 702 class Library extends Indexable { | 758 class Library extends Indexable { |
| 703 | 759 |
| 704 /// Top-level variables in the library. | 760 /// Top-level variables in the library. |
| 705 Map<String, Variable> variables; | 761 Map<String, Variable> variables; |
| 706 | 762 |
| 707 /// Top-level functions in the library. | 763 /// Top-level functions in the library. |
| 708 MethodGroup functions; | 764 MethodGroup functions; |
| 709 | 765 |
| 710 /// Classes defined within the library | 766 /// Classes defined within the library |
| 711 ClassGroup classes; | 767 ClassGroup classes; |
| 712 | 768 |
| 713 String packageName = ''; | 769 String packageName = ''; |
| 714 | 770 |
| 715 Map get previewMap => super.previewMap..['packageName'] = packageName; | 771 String get packagePrefix => packageName == null || packageName.isEmpty |
| 772 ? '' |
| 773 : '$packageName/'; |
| 774 |
| 775 String packageIntro; |
| 776 |
| 777 Map get previewMap { |
| 778 var basic = super.previewMap; |
| 779 basic['packageName'] = packageName; |
| 780 if (packageIntro != null) { |
| 781 basic['packageIntro'] = packageIntro; |
| 782 } |
| 783 return basic; |
| 784 } |
| 716 | 785 |
| 717 Library(String name, String comment, this.variables, | 786 Library(String name, String comment, this.variables, |
| 718 this.functions, this.classes, bool isPrivate) : super(name, comment, | 787 this.functions, this.classes, bool isPrivate) : super(name, comment, |
| 719 name, isPrivate, "") {} | 788 isPrivate, ""); |
| 720 | 789 |
| 721 /// Generates a map describing the [Library] object. | 790 /// Generates a map describing the [Library] object. |
| 722 Map toMap() => { | 791 Map toMap() => { |
| 723 'name': name, | 792 'name': name, |
| 724 'qualifiedName': qualifiedName, | 793 'qualifiedName': qualifiedName, |
| 725 'comment': comment, | 794 'comment': comment, |
| 726 'variables': recurseMap(variables), | 795 'variables': recurseMap(variables), |
| 727 'functions': functions.toMap(), | 796 'functions': functions.toMap(), |
| 728 'classes': classes.toMap(), | 797 'classes': classes.toMap(), |
| 729 'packageName': packageName, | 798 'packageName': packageName, |
| 799 'packageIntro' : packageIntro |
| 730 }; | 800 }; |
| 731 | 801 |
| 732 String get typeName => 'library'; | 802 String get typeName => 'library'; |
| 733 } | 803 } |
| 734 | 804 |
| 735 /** | 805 /** |
| 736 * A class containing contents of a Dart class. | 806 * A class containing contents of a Dart class. |
| 737 */ | 807 */ |
| 738 class Class extends Indexable { | 808 class Class extends Indexable { |
| 739 | 809 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 760 | 830 |
| 761 Class superclass; | 831 Class superclass; |
| 762 bool isAbstract; | 832 bool isAbstract; |
| 763 | 833 |
| 764 /// List of the meta annotations on the class. | 834 /// List of the meta annotations on the class. |
| 765 List<Annotation> annotations; | 835 List<Annotation> annotations; |
| 766 | 836 |
| 767 Class(String name, this.superclass, String comment, this.interfaces, | 837 Class(String name, this.superclass, String comment, this.interfaces, |
| 768 this.variables, this.methods, this.annotations, this.generics, | 838 this.variables, this.methods, this.annotations, this.generics, |
| 769 String qualifiedName, bool isPrivate, String owner, this.isAbstract) | 839 String qualifiedName, bool isPrivate, String owner, this.isAbstract) |
| 770 : super(name, comment, qualifiedName, isPrivate, owner) { | 840 : super(name, comment, isPrivate, owner) { |
| 771 _mdnComment(this); | 841 _mdnComment(this); |
| 772 } | 842 } |
| 773 | 843 |
| 774 String get typeName => 'class'; | 844 String get typeName => 'class'; |
| 775 | 845 |
| 776 /** | 846 /** |
| 777 * Returns a list of all the parent classes. | 847 * Returns a list of all the parent classes. |
| 778 */ | 848 */ |
| 779 List<Class> parent() { | 849 List<Class> parent() { |
| 780 var parent = superclass == null ? [] : [superclass]; | 850 var parent = superclass == null ? [] : [superclass]; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 807 }); | 877 }); |
| 808 } else { | 878 } else { |
| 809 subclasses.add(subclass.qualifiedName); | 879 subclasses.add(subclass.qualifiedName); |
| 810 } | 880 } |
| 811 } | 881 } |
| 812 | 882 |
| 813 /** | 883 /** |
| 814 * Check if this [Class] is an error or exception. | 884 * Check if this [Class] is an error or exception. |
| 815 */ | 885 */ |
| 816 bool isError() { | 886 bool isError() { |
| 817 if (qualifiedName == 'dart.core.Error' || | 887 if (qualifiedName == 'dart-core.Error' || |
| 818 qualifiedName == 'dart.core.Exception') | 888 qualifiedName == 'dart-core.Exception') |
| 819 return true; | 889 return true; |
| 820 for (var interface in interfaces) { | 890 for (var interface in interfaces) { |
| 821 if (interface.isError()) return true; | 891 if (interface.isError()) return true; |
| 822 } | 892 } |
| 823 if (superclass == null) return false; | 893 if (superclass == null) return false; |
| 824 return superclass.isError(); | 894 return superclass.isError(); |
| 825 } | 895 } |
| 826 | 896 |
| 827 /** | 897 /** |
| 828 * Check that the class exists in the owner library. | 898 * Check that the class exists in the owner library. |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 887 * classes, regular classes, typedefs, and errors. | 957 * classes, regular classes, typedefs, and errors. |
| 888 */ | 958 */ |
| 889 class ClassGroup { | 959 class ClassGroup { |
| 890 Map<String, Class> classes = {}; | 960 Map<String, Class> classes = {}; |
| 891 Map<String, Typedef> typedefs = {}; | 961 Map<String, Typedef> typedefs = {}; |
| 892 Map<String, Class> errors = {}; | 962 Map<String, Class> errors = {}; |
| 893 | 963 |
| 894 void addClass(ClassMirror mirror) { | 964 void addClass(ClassMirror mirror) { |
| 895 _currentClass = mirror; | 965 _currentClass = mirror; |
| 896 if (mirror.isTypedef) { | 966 if (mirror.isTypedef) { |
| 967 // This is actually a Dart2jsTypedefMirror, and it does define value, |
| 968 // but we don't have visibility to that type. |
| 969 var mirror = _currentClass; |
| 897 if (_includePrivate || !mirror.isPrivate) { | 970 if (_includePrivate || !mirror.isPrivate) { |
| 898 entityMap[mirror.qualifiedName] = new Typedef(mirror.simpleName, | 971 entityMap[docName(mirror)] = new Typedef(mirror.simpleName, |
| 899 mirror.value.returnType.qualifiedName, _commentToHtml(mirror), | 972 docName(mirror.value.returnType), _commentToHtml(mirror), |
| 900 _generics(mirror), _parameters(mirror.value.parameters), | 973 _generics(mirror), _parameters(mirror.value.parameters), |
| 901 _annotations(mirror), mirror.qualifiedName, _isHidden(mirror), | 974 _annotations(mirror), docName(mirror), _isHidden(mirror), |
| 902 mirror.owner.qualifiedName); | 975 docName(mirror.owner)); |
| 903 typedefs[mirror.simpleName] = entityMap[mirror.qualifiedName]; | 976 typedefs[mirror.simpleName] = entityMap[docName(mirror)]; |
| 904 } | 977 } |
| 905 } else { | 978 } else { |
| 906 var clazz = _class(mirror); | 979 var clazz = _class(mirror); |
| 907 | 980 |
| 908 // Adding inherited parent variables and methods. | 981 // Adding inherited parent variables and methods. |
| 909 clazz.parent().forEach((parent) { | 982 clazz.parent().forEach((parent) { |
| 910 if (_isVisible(clazz)) { | 983 if (_isVisible(clazz)) { |
| 911 parent.addSubclass(clazz); | 984 parent.addSubclass(clazz); |
| 912 } | 985 } |
| 913 }); | 986 }); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 947 | 1020 |
| 948 /// Generic information about the typedef. | 1021 /// Generic information about the typedef. |
| 949 Map<String, Generic> generics; | 1022 Map<String, Generic> generics; |
| 950 | 1023 |
| 951 /// List of the meta annotations on the typedef. | 1024 /// List of the meta annotations on the typedef. |
| 952 List<Annotation> annotations; | 1025 List<Annotation> annotations; |
| 953 | 1026 |
| 954 Typedef(String name, this.returnType, String comment, this.generics, | 1027 Typedef(String name, this.returnType, String comment, this.generics, |
| 955 this.parameters, this.annotations, | 1028 this.parameters, this.annotations, |
| 956 String qualifiedName, bool isPrivate, String owner) | 1029 String qualifiedName, bool isPrivate, String owner) |
| 957 : super(name, comment, qualifiedName, isPrivate, owner); | 1030 : super(name, comment, isPrivate, owner); |
| 958 | 1031 |
| 959 Map toMap() => { | 1032 Map toMap() => { |
| 960 'name': name, | 1033 'name': name, |
| 961 'qualifiedName': qualifiedName, | 1034 'qualifiedName': qualifiedName, |
| 962 'comment': comment, | 1035 'comment': comment, |
| 963 'return': returnType, | 1036 'return': returnType, |
| 964 'parameters': recurseMap(parameters), | 1037 'parameters': recurseMap(parameters), |
| 965 'annotations': annotations.map((a) => a.toMap()).toList(), | 1038 'annotations': annotations.map((a) => a.toMap()).toList(), |
| 966 'generics': recurseMap(generics) | 1039 'generics': recurseMap(generics) |
| 967 }; | 1040 }; |
| 968 | 1041 |
| 969 String get typeName => 'typedef'; | 1042 String get typeName => 'typedef'; |
| 970 } | 1043 } |
| 971 | 1044 |
| 972 /** | 1045 /** |
| 973 * A class containing properties of a Dart variable. | 1046 * A class containing properties of a Dart variable. |
| 974 */ | 1047 */ |
| 975 class Variable extends Indexable { | 1048 class Variable extends Indexable { |
| 976 | 1049 |
| 977 bool isFinal; | 1050 bool isFinal; |
| 978 bool isStatic; | 1051 bool isStatic; |
| 979 bool isConst; | 1052 bool isConst; |
| 980 Type type; | 1053 Type type; |
| 981 | 1054 |
| 982 /// List of the meta annotations on the variable. | 1055 /// List of the meta annotations on the variable. |
| 983 List<Annotation> annotations; | 1056 List<Annotation> annotations; |
| 984 | 1057 |
| 985 Variable(String name, this.isFinal, this.isStatic, this.isConst, this.type, | 1058 Variable(String name, this.isFinal, this.isStatic, this.isConst, this.type, |
| 986 String comment, this.annotations, String qualifiedName, bool isPrivate, | 1059 String comment, this.annotations, String qualifiedName, bool isPrivate, |
| 987 String owner) : super(name, comment, qualifiedName, isPrivate, owner) { | 1060 String owner) : super(name, comment, isPrivate, owner) { |
| 988 _mdnComment(this); | 1061 _mdnComment(this); |
| 989 } | 1062 } |
| 990 | 1063 |
| 991 /// Generates a map describing the [Variable] object. | 1064 /// Generates a map describing the [Variable] object. |
| 992 Map toMap() => { | 1065 Map toMap() => { |
| 993 'name': name, | 1066 'name': name, |
| 994 'qualifiedName': qualifiedName, | 1067 'qualifiedName': qualifiedName, |
| 995 'comment': comment, | 1068 'comment': comment, |
| 996 'final': isFinal.toString(), | 1069 'final': isFinal.toString(), |
| 997 'static': isStatic.toString(), | 1070 'static': isStatic.toString(), |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1023 /// Qualified name to state where the comment is inherited from. | 1096 /// Qualified name to state where the comment is inherited from. |
| 1024 String commentInheritedFrom = ""; | 1097 String commentInheritedFrom = ""; |
| 1025 | 1098 |
| 1026 /// List of the meta annotations on the method. | 1099 /// List of the meta annotations on the method. |
| 1027 List<Annotation> annotations; | 1100 List<Annotation> annotations; |
| 1028 | 1101 |
| 1029 Method(String name, this.isStatic, this.isAbstract, this.isConst, | 1102 Method(String name, this.isStatic, this.isAbstract, this.isConst, |
| 1030 this.returnType, String comment, this.parameters, this.annotations, | 1103 this.returnType, String comment, this.parameters, this.annotations, |
| 1031 String qualifiedName, bool isPrivate, String owner, this.isConstructor, | 1104 String qualifiedName, bool isPrivate, String owner, this.isConstructor, |
| 1032 this.isGetter, this.isSetter, this.isOperator) | 1105 this.isGetter, this.isSetter, this.isOperator) |
| 1033 : super(name, comment, qualifiedName, isPrivate, owner) { | 1106 : super(name, comment, isPrivate, owner) { |
| 1034 _mdnComment(this); | 1107 _mdnComment(this); |
| 1035 } | 1108 } |
| 1036 | 1109 |
| 1037 /** | 1110 /** |
| 1038 * Makes sure that the method with an inherited equivalent have comments. | 1111 * Makes sure that the method with an inherited equivalent have comments. |
| 1039 */ | 1112 */ |
| 1040 void ensureCommentFor(Method inheritedMethod) { | 1113 void ensureCommentFor(Method inheritedMethod) { |
| 1041 if (comment.isNotEmpty) return; | 1114 if (comment.isNotEmpty) return; |
| 1042 entityMap[inheritedMethod.owner].ensureComments(); | 1115 (entityMap[inheritedMethod.owner] as Class).ensureComments(); |
| 1043 comment = inheritedMethod.comment; | 1116 comment = inheritedMethod.comment; |
| 1044 commentInheritedFrom = inheritedMethod.commentInheritedFrom == '' ? | 1117 commentInheritedFrom = inheritedMethod.commentInheritedFrom == '' ? |
| 1045 inheritedMethod.qualifiedName : inheritedMethod.commentInheritedFrom; | 1118 inheritedMethod.qualifiedName : inheritedMethod.commentInheritedFrom; |
| 1046 } | 1119 } |
| 1047 | 1120 |
| 1048 /// Generates a map describing the [Method] object. | 1121 /// Generates a map describing the [Method] object. |
| 1049 Map toMap() => { | 1122 Map toMap() => { |
| 1050 'name': name, | 1123 'name': name, |
| 1051 'qualifiedName': qualifiedName, | 1124 'qualifiedName': qualifiedName, |
| 1052 'comment': comment, | 1125 'comment': comment, |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1072 Map<String, Method> setters = {}; | 1145 Map<String, Method> setters = {}; |
| 1073 Map<String, Method> getters = {}; | 1146 Map<String, Method> getters = {}; |
| 1074 Map<String, Method> constructors = {}; | 1147 Map<String, Method> constructors = {}; |
| 1075 Map<String, Method> operators = {}; | 1148 Map<String, Method> operators = {}; |
| 1076 Map<String, Method> regularMethods = {}; | 1149 Map<String, Method> regularMethods = {}; |
| 1077 | 1150 |
| 1078 void addMethod(MethodMirror mirror) { | 1151 void addMethod(MethodMirror mirror) { |
| 1079 var method = new Method(mirror.simpleName, mirror.isStatic, | 1152 var method = new Method(mirror.simpleName, mirror.isStatic, |
| 1080 mirror.isAbstract, mirror.isConstConstructor, _type(mirror.returnType), | 1153 mirror.isAbstract, mirror.isConstConstructor, _type(mirror.returnType), |
| 1081 _commentToHtml(mirror), _parameters(mirror.parameters), | 1154 _commentToHtml(mirror), _parameters(mirror.parameters), |
| 1082 _annotations(mirror), mirror.qualifiedName, _isHidden(mirror), | 1155 _annotations(mirror), docName(mirror), _isHidden(mirror), |
| 1083 mirror.owner.qualifiedName, mirror.isConstructor, mirror.isGetter, | 1156 docName(mirror.owner), mirror.isConstructor, mirror.isGetter, |
| 1084 mirror.isSetter, mirror.isOperator); | 1157 mirror.isSetter, mirror.isOperator); |
| 1085 entityMap[mirror.qualifiedName] = method; | 1158 entityMap[docName(mirror)] = method; |
| 1086 _currentMember = mirror; | 1159 _currentMember = mirror; |
| 1087 if (mirror.isSetter) { | 1160 if (mirror.isSetter) { |
| 1088 setters[mirror.simpleName] = method; | 1161 setters[mirror.simpleName] = method; |
| 1089 } else if (mirror.isGetter) { | 1162 } else if (mirror.isGetter) { |
| 1090 getters[mirror.simpleName] = method; | 1163 getters[mirror.simpleName] = method; |
| 1091 } else if (mirror.isConstructor) { | 1164 } else if (mirror.isConstructor) { |
| 1092 constructors[mirror.simpleName] = method; | 1165 constructors[mirror.simpleName] = method; |
| 1093 } else if (mirror.isOperator) { | 1166 } else if (mirror.isOperator) { |
| 1094 operators[mirror.simpleName] = method; | 1167 operators[mirror.simpleName] = method; |
| 1095 } else if (mirror.isRegularMethod) { | 1168 } else if (mirror.isRegularMethod) { |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1183 | 1256 |
| 1184 /** | 1257 /** |
| 1185 * Holds the name of a return type, and its generic type parameters. | 1258 * Holds the name of a return type, and its generic type parameters. |
| 1186 * | 1259 * |
| 1187 * Return types are of a form [outer]<[inner]>. | 1260 * Return types are of a form [outer]<[inner]>. |
| 1188 * If there is no [inner] part, [inner] will be an empty list. | 1261 * If there is no [inner] part, [inner] will be an empty list. |
| 1189 * | 1262 * |
| 1190 * For example: | 1263 * For example: |
| 1191 * int size() | 1264 * int size() |
| 1192 * "return" : | 1265 * "return" : |
| 1193 * - "outer" : "dart.core.int" | 1266 * - "outer" : "dart-core.int" |
| 1194 * "inner" : | 1267 * "inner" : |
| 1195 * | 1268 * |
| 1196 * List<String> toList() | 1269 * List<String> toList() |
| 1197 * "return" : | 1270 * "return" : |
| 1198 * - "outer" : "dart.core.List" | 1271 * - "outer" : "dart-core.List" |
| 1199 * "inner" : | 1272 * "inner" : |
| 1200 * - "outer" : "dart.core.String" | 1273 * - "outer" : "dart-core.String" |
| 1201 * "inner" : | 1274 * "inner" : |
| 1202 * | 1275 * |
| 1203 * Map<String, List<int>> | 1276 * Map<String, List<int>> |
| 1204 * "return" : | 1277 * "return" : |
| 1205 * - "outer" : "dart.core.Map" | 1278 * - "outer" : "dart-core.Map" |
| 1206 * "inner" : | 1279 * "inner" : |
| 1207 * - "outer" : "dart.core.String" | 1280 * - "outer" : "dart-core.String" |
| 1208 * "inner" : | 1281 * "inner" : |
| 1209 * - "outer" : "dart.core.List" | 1282 * - "outer" : "dart-core.List" |
| 1210 * "inner" : | 1283 * "inner" : |
| 1211 * - "outer" : "dart.core.int" | 1284 * - "outer" : "dart-core.int" |
| 1212 * "inner" : | 1285 * "inner" : |
| 1213 */ | 1286 */ |
| 1214 class Type { | 1287 class Type { |
| 1215 String outer; | 1288 String outer; |
| 1216 List<Type> inner; | 1289 List<Type> inner; |
| 1217 | 1290 |
| 1218 Type(this.outer, this.inner); | 1291 Type(this.outer, this.inner); |
| 1219 | 1292 |
| 1220 Map toMap() => { | 1293 Map toMap() => { |
| 1221 'outer': outer, | 1294 'outer': outer, |
| 1222 'inner': inner.map((e) => e.toMap()).toList() | 1295 'inner': inner.map((e) => e.toMap()).toList() |
| 1223 }; | 1296 }; |
| 1224 } | 1297 } |
| 1225 | 1298 |
| 1226 /** | 1299 /** |
| 1227 * Holds the name of the annotation, and its parameters. | 1300 * Holds the name of the annotation, and its parameters. |
| 1228 */ | 1301 */ |
| 1229 class Annotation { | 1302 class Annotation { |
| 1230 String qualifiedName; | 1303 String qualifiedName; |
| 1231 List<String> parameters; | 1304 List<String> parameters; |
| 1232 | 1305 |
| 1233 Annotation(this.qualifiedName, this.parameters); | 1306 Annotation(this.qualifiedName, this.parameters); |
| 1234 | 1307 |
| 1235 Map toMap() => { | 1308 Map toMap() => { |
| 1236 'name': qualifiedName, | 1309 'name': qualifiedName, |
| 1237 'parameters': parameters | 1310 'parameters': parameters |
| 1238 }; | 1311 }; |
| 1239 } | 1312 } |
| 1313 |
| 1314 /// Given a mirror, returns its qualified name, but following the conventions |
| 1315 /// we're using in Dartdoc, which is that library names with dots in them |
| 1316 /// have them replaced with hyphens. |
| 1317 String docName(DeclarationMirror m) { |
| 1318 if (m is LibraryMirror) { |
| 1319 return (m as LibraryMirror).qualifiedName.replaceAll('.','-'); |
| 1320 } |
| 1321 var owner = m.owner; |
| 1322 if (owner == null) return m.qualifiedName; |
| 1323 // For the unnamed constructor we just return the class name. |
| 1324 if (m.simpleName == '') return docName(owner); |
| 1325 return docName(owner) + '.' + m.simpleName; |
| 1326 } |
| OLD | NEW |