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] |
11 /// | 11 /// |
12 /// This creates files called `docs/<library_name>.yaml` in your current | 12 /// This creates files called `docs/<library_name>.yaml` in your current |
13 /// working directory. | 13 /// working directory. |
14 library docgen; | 14 library docgen; |
15 | 15 |
16 import 'dart:convert'; | 16 import 'dart:convert'; |
17 import 'dart:io'; | 17 import 'dart:io'; |
18 import 'dart:async'; | 18 import 'dart:async'; |
19 | 19 |
20 | |
20 import 'package:logging/logging.dart'; | 21 import 'package:logging/logging.dart'; |
21 import 'package:markdown/markdown.dart' as markdown; | 22 import 'package:markdown/markdown.dart' as markdown; |
22 import 'package:path/path.dart' as path; | 23 import 'package:path/path.dart' as path; |
23 import 'package:yaml/yaml.dart'; | 24 import 'package:yaml/yaml.dart'; |
24 | 25 |
25 import 'dart2yaml.dart'; | 26 import 'dart2yaml.dart'; |
26 import 'src/io.dart'; | 27 import 'src/io.dart'; |
27 import '../../../sdk/lib/_internal/compiler/compiler.dart' as api; | 28 import '../../../sdk/lib/_internal/compiler/compiler.dart' as api; |
28 import '../../../sdk/lib/_internal/compiler/implementation/filenames.dart'; | 29 import '../../../sdk/lib/_internal/compiler/implementation/filenames.dart'; |
29 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirro r.dart' | 30 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirro rs.dart' |
30 as dart2js; | 31 as dart2js; |
31 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors.dart' ; | 32 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/analyze.dart' |
33 as dart2js; | |
34 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/source_mirror s.dart'; | |
32 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors_util. dart' | 35 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors_util. dart' |
33 as dart2js_util; | 36 as dart2js_util; |
34 import '../../../sdk/lib/_internal/compiler/implementation/source_file_provider. dart'; | 37 import '../../../sdk/lib/_internal/compiler/implementation/source_file_provider. dart'; |
35 import '../../../sdk/lib/_internal/libraries.dart'; | 38 import '../../../sdk/lib/_internal/libraries.dart'; |
36 | 39 |
37 var logger = new Logger('Docgen'); | 40 var logger = new Logger('Docgen'); |
38 | 41 |
39 const String USAGE = 'Usage: dart docgen.dart [OPTIONS] fooDir/barFile'; | 42 const String USAGE = 'Usage: dart docgen.dart [OPTIONS] fooDir/barFile'; |
40 | 43 |
41 | 44 |
42 List<String> skippedAnnotations = const [ | 45 List<String> skippedAnnotations = const [ |
43 'metadata.DocsEditable', '_js_helper.JSName', '_js_helper.Creates', | 46 'metadata.DocsEditable', '_js_helper.JSName', '_js_helper.Creates', |
44 '_js_helper.Returns', 'observe-src-metadata.Reflectable']; | 47 '_js_helper.Returns', 'observe-src-metadata.Reflectable']; |
45 | 48 |
46 /// Set of libraries declared in the SDK, so libraries that can be accessed | 49 /// Set of libraries declared in the SDK, so libraries that can be accessed |
47 /// when running dart by default. | 50 /// when running dart by default. |
48 Iterable<LibraryMirror> _sdkLibraries; | 51 Iterable<LibraryMirror> _sdkLibraries; |
49 | 52 |
50 /// The dart:core library, which contains all types that are always available | 53 /// The dart:core library, which contains all types that are always available |
51 /// without import. | 54 /// without import. |
52 LibraryMirror _coreLibrary; | 55 LibraryMirror _coreLibrary; |
53 | 56 |
54 /// Current library being documented to be used for comment links. | 57 /// Current library being documented to be used for comment links. |
55 LibraryMirror _currentLibrary; | 58 LibraryMirror _currentLibrary; |
56 | 59 |
57 /// Current class being documented to be used for comment links. | 60 /// Current class being documented to be used for comment links. |
58 ClassMirror _currentClass; | 61 ClassMirror _currentClass; |
59 | 62 |
60 /// Current member being documented to be used for comment links. | 63 /// Current member being documented to be used for comment links. |
61 MemberMirror _currentMember; | 64 DeclarationMirror _currentMember; |
62 | 65 |
63 /// Support for [:foo:]-style code comments to the markdown parser. | 66 /// Support for [:foo:]-style code comments to the markdown parser. |
64 List<markdown.InlineSyntax> markdownSyntaxes = | 67 List<markdown.InlineSyntax> markdownSyntaxes = |
65 [new markdown.CodeSyntax(r'\[:\s?((?:.|\n)*?)\s?:\]')]; | 68 [new markdown.CodeSyntax(r'\[:\s?((?:.|\n)*?)\s?:\]')]; |
66 | 69 |
67 /// Resolves reference links in doc comments. | 70 /// Resolves reference links in doc comments. |
68 markdown.Resolver linkResolver; | 71 markdown.Resolver linkResolver; |
69 | 72 |
70 /// Index of all indexable items. This also ensures that no class is | 73 /// Index of all indexable items. This also ensures that no class is |
71 /// created more than once. | 74 /// created more than once. |
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
373 var previousIndex = | 376 var previousIndex = |
374 JSON.decode(new File('docs/index.json').readAsStringSync()); | 377 JSON.decode(new File('docs/index.json').readAsStringSync()); |
375 index.addAll(previousIndex); | 378 index.addAll(previousIndex); |
376 } | 379 } |
377 _writeToFile(JSON.encode(index), 'index.json'); | 380 _writeToFile(JSON.encode(index), 'index.json'); |
378 } | 381 } |
379 | 382 |
380 Library generateLibrary(dart2js.Dart2JsLibraryMirror library) { | 383 Library generateLibrary(dart2js.Dart2JsLibraryMirror library) { |
381 _currentLibrary = library; | 384 _currentLibrary = library; |
382 var result = new Library(docName(library), _commentToHtml(library), | 385 var result = new Library(docName(library), _commentToHtml(library), |
383 _classes(library.classes), | 386 _classes(dart2js_util.typesOf(library.declarations)), |
384 _methods(library.functions), | 387 _methods(dart2js_util.methodsOf(library.declarations)), |
385 _variables(library.variables), | 388 _variables(dart2js_util.variablesOf(library.declarations)), |
386 _isHidden(library)); | 389 _isHidden(library)); |
387 _findPackage(result, library); | 390 _findPackage(result, library); |
388 logger.fine('Generated library for ${result.name}'); | 391 logger.fine('Generated library for ${result.name}'); |
389 return result; | 392 return result; |
390 } | 393 } |
391 | 394 |
392 void _writeIndexableToFile(Indexable result, bool outputToYaml) { | 395 void _writeIndexableToFile(Indexable result, bool outputToYaml) { |
393 var outputFile = result.fileName; | 396 var outputFile = result.fileName; |
394 var output; | 397 var output; |
395 if (outputToYaml) { | 398 if (outputToYaml) { |
396 output = getYamlString(result.toMap()); | 399 output = getYamlString(result.toMap()); |
397 outputFile = outputFile + '.yaml'; | 400 outputFile = outputFile + '.yaml'; |
398 } else { | 401 } else { |
399 output = JSON.encode(result.toMap()); | 402 output = JSON.encode(result.toMap()); |
400 outputFile = outputFile + '.json'; | 403 outputFile = outputFile + '.json'; |
401 } | 404 } |
402 _writeToFile(output, outputFile); | 405 _writeToFile(output, outputFile); |
403 } | 406 } |
404 | 407 |
405 /// Returns true if a library name starts with an underscore, and false | 408 /// Returns true if a library name starts with an underscore, and false |
406 /// otherwise. | 409 /// otherwise. |
407 /// | 410 /// |
408 /// An example that starts with _ is _js_helper. | 411 /// An example that starts with _ is _js_helper. |
409 /// An example that contains ._ is dart._collection.dev | 412 /// An example that contains ._ is dart._collection.dev |
410 // This is because LibraryMirror.isPrivate returns `false` all the time. | 413 // This is because LibraryMirror.isPrivate returns `false` all the time. |
411 bool _isLibraryPrivate(LibraryMirror mirror) { | 414 bool _isLibraryPrivate(LibraryMirror mirror) { |
412 var sdkLibrary = LIBRARIES[mirror.simpleName]; | 415 var sdkLibrary = LIBRARIES[dart2js_util.nameOf(mirror)]; |
413 if (sdkLibrary != null) { | 416 if (sdkLibrary != null) { |
414 return !sdkLibrary.documented; | 417 return !sdkLibrary.documented; |
415 } else if (mirror.simpleName.startsWith('_') || | 418 } else if (dart2js_util.nameOf(mirror).startsWith('_') || |
416 mirror.simpleName.contains('._')) { | 419 dart2js_util.nameOf(mirror).contains('._')) { |
417 return true; | 420 return true; |
418 } | 421 } |
419 return false; | 422 return false; |
420 } | 423 } |
421 | 424 |
422 /// A declaration is private if itself is private, or the owner is private. | 425 /// A declaration is private if itself is private, or the owner is private. |
423 // Issue(12202) - A declaration is public even if it's owner is private. | 426 // Issue(12202) - A declaration is public even if it's owner is private. |
424 bool _isHidden(DeclarationMirror mirror) { | 427 bool _isHidden(DeclarationMirror mirror) { |
425 if (mirror is LibraryMirror) { | 428 if (mirror is LibraryMirror) { |
426 return _isLibraryPrivate(mirror); | 429 return _isLibraryPrivate(mirror); |
427 } else if (mirror.owner is LibraryMirror) { | 430 } else if (mirror.owner is LibraryMirror) { |
428 return (mirror.isPrivate || _isLibraryPrivate(mirror.owner)); | 431 return (mirror.isPrivate || _isLibraryPrivate(mirror.owner)); |
429 } else { | 432 } else { |
430 return (mirror.isPrivate || _isHidden(mirror.owner)); | 433 return (mirror.isPrivate || _isHidden(mirror.owner)); |
431 } | 434 } |
432 } | 435 } |
433 | 436 |
434 bool _isVisible(Indexable item) { | 437 bool _isVisible(Indexable item) { |
435 return _includePrivate || !item.isPrivate; | 438 return _includePrivate || !item.isPrivate; |
436 } | 439 } |
437 | 440 |
438 /// Returns a list of meta annotations assocated with a mirror. | 441 /// Returns a list of meta annotations assocated with a mirror. |
439 List<Annotation> _annotations(DeclarationMirror mirror) { | 442 List<Annotation> _annotations(DeclarationMirror mirror) { |
440 var annotationMirrors = mirror.metadata.where((e) => | 443 var annotationMirrors = mirror.metadata.where((e) => |
441 e is dart2js.Dart2JsConstructedConstantMirror); | 444 e is dart2js.Dart2JsConstructedConstantMirror); |
442 var annotations = []; | 445 var annotations = []; |
443 annotationMirrors.forEach((annotation) { | 446 annotationMirrors.forEach((annotation) { |
444 var parameterList = annotation.type.variables.values | 447 var parameterList = dart2js_util.variablesOf(annotation.type.declarations) |
445 .where((e) => e.isFinal) | 448 .where((e) => e.isFinal) |
446 .map((e) => annotation.getField(e.simpleName).reflectee) | 449 .map((e) => annotation.getField(e.simpleName).reflectee) |
447 .where((e) => e != null) | 450 .where((e) => e != null) |
448 .toList(); | 451 .toList(); |
449 if (!skippedAnnotations.contains(docName(annotation.type))) { | 452 if (!skippedAnnotations.contains(docName(annotation.type))) { |
450 annotations.add(new Annotation(docName(annotation.type), | 453 annotations.add(new Annotation(docName(annotation.type), |
451 parameterList)); | 454 parameterList)); |
452 } | 455 } |
453 }); | 456 }); |
454 return annotations; | 457 return annotations; |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
531 } | 534 } |
532 | 535 |
533 String _htmlMdn(String content, String url) { | 536 String _htmlMdn(String content, String url) { |
534 return '<div class="mdn">' + content.trim() + '<p class="mdn-note">' | 537 return '<div class="mdn">' + content.trim() + '<p class="mdn-note">' |
535 '<a href="' + url.trim() + '">from Mdn</a></p></div>'; | 538 '<a href="' + url.trim() + '">from Mdn</a></p></div>'; |
536 } | 539 } |
537 | 540 |
538 /// Look for the specified name starting with the current member, and | 541 /// Look for the specified name starting with the current member, and |
539 /// progressively working outward to the current library scope. | 542 /// progressively working outward to the current library scope. |
540 String findElementInScope(String name, LibraryMirror currentLibrary, | 543 String findElementInScope(String name, LibraryMirror currentLibrary, |
541 ClassMirror currentClass, MemberMirror currentMember) { | 544 ClassMirror currentClass, |
545 DeclarationMirror currentMember) { | |
542 determineLookupFunc(name) => name.contains('.') ? | 546 determineLookupFunc(name) => name.contains('.') ? |
543 dart2js_util.lookupQualifiedInScope : | 547 dart2js_util.lookupQualifiedInScope : |
544 (mirror, name) => mirror.lookupInScope(name); | 548 (mirror, name) => mirror.lookupInScope(name); |
545 var lookupFunc = determineLookupFunc(name); | 549 var lookupFunc = determineLookupFunc(name); |
546 | 550 |
547 var memberScope = currentMember == null ? | 551 var memberScope = currentMember == null ? |
548 null : lookupFunc(currentMember, name); | 552 null : lookupFunc(currentMember, name); |
549 if (memberScope != null) return docName(memberScope); | 553 if (memberScope != null) return docName(memberScope); |
550 | 554 |
551 var classScope = currentClass; | 555 var classScope = currentClass; |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
620 /// This is a more complex reference. Try to break up if its of the form A<B> | 624 /// This is a more complex reference. Try to break up if its of the form A<B> |
621 /// where A is an alphanumeric string and B is an A, a list of B ("B, B, B"), | 625 /// where A is an alphanumeric string and B is an A, a list of B ("B, B, B"), |
622 /// or of the form A<B>. Note: unlike other the other markdown-style links, all | 626 /// or of the form A<B>. Note: unlike other the other markdown-style links, all |
623 /// text inside the square brackets is treated as part of the link (aka the * is | 627 /// text inside the square brackets is treated as part of the link (aka the * is |
624 /// interpreted literally as a *, not as a indicator for bold <em>. | 628 /// interpreted literally as a *, not as a indicator for bold <em>. |
625 /// | 629 /// |
626 /// Example: [foo<_bar_>] will produce | 630 /// Example: [foo<_bar_>] will produce |
627 /// <a>resolvedFoo</a><<a>resolved_bar_</a>> rather than an italicized | 631 /// <a>resolvedFoo</a><<a>resolved_bar_</a>> rather than an italicized |
628 /// version of resolvedBar. | 632 /// version of resolvedBar. |
629 markdown.Node _fixComplexReference(String name, LibraryMirror currentLibrary, | 633 markdown.Node _fixComplexReference(String name, LibraryMirror currentLibrary, |
630 ClassMirror currentClass, MemberMirror currentMember) { | 634 ClassMirror currentClass, |
635 DeclarationMirror currentMember) { | |
631 // Parse into multiple elements we can try to resolve. | 636 // Parse into multiple elements we can try to resolve. |
632 var tokens = _tokenizeComplexReference(name); | 637 var tokens = _tokenizeComplexReference(name); |
633 | 638 |
634 // Produce an html representation of our elements. Group unresolved and plain | 639 // Produce an html representation of our elements. Group unresolved and plain |
635 // text are grouped into "link" elements so they display as code. | 640 // text are grouped into "link" elements so they display as code. |
636 final textElements = [' ', ',', '>', _LESS_THAN]; | 641 final textElements = [' ', ',', '>', _LESS_THAN]; |
637 var accumulatedHtml = ''; | 642 var accumulatedHtml = ''; |
638 | 643 |
639 for (var token in tokens) { | 644 for (var token in tokens) { |
640 bool added = false; | 645 bool added = false; |
641 if (!textElements.contains(token)) { | 646 if (!textElements.contains(token)) { |
642 String elementName = findElementInScope(token, currentLibrary, | 647 String elementName = findElementInScope(token, currentLibrary, |
643 currentClass, currentMember); | 648 currentClass, currentMember); |
644 if (elementName != null) { | 649 if (elementName != null) { |
645 accumulatedHtml += markdown.renderToHtml([new markdown.Element.text( | 650 accumulatedHtml += markdown.renderToHtml([new markdown.Element.text( |
646 'a', elementName)]); | 651 'a', elementName)]); |
647 added = true; | 652 added = true; |
648 } | 653 } |
649 } | 654 } |
650 if (!added) { | 655 if (!added) { |
651 accumulatedHtml += token; | 656 accumulatedHtml += token; |
652 } | 657 } |
653 } | 658 } |
654 return new markdown.Text(accumulatedHtml); | 659 return new markdown.Text(accumulatedHtml); |
655 } | 660 } |
656 | 661 |
657 /// Converts all [foo] references in comments to <a>libraryName.foo</a>. | 662 /// Converts all [foo] references in comments to <a>libraryName.foo</a>. |
658 markdown.Node fixReference(String name, LibraryMirror currentLibrary, | 663 markdown.Node fixReference(String name, LibraryMirror currentLibrary, |
659 ClassMirror currentClass, MemberMirror currentMember) { | 664 ClassMirror currentClass, |
665 DeclarationMirror currentMember) { | |
660 // Attempt the look up the whole name up in the scope. | 666 // Attempt the look up the whole name up in the scope. |
661 String elementName = | 667 String elementName = |
662 findElementInScope(name, currentLibrary, currentClass, currentMember); | 668 findElementInScope(name, currentLibrary, currentClass, currentMember); |
663 if (elementName != null) { | 669 if (elementName != null) { |
664 return new markdown.Element.text('a', elementName); | 670 return new markdown.Element.text('a', elementName); |
665 } | 671 } |
666 return _fixComplexReference(name, currentLibrary, currentClass, currentMember) ; | 672 return _fixComplexReference(name, currentLibrary, currentClass, currentMember) ; |
667 } | 673 } |
668 | 674 |
669 /// Returns a map of [Variable] objects constructed from [mirrorMap]. | 675 /// Returns a map of [Variable] objects constructed from [mirrorMap]. |
670 Map<String, Variable> _variables(Map<String, VariableMirror> mirrorMap) { | 676 Map<String, Variable> _variables(Iterable<VariableMirror> mirrors) { |
671 var data = {}; | 677 var data = {}; |
672 // TODO(janicejl): When map to map feature is created, replace the below with | 678 // TODO(janicejl): When map to map feature is created, replace the below with |
673 // a filter. Issue(#9590). | 679 // a filter. Issue(#9590). |
floitsch
2014/01/28 19:21:53
Either rewrite TODO, or just do the switch.
| |
674 mirrorMap.forEach((String mirrorName, VariableMirror mirror) { | 680 mirrors.forEach((VariableMirror mirror) { |
675 _currentMember = mirror; | 681 _currentMember = mirror; |
676 if (_includePrivate || !_isHidden(mirror)) { | 682 if (_includePrivate || !_isHidden(mirror)) { |
683 var mirrorName = dart2js_util.nameOf(mirror); | |
677 entityMap[docName(mirror)] = new Variable(mirrorName, mirror.isFinal, | 684 entityMap[docName(mirror)] = new Variable(mirrorName, mirror.isFinal, |
678 mirror.isStatic, mirror.isConst, _type(mirror.type), | 685 mirror.isStatic, mirror.isConst, _type(mirror.type), |
679 _commentToHtml(mirror), _annotations(mirror), docName(mirror), | 686 _commentToHtml(mirror), _annotations(mirror), docName(mirror), |
680 _isHidden(mirror), docName(mirror.owner)); | 687 _isHidden(mirror), docName(mirror.owner)); |
681 data[mirrorName] = entityMap[docName(mirror)]; | 688 data[mirrorName] = entityMap[docName(mirror)]; |
682 } | 689 } |
683 }); | 690 }); |
684 return data; | 691 return data; |
685 } | 692 } |
686 | 693 |
687 /// Returns a map of [Method] objects constructed from [mirrorMap]. | 694 /// Returns a map of [Method] objects constructed from [mirrorMap]. |
688 MethodGroup _methods(Map<String, MethodMirror> mirrorMap) { | 695 MethodGroup _methods(Iterable<MethodMirror> mirrors) { |
689 var group = new MethodGroup(); | 696 var group = new MethodGroup(); |
690 mirrorMap.forEach((String mirrorName, MethodMirror mirror) { | 697 mirrors.forEach((MethodMirror mirror) { |
691 if (_includePrivate || !mirror.isPrivate) { | 698 if (_includePrivate || !mirror.isPrivate) { |
692 group.addMethod(mirror); | 699 group.addMethod(mirror); |
693 } | 700 } |
694 }); | 701 }); |
695 return group; | 702 return group; |
696 } | 703 } |
697 | 704 |
698 /// Returns the [Class] for the given [mirror] has already been created, and if | 705 /// Returns the [Class] for the given [mirror] has already been created, and if |
699 /// it does not exist, creates it. | 706 /// it does not exist, creates it. |
700 Class _class(ClassMirror mirror) { | 707 Class _class(ClassSourceMirror mirror) { |
701 var clazz = entityMap[docName(mirror)]; | 708 var clazz = entityMap[docName(mirror)]; |
702 if (clazz == null) { | 709 if (clazz == null) { |
710 var mirrorName = dart2js_util.nameOf(mirror); | |
703 var superclass = mirror.superclass != null ? | 711 var superclass = mirror.superclass != null ? |
704 _class(mirror.superclass) : null; | 712 _class(mirror.superclass) : null; |
705 var interfaces = | 713 var interfaces = |
706 mirror.superinterfaces.map((interface) => _class(interface)); | 714 mirror.superinterfaces.map((interface) => _class(interface)); |
707 clazz = new Class(mirror.simpleName, superclass, _commentToHtml(mirror), | 715 clazz = new Class(mirrorName, superclass, _commentToHtml(mirror), |
708 interfaces.toList(), _variables(mirror.variables), | 716 interfaces.toList(), |
709 _methods(mirror.methods), _annotations(mirror), _generics(mirror), | 717 _variables(dart2js_util.variablesOf(mirror.declarations)), |
718 _methods(dart2js_util.methodsOf(mirror.declarations)), | |
719 _annotations(mirror), _generics(mirror), | |
710 docName(mirror), _isHidden(mirror), docName(mirror.owner), | 720 docName(mirror), _isHidden(mirror), docName(mirror.owner), |
711 mirror.isAbstract); | 721 mirror.isAbstract); |
712 if (superclass != null) clazz.addInherited(superclass); | 722 if (superclass != null) clazz.addInherited(superclass); |
713 interfaces.forEach((interface) => clazz.addInherited(interface)); | 723 interfaces.forEach((interface) => clazz.addInherited(interface)); |
714 entityMap[docName(mirror)] = clazz; | 724 entityMap[docName(mirror)] = clazz; |
715 } | 725 } |
716 return clazz; | 726 return clazz; |
717 } | 727 } |
718 | 728 |
719 /// Returns a map of [Class] objects constructed from [mirrorMap]. | 729 /// Returns a map of [Class] objects constructed from [mirrorMap]. |
720 ClassGroup _classes(Map<String, ClassMirror> mirrorMap) { | 730 ClassGroup _classes(Iterable<TypeMirror> mirrors) { |
721 var group = new ClassGroup(); | 731 var group = new ClassGroup(); |
722 mirrorMap.forEach((String mirrorName, ClassMirror mirror) { | 732 mirrors.forEach(group.addClass); |
723 group.addClass(mirror); | |
724 }); | |
725 return group; | 733 return group; |
726 } | 734 } |
727 | 735 |
728 /// Returns a map of [Parameter] objects constructed from [mirrorList]. | 736 /// Returns a map of [Parameter] objects constructed from [mirrorList]. |
729 Map<String, Parameter> _parameters(List<ParameterMirror> mirrorList) { | 737 Map<String, Parameter> _parameters(List<ParameterMirror> mirrorList) { |
730 var data = {}; | 738 var data = {}; |
731 mirrorList.forEach((ParameterMirror mirror) { | 739 mirrorList.forEach((ParameterMirror mirror) { |
740 var mirrorName = dart2js_util.nameOf(mirror); | |
732 _currentMember = mirror; | 741 _currentMember = mirror; |
733 data[mirror.simpleName] = new Parameter(mirror.simpleName, | 742 data[mirrorName] = new Parameter(mirrorName, |
734 mirror.isOptional, mirror.isNamed, mirror.hasDefaultValue, | 743 mirror.isOptional, mirror.isNamed, mirror.hasDefaultValue, |
735 _type(mirror.type), mirror.defaultValue, | 744 _type(mirror.type), '${mirror.defaultValue}', |
736 _annotations(mirror)); | 745 _annotations(mirror)); |
737 }); | 746 }); |
738 return data; | 747 return data; |
739 } | 748 } |
740 | 749 |
741 /// Returns a map of [Generic] objects constructed from the class mirror. | 750 /// Returns a map of [Generic] objects constructed from the class mirror. |
floitsch
2014/01/28 19:21:53
from the type mirror.
| |
742 Map<String, Generic> _generics(ClassMirror mirror) { | 751 Map<String, Generic> _generics(TypeMirror mirror) { |
743 return new Map.fromIterable(mirror.typeVariables, | 752 return new Map.fromIterable(mirror.typeVariables, |
744 key: (e) => e.toString(), | 753 key: (e) => e.toString(), |
745 value: (e) => new Generic(e.toString(), e.upperBound.qualifiedName)); | 754 value: (e) => new Generic(e.toString(), e.upperBound.qualifiedName)); |
746 } | 755 } |
747 | 756 |
748 /// Returns a single [Type] object constructed from the Method.returnType | 757 /// Returns a single [Type] object constructed from the Method.returnType |
749 /// Type mirror. | 758 /// Type mirror. |
750 Type _type(TypeMirror mirror) { | 759 Type _type(TypeMirror mirror) { |
751 return new Type(docName(mirror), _typeGenerics(mirror)); | 760 return new Type(docName(mirror), _typeGenerics(mirror)); |
752 } | 761 } |
753 | 762 |
754 /// Returns a list of [Type] objects constructed from TypeMirrors. | 763 /// Returns a list of [Type] objects constructed from TypeMirrors. |
755 List<Type> _typeGenerics(TypeMirror mirror) { | 764 List<Type> _typeGenerics(TypeMirror mirror) { |
756 if (mirror is ClassMirror && !mirror.isTypedef) { | 765 if (mirror is ClassMirror) { |
757 var innerList = []; | 766 var innerList = []; |
758 mirror.typeArguments.forEach((e) { | 767 mirror.typeArguments.forEach((e) { |
759 innerList.add(new Type(docName(e), _typeGenerics(e))); | 768 innerList.add(new Type(docName(e), _typeGenerics(e))); |
760 }); | 769 }); |
761 return innerList; | 770 return innerList; |
762 } | 771 } |
763 return []; | 772 return []; |
764 } | 773 } |
765 | 774 |
766 /// Writes text to a file in the 'docs' directory. | 775 /// Writes text to a file in the 'docs' directory. |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1028 }; | 1037 }; |
1029 } | 1038 } |
1030 | 1039 |
1031 /// A container to categorize classes into the following groups: abstract | 1040 /// A container to categorize classes into the following groups: abstract |
1032 /// classes, regular classes, typedefs, and errors. | 1041 /// classes, regular classes, typedefs, and errors. |
1033 class ClassGroup { | 1042 class ClassGroup { |
1034 Map<String, Class> classes = {}; | 1043 Map<String, Class> classes = {}; |
1035 Map<String, Typedef> typedefs = {}; | 1044 Map<String, Typedef> typedefs = {}; |
1036 Map<String, Class> errors = {}; | 1045 Map<String, Class> errors = {}; |
1037 | 1046 |
1038 void addClass(ClassMirror mirror) { | 1047 void addClass(TypeMirror mirror) { |
1039 _currentClass = mirror; | 1048 _currentClass = mirror; |
1040 if (mirror.isTypedef) { | 1049 var mirrorName = dart2js_util.nameOf(mirror); |
1050 if (mirror is TypedefMirror) { | |
1041 // This is actually a Dart2jsTypedefMirror, and it does define value, | 1051 // This is actually a Dart2jsTypedefMirror, and it does define value, |
1042 // but we don't have visibility to that type. | 1052 // but we don't have visibility to that type. |
1043 var mirror = _currentClass; | 1053 //var mirror = _currentClass; |
1044 if (_includePrivate || !mirror.isPrivate) { | 1054 if (_includePrivate || !mirror.isPrivate) { |
1045 entityMap[docName(mirror)] = new Typedef(mirror.simpleName, | 1055 entityMap[docName(mirror)] = new Typedef(mirrorName, |
1046 docName(mirror.value.returnType), _commentToHtml(mirror), | 1056 docName(mirror.referent.returnType), _commentToHtml(mirror), |
1047 _generics(mirror), _parameters(mirror.value.parameters), | 1057 _generics(mirror), _parameters(mirror.referent.parameters), |
1048 _annotations(mirror), docName(mirror), _isHidden(mirror), | 1058 _annotations(mirror), docName(mirror), _isHidden(mirror), |
1049 docName(mirror.owner)); | 1059 docName(mirror.owner)); |
1050 typedefs[mirror.simpleName] = entityMap[docName(mirror)]; | 1060 typedefs[mirrorName] = entityMap[docName(mirror)]; |
1051 } | 1061 } |
1052 } else { | 1062 } else if (mirror is ClassMirror) { |
1053 var clazz = _class(mirror); | 1063 var clazz = _class(mirror); |
1054 | 1064 |
1055 // Adding inherited parent variables and methods. | 1065 // Adding inherited parent variables and methods. |
1056 clazz.parent().forEach((parent) { | 1066 clazz.parent().forEach((parent) { |
1057 if (_isVisible(clazz)) { | 1067 if (_isVisible(clazz)) { |
1058 parent.addSubclass(clazz); | 1068 parent.addSubclass(clazz); |
1059 } | 1069 } |
1060 }); | 1070 }); |
1061 | 1071 |
1062 clazz.ensureComments(); | 1072 clazz.ensureComments(); |
1063 | 1073 |
1064 if (clazz.isError()) { | 1074 if (clazz.isError()) { |
1065 errors[mirror.simpleName] = clazz; | 1075 errors[mirrorName] = clazz; |
1066 } else if (mirror.isClass) { | |
1067 classes[mirror.simpleName] = clazz; | |
1068 } else { | 1076 } else { |
1069 throw new ArgumentError('${mirror.simpleName} - no class type match. '); | 1077 classes[mirrorName] = clazz; |
1070 } | 1078 } |
1079 } else { | |
1080 throw new ArgumentError('${mirrorName} - no class type match. '); | |
1071 } | 1081 } |
1072 } | 1082 } |
1073 | 1083 |
1074 /// Checks if the given name is a key for any of the Class Maps. | 1084 /// Checks if the given name is a key for any of the Class Maps. |
1075 bool containsKey(String name) { | 1085 bool containsKey(String name) { |
1076 return classes.containsKey(name) || errors.containsKey(name); | 1086 return classes.containsKey(name) || errors.containsKey(name); |
1077 } | 1087 } |
1078 | 1088 |
1079 Map toMap() => { | 1089 Map toMap() => { |
1080 'class': classes.values.where(_isVisible) | 1090 'class': classes.values.where(_isVisible) |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1206 /// A container to categorize methods into the following groups: setters, | 1216 /// A container to categorize methods into the following groups: setters, |
1207 /// getters, constructors, operators, regular methods. | 1217 /// getters, constructors, operators, regular methods. |
1208 class MethodGroup { | 1218 class MethodGroup { |
1209 Map<String, Method> setters = {}; | 1219 Map<String, Method> setters = {}; |
1210 Map<String, Method> getters = {}; | 1220 Map<String, Method> getters = {}; |
1211 Map<String, Method> constructors = {}; | 1221 Map<String, Method> constructors = {}; |
1212 Map<String, Method> operators = {}; | 1222 Map<String, Method> operators = {}; |
1213 Map<String, Method> regularMethods = {}; | 1223 Map<String, Method> regularMethods = {}; |
1214 | 1224 |
1215 void addMethod(MethodMirror mirror) { | 1225 void addMethod(MethodMirror mirror) { |
1216 var method = new Method(mirror.simpleName, mirror.isStatic, | 1226 var methodName = dart2js_util.nameOf(mirror); |
1227 var method = new Method(methodName, mirror.isStatic, | |
1217 mirror.isAbstract, mirror.isConstConstructor, _type(mirror.returnType), | 1228 mirror.isAbstract, mirror.isConstConstructor, _type(mirror.returnType), |
1218 _commentToHtml(mirror), _parameters(mirror.parameters), | 1229 _commentToHtml(mirror), _parameters(mirror.parameters), |
1219 _annotations(mirror), docName(mirror), _isHidden(mirror), | 1230 _annotations(mirror), docName(mirror), _isHidden(mirror), |
1220 docName(mirror.owner), mirror.isConstructor, mirror.isGetter, | 1231 docName(mirror.owner), mirror.isConstructor, mirror.isGetter, |
1221 mirror.isSetter, mirror.isOperator); | 1232 mirror.isSetter, mirror.isOperator); |
1222 entityMap[docName(mirror)] = method; | 1233 entityMap[docName(mirror)] = method; |
1223 _currentMember = mirror; | 1234 _currentMember = mirror; |
1224 if (mirror.isSetter) { | 1235 if (mirror.isSetter) { |
1225 setters[mirror.simpleName] = method; | 1236 setters[methodName] = method; |
1226 } else if (mirror.isGetter) { | 1237 } else if (mirror.isGetter) { |
1227 getters[mirror.simpleName] = method; | 1238 getters[methodName] = method; |
1228 } else if (mirror.isConstructor) { | 1239 } else if (mirror.isConstructor) { |
1229 constructors[mirror.simpleName] = method; | 1240 constructors[methodName] = method; |
1230 } else if (mirror.isOperator) { | 1241 } else if (mirror.isOperator) { |
1231 operators[mirror.simpleName] = method; | 1242 operators[methodName] = method; |
1232 } else if (mirror.isRegularMethod) { | 1243 } else if (mirror.isRegularMethod) { |
1233 regularMethods[mirror.simpleName] = method; | 1244 regularMethods[methodName] = method; |
1234 } else { | 1245 } else { |
1235 throw new ArgumentError('${mirror.simpleName} - no method type match'); | 1246 throw new ArgumentError('${methodName} - no method type match'); |
1236 } | 1247 } |
1237 } | 1248 } |
1238 | 1249 |
1239 void addInherited(Class parent) { | 1250 void addInherited(Class parent) { |
1240 setters.addAll(parent.inheritedMethods.setters); | 1251 setters.addAll(parent.inheritedMethods.setters); |
1241 setters.addAll(_filterStatics(parent.methods.setters)); | 1252 setters.addAll(_filterStatics(parent.methods.setters)); |
1242 getters.addAll(parent.inheritedMethods.getters); | 1253 getters.addAll(parent.inheritedMethods.getters); |
1243 getters.addAll(_filterStatics(parent.methods.getters)); | 1254 getters.addAll(_filterStatics(parent.methods.getters)); |
1244 operators.addAll(parent.inheritedMethods.operators); | 1255 operators.addAll(parent.inheritedMethods.operators); |
1245 operators.addAll(_filterStatics(parent.methods.operators)); | 1256 operators.addAll(_filterStatics(parent.methods.operators)); |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1365 'name': qualifiedName, | 1376 'name': qualifiedName, |
1366 'parameters': parameters | 1377 'parameters': parameters |
1367 }; | 1378 }; |
1368 } | 1379 } |
1369 | 1380 |
1370 /// Given a mirror, returns its qualified name, but following the conventions | 1381 /// Given a mirror, returns its qualified name, but following the conventions |
1371 /// we're using in Dartdoc, which is that library names with dots in them | 1382 /// we're using in Dartdoc, which is that library names with dots in them |
1372 /// have them replaced with hyphens. | 1383 /// have them replaced with hyphens. |
1373 String docName(DeclarationMirror m) { | 1384 String docName(DeclarationMirror m) { |
1374 if (m is LibraryMirror) { | 1385 if (m is LibraryMirror) { |
1375 return (m as LibraryMirror).qualifiedName.replaceAll('.','-'); | 1386 return dart2js_util.qualifiedNameOf(m).replaceAll('.','-'); |
1376 } | 1387 } |
1377 var owner = m.owner; | 1388 var owner = m.owner; |
1378 if (owner == null) return m.qualifiedName; | 1389 if (owner == null) return dart2js_util.qualifiedNameOf(m); |
1379 // For the unnamed constructor we just return the class name. | 1390 // For the unnamed constructor we just return the class name. |
1380 if (m.simpleName == '') return docName(owner); | 1391 if (m.simpleName == '') return docName(owner); |
1381 return docName(owner) + '.' + m.simpleName; | 1392 return docName(owner) + '.' + dart2js_util.nameOf(m); |
1382 } | 1393 } |
1383 | 1394 |
1384 /// Remove statics from the map of inherited items before adding them. | 1395 /// Remove statics from the map of inherited items before adding them. |
1385 Map _filterStatics(Map items) { | 1396 Map _filterStatics(Map items) { |
1386 var result = {}; | 1397 var result = {}; |
1387 items.forEach((name, item) { | 1398 items.forEach((name, item) { |
1388 if (!item.isStatic) { | 1399 if (!item.isStatic) { |
1389 result[name] = item; | 1400 result[name] = item; |
1390 } | 1401 } |
1391 }); | 1402 }); |
1392 return result; | 1403 return result; |
1393 } | 1404 } |
OLD | NEW |