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] |
| 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 import 'package:logging/logging.dart'; | 20 import 'package:logging/logging.dart'; |
| 21 import 'package:markdown/markdown.dart' as markdown; | 21 import 'package:markdown/markdown.dart' as markdown; |
| 22 import 'package:path/path.dart' as path; | 22 import 'package:path/path.dart' as path; |
| 23 import 'package:yaml/yaml.dart'; | 23 import 'package:yaml/yaml.dart'; |
| 24 | 24 |
| 25 import 'dart2yaml.dart'; | 25 import 'dart2yaml.dart'; |
| 26 import 'src/io.dart'; | 26 import 'src/io.dart'; |
| 27 import 'src/mdn.dart'; | |
| 28 import 'src/models.dart'; | |
| 29 import 'src/utils.dart'; | |
| 30 | |
| 27 import '../../../sdk/lib/_internal/compiler/compiler.dart' as api; | 31 import '../../../sdk/lib/_internal/compiler/compiler.dart' as api; |
| 28 import '../../../sdk/lib/_internal/compiler/implementation/filenames.dart'; | 32 import '../../../sdk/lib/_internal/compiler/implementation/filenames.dart'; |
| 29 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirro rs.dart' | 33 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirro rs.dart' |
| 30 as dart2js_mirrors; | 34 as dart2js_mirrors; |
| 31 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/analyze.dart' | 35 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/analyze.dart' |
| 32 as dart2js; | 36 as dart2js; |
| 33 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/source_mirror s.dart'; | 37 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/source_mirror s.dart'; |
| 34 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors_util. dart' | 38 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors_util. dart' |
| 35 as dart2js_util; | 39 as dart2js_util; |
| 36 import '../../../sdk/lib/_internal/compiler/implementation/source_file_provider. dart'; | 40 import '../../../sdk/lib/_internal/compiler/implementation/source_file_provider. dart'; |
| 37 import '../../../sdk/lib/_internal/libraries.dart'; | 41 import '../../../sdk/lib/_internal/libraries.dart'; |
| 38 | 42 |
| 39 const _DEFAULT_OUTPUT_DIRECTORY = 'docs'; | 43 const _DEFAULT_OUTPUT_DIRECTORY = 'docs'; |
| 40 | 44 |
| 41 /// Annotations that we do not display in the viewer. | 45 /// Annotations that we do not display in the viewer. |
| 42 const List<String> _SKIPPED_ANNOTATIONS = const [ | 46 const List<String> _SKIPPED_ANNOTATIONS = const [ |
| 43 'metadata.DocsEditable', '_js_helper.JSName', '_js_helper.Creates', | 47 'metadata.DocsEditable', '_js_helper.JSName', '_js_helper.Creates', |
| 44 '_js_helper.Returns']; | 48 '_js_helper.Returns']; |
| 45 | 49 |
| 46 /// Support for [:foo:]-style code comments to the markdown parser. | 50 /// Support for [:foo:]-style code comments to the markdown parser. |
| 47 List<markdown.InlineSyntax> _MARKDOWN_SYNTAXES = | 51 final List<markdown.InlineSyntax> _MARKDOWN_SYNTAXES = |
| 48 [new markdown.CodeSyntax(r'\[:\s?((?:.|\n)*?)\s?:\]')]; | 52 [new markdown.CodeSyntax(r'\[:\s?((?:.|\n)*?)\s?:\]')]; |
| 49 | 53 |
| 50 /// If we can't find the SDK introduction text, which will happen if running | 54 /// If we can't find the SDK introduction text, which will happen if running |
| 51 /// from a snapshot and using --parse-sdk or --include-sdk, then use this | 55 /// from a snapshot and using --parse-sdk or --include-sdk, then use this |
| 52 /// hard-coded version. This should be updated to be consistent with the text | 56 /// hard-coded version. This should be updated to be consistent with the text |
| 53 /// in docgen/doc/sdk-introduction.md | 57 /// in docgen/doc/sdk-introduction.md |
| 54 const _DEFAULT_SDK_INTRODUCTION = """ | 58 const _DEFAULT_SDK_INTRODUCTION = """ |
| 55 Welcome to the Dart API reference documentation, | 59 Welcome to the Dart API reference documentation, |
| 56 covering the official Dart API libraries. | 60 covering the official Dart API libraries. |
| 57 Some of the most fundamental Dart libraries include: | 61 Some of the most fundamental Dart libraries include: |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 211 String get packagePrefix => packageName == null || packageName.isEmpty ? | 215 String get packagePrefix => packageName == null || packageName.isEmpty ? |
| 212 '' : '$packageName/'; | 216 '' : '$packageName/'; |
| 213 | 217 |
| 214 LibraryMirror _getOwningLibraryFromMirror(DeclarationMirror mirror) { | 218 LibraryMirror _getOwningLibraryFromMirror(DeclarationMirror mirror) { |
| 215 if (mirror is LibraryMirror) return mirror; | 219 if (mirror is LibraryMirror) return mirror; |
| 216 if (mirror == null) return null; | 220 if (mirror == null) return null; |
| 217 return _getOwningLibraryFromMirror(mirror.owner); | 221 return _getOwningLibraryFromMirror(mirror.owner); |
| 218 } | 222 } |
| 219 } | 223 } |
| 220 | 224 |
| 221 /// Docgen representation of an item to be documented, that wraps around a | |
| 222 /// dart2js mirror. | |
| 223 abstract class MirrorBased { | |
| 224 /// The original dart2js mirror around which this object wraps. | |
| 225 DeclarationMirror get mirror; | |
| 226 | |
| 227 /// Returns a list of meta annotations assocated with a mirror. | |
| 228 static List<Annotation> _createAnnotations(DeclarationMirror mirror, | |
| 229 Library owningLibrary) { | |
| 230 var annotationMirrors = mirror.metadata.where((e) => | |
| 231 e is dart2js_mirrors.Dart2JsConstructedConstantMirror); | |
| 232 var annotations = []; | |
| 233 annotationMirrors.forEach((annotation) { | |
| 234 var docgenAnnotation = new Annotation(annotation, owningLibrary); | |
| 235 if (!_SKIPPED_ANNOTATIONS.contains( | |
| 236 dart2js_util.qualifiedNameOf(docgenAnnotation.mirror))) { | |
| 237 annotations.add(docgenAnnotation); | |
| 238 } | |
| 239 }); | |
| 240 return annotations; | |
| 241 } | |
| 242 } | |
| 243 | |
| 244 /// Top level documentation traversal and generation object. | 225 /// Top level documentation traversal and generation object. |
| 245 /// | 226 /// |
| 246 /// Yes, everything in this class is used statically so this technically doesn't | 227 /// Yes, everything in this class is used statically so this technically doesn't |
| 247 /// need to be its own class, but it's grouped together for semantic separation | 228 /// need to be its own class, but it's grouped together for semantic separation |
| 248 /// from the other classes and functionality in this library. | 229 /// from the other classes and functionality in this library. |
| 249 class _Generator { | 230 class _Generator { |
| 250 /// The directory where the output docs are generated. | 231 /// The directory where the output docs are generated. |
| 251 static String _outputDirectory; | 232 static String _outputDirectory; |
| 252 | 233 |
| 253 /// This is set from the command line arguments flag --include-private | 234 /// This is set from the command line arguments flag --include-private |
| (...skipping 582 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 836 }); | 817 }); |
| 837 } | 818 } |
| 838 }, | 819 }, |
| 839 onError: (e) { | 820 onError: (e) { |
| 840 print('HttpServer: an error occured $e'); | 821 print('HttpServer: an error occured $e'); |
| 841 }); | 822 }); |
| 842 }); | 823 }); |
| 843 } | 824 } |
| 844 } | 825 } |
| 845 | 826 |
| 827 /** Walk up the owner chain to find the owning library. */ | |
|
Emily Fortuna
2014/03/06 22:05:38
Consistency! Triple slashes are everywhere through
kevmoo
2014/03/06 22:20:17
Sticking with copy-paste the old style for this CL
| |
| 828 Library _getOwningLibrary(Indexable indexable) { | |
|
Emily Fortuna
2014/03/06 22:05:38
make static function instead of global?
kevmoo
2014/03/06 22:20:17
If the static uses privates on the class or make u
Alan Knight
2014/03/12 18:17:56
Why static or global at all? Why not just have thi
kevmoo
2014/03/17 02:01:29
Done.
| |
| 829 if (indexable is Library) return indexable; | |
| 830 return _getOwningLibrary(indexable.owner); | |
| 831 } | |
| 832 | |
| 846 /// An item that is categorized in our mirrorToDocgen map, as a distinct, | 833 /// An item that is categorized in our mirrorToDocgen map, as a distinct, |
| 847 /// searchable element. | 834 /// searchable element. |
| 848 /// | 835 /// |
| 849 /// These are items that refer to concrete entities (a Class, for example, | 836 /// These are items that refer to concrete entities (a Class, for example, |
| 850 /// but not a Type, which is a "pointer" to a class) that we wish to be | 837 /// but not a Type, which is a "pointer" to a class) that we wish to be |
| 851 /// globally resolvable. This includes things such as class methods and | 838 /// globally resolvable. This includes things such as class methods and |
| 852 /// variables, but parameters for methods are not "Indexable" as we do not want | 839 /// variables, but parameters for methods are not "Indexable" as we do not want |
| 853 /// the user to be able to search for a method based on its parameter names! | 840 /// the user to be able to search for a method based on its parameter names! |
| 854 /// The set of indexable items also includes Typedefs, since the user can refer | 841 /// The set of indexable items also includes Typedefs, since the user can refer |
| 855 /// to them as concrete entities in a particular scope. | 842 /// to them as concrete entities in a particular scope. |
| 856 abstract class Indexable extends MirrorBased { | 843 abstract class Indexable extends MirrorBased { |
| 857 /// The dart:core library, which contains all types that are always available | 844 /// The dart:core library, which contains all types that are always available |
| 858 /// without import. | 845 /// without import. |
| 859 static Library _coreLibrary; | 846 static Library _coreLibrary; |
| 860 | 847 |
| 861 /// Set of libraries declared in the SDK, so libraries that can be accessed | 848 /// Set of libraries declared in the SDK, so libraries that can be accessed |
| 862 /// when running dart by default. | 849 /// when running dart by default. |
| 863 static Iterable<LibraryMirror> _sdkLibraries; | 850 static Iterable<LibraryMirror> _sdkLibraries; |
| 864 | 851 |
| 852 final DeclarationMirror mirror; | |
|
Alan Knight
2014/03/12 18:17:56
If we're re-formatting these to have their own lin
kevmoo
2014/03/17 02:01:29
Not sure what the docs should be. Reverting whites
| |
| 853 | |
| 854 final bool isPrivate; | |
| 855 | |
| 865 String get qualifiedName => fileName; | 856 String get qualifiedName => fileName; |
| 866 bool isPrivate; | 857 |
| 867 DeclarationMirror mirror; | |
| 868 /// The comment text pre-resolution. We keep this around because inherited | 858 /// The comment text pre-resolution. We keep this around because inherited |
| 869 /// methods need to resolve links differently from the superclass. | 859 /// methods need to resolve links differently from the superclass. |
| 870 String _unresolvedComment = ''; | 860 String _unresolvedComment = ''; |
| 871 | 861 |
| 872 // TODO(janicejl): Make MDN content generic or pluggable. Maybe move | |
| 873 // MDN-specific code to its own library that is imported into the default | |
| 874 // impl? | |
| 875 /// Map of all the comments for dom elements from MDN. | |
| 876 static Map _mdn; | |
| 877 | 862 |
| 878 /// Index of all the dart2js mirrors examined to corresponding MirrorBased | 863 /// Index of all the dart2js mirrors examined to corresponding MirrorBased |
| 879 /// docgen objects. | 864 /// docgen objects. |
| 880 /// | 865 /// |
| 881 /// Used for lookup because of the dart2js mirrors exports | 866 /// Used for lookup because of the dart2js mirrors exports |
| 882 /// issue. The second level map is indexed by owner docName for faster lookup. | 867 /// issue. The second level map is indexed by owner docName for faster lookup. |
| 883 /// Why two levels of lookup? Speed, man. Speed. | 868 /// Why two levels of lookup? Speed, man. Speed. |
| 884 static Map<String, Map<String, Set<Indexable>>> _mirrorToDocgen = | 869 static Map<String, Map<String, Set<Indexable>>> _mirrorToDocgen = |
| 885 new Map<String, Map<String, Set<Indexable>>>(); | 870 new Map<String, Map<String, Set<Indexable>>>(); |
| 886 | 871 |
| 887 Indexable(this.mirror) { | 872 Indexable(DeclarationMirror mirror) |
| 888 this.isPrivate = _isHidden(mirror); | 873 : this.mirror = mirror, |
| 874 this.isPrivate = isHidden(mirror) { | |
| 889 | 875 |
| 890 var map = _mirrorToDocgen[dart2js_util.qualifiedNameOf(this.mirror)]; | 876 var map = _mirrorToDocgen[dart2js_util.qualifiedNameOf(this.mirror)]; |
| 891 if (map == null) map = new Map<String, Set<Indexable>>(); | 877 if (map == null) map = new Map<String, Set<Indexable>>(); |
| 892 | 878 |
| 893 var set = map[owner.docName]; | 879 var set = map[owner.docName]; |
| 894 if (set == null) set = new Set<Indexable>(); | 880 if (set == null) set = new Set<Indexable>(); |
| 895 set.add(this); | 881 set.add(this); |
| 896 map[owner.docName] = set; | 882 map[owner.docName] = set; |
| 897 _mirrorToDocgen[dart2js_util.qualifiedNameOf(this.mirror)] = map; | 883 _mirrorToDocgen[dart2js_util.qualifiedNameOf(this.mirror)] = map; |
| 898 } | 884 } |
| 899 | 885 |
| 900 /** Walk up the owner chain to find the owning library. */ | |
| 901 Library _getOwningLibrary(Indexable indexable) { | |
| 902 if (indexable is Library) return indexable; | |
| 903 return _getOwningLibrary(indexable.owner); | |
| 904 } | |
| 905 | |
| 906 static _initializeTopLevelLibraries(MirrorSystem mirrorSystem) { | 886 static _initializeTopLevelLibraries(MirrorSystem mirrorSystem) { |
| 907 _sdkLibraries = mirrorSystem.libraries.values.where( | 887 _sdkLibraries = mirrorSystem.libraries.values.where( |
| 908 (each) => each.uri.scheme == 'dart'); | 888 (each) => each.uri.scheme == 'dart'); |
| 909 _coreLibrary = new Library(_sdkLibraries.singleWhere((lib) => | 889 _coreLibrary = new Library(_sdkLibraries.singleWhere((lib) => |
| 910 lib.uri.toString().startsWith('dart:core'))); | 890 lib.uri.toString().startsWith('dart:core'))); |
| 911 } | 891 } |
| 912 | 892 |
| 913 /// Returns this object's qualified name, but following the conventions | 893 /// Returns this object's qualified name, but following the conventions |
| 914 /// we're using in Dartdoc, which is that library names with dots in them | 894 /// we're using in Dartdoc, which is that library names with dots in them |
| 915 /// have them replaced with hyphens. | 895 /// have them replaced with hyphens. |
| 916 String get docName; | 896 String get docName; |
| 917 | 897 |
| 918 /// Converts all [foo] references in comments to <a>libraryName.foo</a>. | 898 /// Converts all [foo] references in comments to <a>libraryName.foo</a>. |
| 919 markdown.Node fixReference(String name) { | 899 markdown.Node fixReference(String name) { |
| 920 // Attempt the look up the whole name up in the scope. | 900 // Attempt the look up the whole name up in the scope. |
| 921 String elementName = findElementInScope(name); | 901 String elementName = findElementInScope(name); |
| 922 if (elementName != null) { | 902 if (elementName != null) { |
| 923 return new markdown.Element.text('a', elementName); | 903 return new markdown.Element.text('a', elementName); |
| 924 } | 904 } |
| 925 return _fixComplexReference(name); | 905 return _fixComplexReference(name); |
| 926 } | 906 } |
| 927 | 907 |
| 928 /// Look for the specified name starting with the current member, and | 908 /// Look for the specified name starting with the current member, and |
| 929 /// progressively working outward to the current library scope. | 909 /// progressively working outward to the current library scope. |
| 930 String findElementInScope(String name) => | 910 String findElementInScope(String name) => |
| 931 _findElementInScope(name, packagePrefix); | 911 _findElementInScope(name, packagePrefix); |
| 932 | 912 |
| 933 /// For a given name, determine if we need to resolve it as a qualified name | |
| 934 /// or a simple name in the source mirors. | |
| 935 static determineLookupFunc(name) => name.contains('.') ? | |
| 936 dart2js_util.lookupQualifiedInScope : | |
| 937 (mirror, name) => mirror.lookupInScope(name); | |
| 938 | |
| 939 /// The reference to this element based on where it is printed as a | 913 /// The reference to this element based on where it is printed as a |
| 940 /// documentation file and also the unique URL to refer to this item. | 914 /// documentation file and also the unique URL to refer to this item. |
| 941 /// | 915 /// |
| 942 /// The qualified name (for URL purposes) and the file name are the same, | 916 /// The qualified name (for URL purposes) and the file name are the same, |
| 943 /// of the form packageName/ClassName or packageName/ClassName.methodName. | 917 /// of the form packageName/ClassName or packageName/ClassName.methodName. |
| 944 /// This defines both the URL and the directory structure. | 918 /// This defines both the URL and the directory structure. |
| 945 String get fileName => packagePrefix + ownerPrefix + name; | 919 String get fileName => packagePrefix + ownerPrefix + name; |
| 946 | 920 |
| 947 /// The full docName of the owner element, appended with a '.' for this | 921 /// The full docName of the owner element, appended with a '.' for this |
| 948 /// object's name to be appended. | 922 /// object's name to be appended. |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 979 /// | 953 /// |
| 980 /// "Owning" is defined as the object one scope-level above which this item | 954 /// "Owning" is defined as the object one scope-level above which this item |
| 981 /// is defined. Ex: The owner for a top level class, would be its enclosing | 955 /// is defined. Ex: The owner for a top level class, would be its enclosing |
| 982 /// library. The owner of a local variable in a method would be the enclosing | 956 /// library. The owner of a local variable in a method would be the enclosing |
| 983 /// method. | 957 /// method. |
| 984 Indexable get owner => new DummyMirror(mirror.owner); | 958 Indexable get owner => new DummyMirror(mirror.owner); |
| 985 | 959 |
| 986 /// Generates MDN comments from database.json. | 960 /// Generates MDN comments from database.json. |
| 987 String _mdnComment(); | 961 String _mdnComment(); |
| 988 | 962 |
| 989 /// Generates the MDN Comment for variables and method DOM elements. | |
| 990 String _mdnMemberComment(String type, String member) { | |
| 991 var mdnType = _mdn[type]; | |
| 992 if (mdnType == null) return ''; | |
| 993 var mdnMember = mdnType['members'].firstWhere((e) => e['name'] == member, | |
| 994 orElse: () => null); | |
| 995 if (mdnMember == null) return ''; | |
| 996 if (mdnMember['help'] == null || mdnMember['help'] == '') return ''; | |
| 997 if (mdnMember['url'] == null) return ''; | |
| 998 return _htmlifyMdn(mdnMember['help'], mdnMember['url']); | |
| 999 } | |
| 1000 | |
| 1001 /// Generates the MDN Comment for class DOM elements. | |
| 1002 String _mdnTypeComment(String type) { | |
| 1003 var mdnType = _mdn[type]; | |
| 1004 if (mdnType == null) return ''; | |
| 1005 if (mdnType['summary'] == null || mdnType['summary'] == "") return ''; | |
| 1006 if (mdnType['srcUrl'] == null) return ''; | |
| 1007 return _htmlifyMdn(mdnType['summary'], mdnType['srcUrl']); | |
| 1008 } | |
| 1009 | |
| 1010 /// Encloses the given content in an MDN div and the original source link. | |
| 1011 String _htmlifyMdn(String content, String url) { | |
| 1012 return '<div class="mdn">' + content.trim() + '<p class="mdn-note">' | |
| 1013 '<a href="' + url.trim() + '">from Mdn</a></p></div>'; | |
| 1014 } | |
| 1015 | |
| 1016 /// The type of this member to be used in index.txt. | 963 /// The type of this member to be used in index.txt. |
| 1017 String get typeName => ''; | 964 String get typeName => ''; |
| 1018 | 965 |
| 1019 /// Creates a [Map] with this [Indexable]'s name and a preview comment. | 966 /// Creates a [Map] with this [Indexable]'s name and a preview comment. |
| 1020 Map get previewMap { | 967 Map get previewMap { |
| 1021 var finalMap = { 'name' : name, 'qualifiedName' : qualifiedName }; | 968 var finalMap = { 'name' : name, 'qualifiedName' : qualifiedName }; |
| 1022 var preview = _preview; | 969 var preview = _preview; |
| 1023 if(preview != null) finalMap['preview'] = preview; | 970 if(preview != null) finalMap['preview'] = preview; |
| 1024 return finalMap; | 971 return finalMap; |
| 1025 } | 972 } |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1074 /// Returns a map of [Variable] objects constructed from [mirrorMap]. | 1021 /// Returns a map of [Variable] objects constructed from [mirrorMap]. |
| 1075 /// The optional parameter [containingLibrary] is contains data for variables | 1022 /// The optional parameter [containingLibrary] is contains data for variables |
| 1076 /// defined at the top level of a library (potentially for exporting | 1023 /// defined at the top level of a library (potentially for exporting |
| 1077 /// purposes). | 1024 /// purposes). |
| 1078 Map<String, Variable> _createVariables(Iterable<VariableMirror> mirrors, | 1025 Map<String, Variable> _createVariables(Iterable<VariableMirror> mirrors, |
| 1079 Indexable owner) { | 1026 Indexable owner) { |
| 1080 var data = {}; | 1027 var data = {}; |
| 1081 // TODO(janicejl): When map to map feature is created, replace the below | 1028 // TODO(janicejl): When map to map feature is created, replace the below |
| 1082 // with a filter. Issue(#9590). | 1029 // with a filter. Issue(#9590). |
| 1083 mirrors.forEach((VariableMirror mirror) { | 1030 mirrors.forEach((VariableMirror mirror) { |
| 1084 if (_Generator._includePrivate || !_isHidden(mirror)) { | 1031 if (_Generator._includePrivate || !isHidden(mirror)) { |
| 1085 var mirrorName = dart2js_util.nameOf(mirror); | 1032 var mirrorName = dart2js_util.nameOf(mirror); |
| 1086 data[mirrorName] = new Variable(mirrorName, mirror, owner); | 1033 data[mirrorName] = new Variable(mirrorName, mirror, owner); |
| 1087 } | 1034 } |
| 1088 }); | 1035 }); |
| 1089 return data; | 1036 return data; |
| 1090 } | 1037 } |
| 1091 | 1038 |
| 1092 /// Returns a map of [Method] objects constructed from [mirrorMap]. | 1039 /// Returns a map of [Method] objects constructed from [mirrorMap]. |
| 1093 /// The optional parameter [containingLibrary] is contains data for variables | 1040 /// The optional parameter [containingLibrary] is contains data for variables |
| 1094 /// defined at the top level of a library (potentially for exporting | 1041 /// defined at the top level of a library (potentially for exporting |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 1121 key: (e) => dart2js_util.nameOf(e), | 1068 key: (e) => dart2js_util.nameOf(e), |
| 1122 value: (e) => new Generic(e)); | 1069 value: (e) => new Generic(e)); |
| 1123 } | 1070 } |
| 1124 | 1071 |
| 1125 /// Return an informative [Object.toString] for debugging. | 1072 /// Return an informative [Object.toString] for debugging. |
| 1126 String toString() => "${super.toString()}(${name.toString()})"; | 1073 String toString() => "${super.toString()}(${name.toString()})"; |
| 1127 | 1074 |
| 1128 /// Return a map representation of this type. | 1075 /// Return a map representation of this type. |
| 1129 Map toMap(); | 1076 Map toMap(); |
| 1130 | 1077 |
| 1131 /// A declaration is private if itself is private, or the owner is private. | |
| 1132 // Issue(12202) - A declaration is public even if it's owner is private. | |
| 1133 bool _isHidden(DeclarationMirror mirror) { | |
| 1134 if (mirror is LibraryMirror) { | |
| 1135 return _isLibraryPrivate(mirror); | |
| 1136 } else if (mirror.owner is LibraryMirror) { | |
| 1137 return (mirror.isPrivate || _isLibraryPrivate(mirror.owner) | |
| 1138 || mirror.isNameSynthetic); | |
| 1139 } else { | |
| 1140 return (mirror.isPrivate || _isHidden(mirror.owner) | |
| 1141 || owner.mirror.isNameSynthetic); | |
| 1142 } | |
| 1143 } | |
| 1144 | 1078 |
| 1145 /// Returns true if a library name starts with an underscore, and false | |
| 1146 /// otherwise. | |
| 1147 /// | |
| 1148 /// An example that starts with _ is _js_helper. | |
| 1149 /// An example that contains ._ is dart._collection.dev | |
| 1150 bool _isLibraryPrivate(LibraryMirror mirror) { | |
| 1151 // This method is needed because LibraryMirror.isPrivate returns `false` all | |
| 1152 // the time. | |
| 1153 var sdkLibrary = LIBRARIES[dart2js_util.nameOf(mirror)]; | |
| 1154 if (sdkLibrary != null) { | |
| 1155 return !sdkLibrary.documented; | |
| 1156 } else if (dart2js_util.nameOf(mirror).startsWith('_') || | |
| 1157 dart2js_util.nameOf(mirror).contains('._')) { | |
| 1158 return true; | |
| 1159 } | |
| 1160 return false; | |
| 1161 } | |
| 1162 | 1079 |
| 1163 ////// Top level resolution functions | 1080 ////// Top level resolution functions |
| 1164 /// Converts all [foo] references in comments to <a>libraryName.foo</a>. | 1081 /// Converts all [foo] references in comments to <a>libraryName.foo</a>. |
| 1165 static markdown.Node globalFixReference(String name) { | 1082 static markdown.Node globalFixReference(String name) { |
| 1166 // Attempt the look up the whole name up in the scope. | 1083 // Attempt the look up the whole name up in the scope. |
| 1167 String elementName = _findElementInScope(name, ''); | 1084 String elementName = _findElementInScope(name, ''); |
| 1168 if (elementName != null) { | 1085 if (elementName != null) { |
| 1169 return new markdown.Element.text('a', elementName); | 1086 return new markdown.Element.text('a', elementName); |
| 1170 } | 1087 } |
| 1171 return _fixComplexReference(name); | 1088 return _fixComplexReference(name); |
| 1172 } | 1089 } |
| 1173 | 1090 |
| 1174 /// This is a more complex reference. Try to break up if its of the form A<B> | 1091 /// This is a more complex reference. Try to break up if its of the form A<B> |
| 1175 /// where A is an alphanumeric string and B is an A, a list of B ("B, B, B"), | 1092 /// where A is an alphanumeric string and B is an A, a list of B ("B, B, B"), |
| 1176 /// or of the form A<B>. Note: unlike other the other markdown-style links, | 1093 /// or of the form A<B>. Note: unlike other the other markdown-style links, |
| 1177 /// all text inside the square brackets is treated as part of the link (aka | 1094 /// all text inside the square brackets is treated as part of the link (aka |
| 1178 /// the * is interpreted literally as a *, not as a indicator for bold <em>. | 1095 /// the * is interpreted literally as a *, not as a indicator for bold <em>. |
| 1179 /// | 1096 /// |
| 1180 /// Example: [foo<_bar_>] will produce | 1097 /// Example: [foo<_bar_>] will produce |
| 1181 /// <a>resolvedFoo</a><<a>resolved_bar_</a>> rather than an italicized | 1098 /// <a>resolvedFoo</a><<a>resolved_bar_</a>> rather than an italicized |
| 1182 /// version of resolvedBar. | 1099 /// version of resolvedBar. |
| 1183 static markdown.Node _fixComplexReference(String name) { | 1100 static markdown.Node _fixComplexReference(String name) { |
| 1184 // Parse into multiple elements we can try to resolve. | 1101 // Parse into multiple elements we can try to resolve. |
| 1185 var tokens = _tokenizeComplexReference(name); | 1102 var tokens = tokenizeComplexReference(name); |
| 1186 | 1103 |
| 1187 // Produce an html representation of our elements. Group unresolved and | 1104 // Produce an html representation of our elements. Group unresolved and |
| 1188 // plain text are grouped into "link" elements so they display as code. | 1105 // plain text are grouped into "link" elements so they display as code. |
| 1189 final textElements = [' ', ',', '>', _LESS_THAN]; | 1106 final textElements = [' ', ',', '>', LESS_THAN]; |
| 1190 var accumulatedHtml = ''; | 1107 var accumulatedHtml = ''; |
| 1191 | 1108 |
| 1192 for (var token in tokens) { | 1109 for (var token in tokens) { |
| 1193 bool added = false; | 1110 bool added = false; |
| 1194 if (!textElements.contains(token)) { | 1111 if (!textElements.contains(token)) { |
| 1195 String elementName = _findElementInScope(token, ''); | 1112 String elementName = _findElementInScope(token, ''); |
| 1196 if (elementName != null) { | 1113 if (elementName != null) { |
| 1197 accumulatedHtml += markdown.renderToHtml([new markdown.Element.text( | 1114 accumulatedHtml += markdown.renderToHtml([new markdown.Element.text( |
| 1198 'a', elementName)]); | 1115 'a', elementName)]); |
| 1199 added = true; | 1116 added = true; |
| 1200 } | 1117 } |
| 1201 } | 1118 } |
| 1202 if (!added) { | 1119 if (!added) { |
| 1203 accumulatedHtml += token; | 1120 accumulatedHtml += token; |
| 1204 } | 1121 } |
| 1205 } | 1122 } |
| 1206 return new markdown.Text(accumulatedHtml); | 1123 return new markdown.Text(accumulatedHtml); |
| 1207 } | 1124 } |
| 1208 | 1125 |
| 1209 | |
| 1210 // HTML escaped version of '<' character. | |
| 1211 static final _LESS_THAN = '<'; | |
| 1212 | |
| 1213 /// Chunk the provided name into individual parts to be resolved. We take a | |
| 1214 /// simplistic approach to chunking, though, we break at " ", ",", "<" | |
| 1215 /// and ">". All other characters are grouped into the name to be resolved. | |
| 1216 /// As a result, these characters will all be treated as part of the item to | |
| 1217 /// be resolved (aka the * is interpreted literally as a *, not as an | |
| 1218 /// indicator for bold <em>. | |
| 1219 static List<String> _tokenizeComplexReference(String name) { | |
| 1220 var tokens = []; | |
| 1221 var append = false; | |
| 1222 var index = 0; | |
| 1223 while(index < name.length) { | |
| 1224 if (name.indexOf(_LESS_THAN, index) == index) { | |
| 1225 tokens.add(_LESS_THAN); | |
| 1226 append = false; | |
| 1227 index += _LESS_THAN.length; | |
| 1228 } else if (name[index] == ' ' || name[index] == ',' || | |
| 1229 name[index] == '>') { | |
| 1230 tokens.add(name[index]); | |
| 1231 append = false; | |
| 1232 index++; | |
| 1233 } else { | |
| 1234 if (append) { | |
| 1235 tokens[tokens.length - 1] = tokens.last + name[index]; | |
| 1236 } else { | |
| 1237 tokens.add(name[index]); | |
| 1238 append = true; | |
| 1239 } | |
| 1240 index++; | |
| 1241 } | |
| 1242 } | |
| 1243 return tokens; | |
| 1244 } | |
| 1245 | |
| 1246 static String _findElementInScope(String name, String packagePrefix) { | 1126 static String _findElementInScope(String name, String packagePrefix) { |
| 1247 var lookupFunc = determineLookupFunc(name); | 1127 var lookupFunc = determineLookupFunc(name); |
| 1248 // Look in the dart core library scope. | 1128 // Look in the dart core library scope. |
| 1249 var coreScope = _coreLibrary == null? null : | 1129 var coreScope = _coreLibrary == null? null : |
| 1250 lookupFunc(_coreLibrary.mirror, name); | 1130 lookupFunc(_coreLibrary.mirror, name); |
| 1251 if (coreScope != null) return packagePrefix + _coreLibrary.docName; | 1131 if (coreScope != null) return packagePrefix + _coreLibrary.docName; |
| 1252 | 1132 |
| 1253 // If it's a reference that starts with a another library name, then it | 1133 // If it's a reference that starts with a another library name, then it |
| 1254 // looks for a match of that library name in the other sdk libraries. | 1134 // looks for a match of that library name in the other sdk libraries. |
| 1255 if(name.contains('.')) { | 1135 if(name.contains('.')) { |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 1271 } | 1151 } |
| 1272 } | 1152 } |
| 1273 } | 1153 } |
| 1274 } | 1154 } |
| 1275 return null; | 1155 return null; |
| 1276 } | 1156 } |
| 1277 | 1157 |
| 1278 /// Expand the method map [mapToExpand] into a more detailed map that | 1158 /// Expand the method map [mapToExpand] into a more detailed map that |
| 1279 /// separates out setters, getters, constructors, operators, and methods. | 1159 /// separates out setters, getters, constructors, operators, and methods. |
| 1280 Map _expandMethodMap(Map<String, Method> mapToExpand) => { | 1160 Map _expandMethodMap(Map<String, Method> mapToExpand) => { |
| 1281 'setters': recurseMap(_filterMap(mapToExpand, | 1161 'setters': recurseMap(filterMap(mapToExpand, |
| 1282 (key, val) => val.mirror.isSetter)), | 1162 (key, val) => val.mirror.isSetter)), |
| 1283 'getters': recurseMap(_filterMap(mapToExpand, | 1163 'getters': recurseMap(filterMap(mapToExpand, |
| 1284 (key, val) => val.mirror.isGetter)), | 1164 (key, val) => val.mirror.isGetter)), |
| 1285 'constructors': recurseMap(_filterMap(mapToExpand, | 1165 'constructors': recurseMap(filterMap(mapToExpand, |
| 1286 (key, val) => val.mirror.isConstructor)), | 1166 (key, val) => val.mirror.isConstructor)), |
| 1287 'operators': recurseMap(_filterMap(mapToExpand, | 1167 'operators': recurseMap(filterMap(mapToExpand, |
| 1288 (key, val) => val.mirror.isOperator)), | 1168 (key, val) => val.mirror.isOperator)), |
| 1289 'methods': recurseMap(_filterMap(mapToExpand, | 1169 'methods': recurseMap(filterMap(mapToExpand, |
| 1290 (key, val) => val.mirror.isRegularMethod && !val.mirror.isOperator)) | 1170 (key, val) => val.mirror.isRegularMethod && !val.mirror.isOperator)) |
| 1291 }; | 1171 }; |
| 1292 | 1172 |
| 1293 /// Transforms the map by calling toMap on each value in it. | |
| 1294 Map recurseMap(Map inputMap) { | |
| 1295 var outputMap = {}; | |
| 1296 inputMap.forEach((key, value) { | |
| 1297 if (value is Map) { | |
| 1298 outputMap[key] = recurseMap(value); | |
| 1299 } else { | |
| 1300 outputMap[key] = value.toMap(); | |
| 1301 } | |
| 1302 }); | |
| 1303 return outputMap; | |
| 1304 } | |
| 1305 | |
| 1306 Map _filterMap(Map map, Function test) { | |
| 1307 var exported = new Map(); | |
| 1308 map.forEach((key, value) { | |
| 1309 if (test(key, value)) exported[key] = value; | |
| 1310 }); | |
| 1311 return exported; | |
| 1312 } | |
| 1313 | |
| 1314 /// Accessor to determine if this item and all of its owners are visible. | 1173 /// Accessor to determine if this item and all of its owners are visible. |
| 1315 bool get _isVisible => _Generator._isFullChainVisible(this); | 1174 bool get _isVisible => _Generator._isFullChainVisible(this); |
| 1316 | 1175 |
| 1317 /// Given a Dart2jsMirror, find the corresponding Docgen [MirrorBased] object. | 1176 /// Given a Dart2jsMirror, find the corresponding Docgen [MirrorBased] object. |
| 1318 /// | 1177 /// |
| 1319 /// We have this global lookup function to avoid re-implementing looking up | 1178 /// We have this global lookup function to avoid re-implementing looking up |
| 1320 /// the scoping rules for comment resolution here (it is currently done in | 1179 /// the scoping rules for comment resolution here (it is currently done in |
| 1321 /// mirrors). If no corresponding MirrorBased object is found, we return a | 1180 /// mirrors). If no corresponding MirrorBased object is found, we return a |
| 1322 /// [DummyMirror] that simply returns the original mirror's qualifiedName | 1181 /// [DummyMirror] that simply returns the original mirror's qualifiedName |
| 1323 /// while behaving like a MirrorBased object. | 1182 /// while behaving like a MirrorBased object. |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1421 this.functions = _createMethods(_addAll(exported['methods'], | 1280 this.functions = _createMethods(_addAll(exported['methods'], |
| 1422 libraryMirror.declarations.values.where( | 1281 libraryMirror.declarations.values.where( |
| 1423 (mirror) => mirror is MethodMirror)).values, this); | 1282 (mirror) => mirror is MethodMirror)).values, this); |
| 1424 this.variables = _createVariables(_addAll(exported['variables'], | 1283 this.variables = _createVariables(_addAll(exported['variables'], |
| 1425 dart2js_util.variablesOf(libraryMirror.declarations)).values, this); | 1284 dart2js_util.variablesOf(libraryMirror.declarations)).values, this); |
| 1426 } | 1285 } |
| 1427 | 1286 |
| 1428 /// Look for the specified name starting with the current member, and | 1287 /// Look for the specified name starting with the current member, and |
| 1429 /// progressively working outward to the current library scope. | 1288 /// progressively working outward to the current library scope. |
| 1430 String findElementInScope(String name) { | 1289 String findElementInScope(String name) { |
| 1431 var lookupFunc = Indexable.determineLookupFunc(name); | 1290 var lookupFunc = determineLookupFunc(name); |
| 1432 var libraryScope = lookupFunc(mirror, name); | 1291 var libraryScope = lookupFunc(mirror, name); |
| 1433 if (libraryScope != null) { | 1292 if (libraryScope != null) { |
| 1434 var result = Indexable.getDocgenObject(libraryScope, this); | 1293 var result = Indexable.getDocgenObject(libraryScope, this); |
| 1435 if (result is DummyMirror) return packagePrefix + result.docName; | 1294 if (result is DummyMirror) return packagePrefix + result.docName; |
| 1436 return result.packagePrefix + result.docName; | 1295 return result.packagePrefix + result.docName; |
| 1437 } | 1296 } |
| 1438 return super.findElementInScope(name); | 1297 return super.findElementInScope(name); |
| 1439 } | 1298 } |
| 1440 | 1299 |
| 1441 String _mdnComment() => ''; | 1300 String _mdnComment() => ''; |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1562 /// corresponding to the actual DeclarationMirror. | 1421 /// corresponding to the actual DeclarationMirror. |
| 1563 Map<String, Map<String, DeclarationMirror>> _calcExportedItems( | 1422 Map<String, Map<String, DeclarationMirror>> _calcExportedItems( |
| 1564 LibrarySourceMirror library) { | 1423 LibrarySourceMirror library) { |
| 1565 var exports = {}; | 1424 var exports = {}; |
| 1566 exports['classes'] = {}; | 1425 exports['classes'] = {}; |
| 1567 exports['methods'] = {}; | 1426 exports['methods'] = {}; |
| 1568 exports['variables'] = {}; | 1427 exports['variables'] = {}; |
| 1569 | 1428 |
| 1570 // Determine the classes, variables and methods that are exported for a | 1429 // Determine the classes, variables and methods that are exported for a |
| 1571 // specific dependency. | 1430 // specific dependency. |
| 1572 _populateExports(LibraryDependencyMirror export, bool showExport) { | 1431 void _populateExports(LibraryDependencyMirror export, bool showExport) { |
| 1573 if (!showExport) { | 1432 if (!showExport) { |
| 1574 // Add all items, and then remove the hidden ones. | 1433 // Add all items, and then remove the hidden ones. |
| 1575 // Ex: "export foo hide bar" | 1434 // Ex: "export foo hide bar" |
| 1576 _addAll(exports['classes'], | 1435 _addAll(exports['classes'], |
| 1577 dart2js_util.typesOf(export.targetLibrary.declarations)); | 1436 dart2js_util.typesOf(export.targetLibrary.declarations)); |
| 1578 _addAll(exports['methods'], | 1437 _addAll(exports['methods'], |
| 1579 export.targetLibrary.declarations.values.where( | 1438 export.targetLibrary.declarations.values.where( |
| 1580 (mirror) => mirror is MethodMirror)); | 1439 (mirror) => mirror is MethodMirror)); |
| 1581 _addAll(exports['variables'], | 1440 _addAll(exports['variables'], |
| 1582 dart2js_util.variablesOf(export.targetLibrary.declarations)); | 1441 dart2js_util.variablesOf(export.targetLibrary.declarations)); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1660 | 1519 |
| 1661 /// Returns this object's qualified name, but following the conventions | 1520 /// Returns this object's qualified name, but following the conventions |
| 1662 /// we're using in Dartdoc, which is that library names with dots in them | 1521 /// we're using in Dartdoc, which is that library names with dots in them |
| 1663 /// have them replaced with hyphens. | 1522 /// have them replaced with hyphens. |
| 1664 String get docName => owner.docName + '.' + dart2js_util.nameOf(mirror); | 1523 String get docName => owner.docName + '.' + dart2js_util.nameOf(mirror); |
| 1665 | 1524 |
| 1666 OwnedIndexable(DeclarationMirror mirror, this.owner) : super(mirror); | 1525 OwnedIndexable(DeclarationMirror mirror, this.owner) : super(mirror); |
| 1667 | 1526 |
| 1668 /// Generates MDN comments from database.json. | 1527 /// Generates MDN comments from database.json. |
| 1669 String _mdnComment() { | 1528 String _mdnComment() { |
| 1670 //Check if MDN is loaded. | |
| 1671 if (Indexable._mdn == null) { | |
| 1672 // Reading in MDN related json file. | |
| 1673 var root = _Generator._rootDirectory; | |
| 1674 var mdnPath = path.join(root, 'utils/apidoc/mdn/database.json'); | |
| 1675 var mdnFile = new File(mdnPath); | |
| 1676 if (mdnFile.existsSync()) { | |
| 1677 Indexable._mdn = JSON.decode(mdnFile.readAsStringSync()); | |
| 1678 } else { | |
| 1679 _Generator.logger.warning("Cannot find MDN docs expected at $mdnPath"); | |
| 1680 Indexable._mdn = {}; | |
| 1681 } | |
| 1682 } | |
| 1683 var domAnnotation = this.annotations.firstWhere( | 1529 var domAnnotation = this.annotations.firstWhere( |
| 1684 (e) => e.mirror.qualifiedName == #metadata.DomName, | 1530 (e) => e.mirror.qualifiedName == #metadata.DomName, |
| 1685 orElse: () => null); | 1531 orElse: () => null); |
| 1686 if (domAnnotation == null) return ''; | 1532 if (domAnnotation == null) return ''; |
| 1687 var domName = domAnnotation.parameters.single; | 1533 var domName = domAnnotation.parameters.single; |
| 1688 var parts = domName.split('.'); | |
| 1689 if (parts.length == 2) return _mdnMemberComment(parts[0], parts[1]); | |
| 1690 if (parts.length == 1) return _mdnTypeComment(parts[0]); | |
| 1691 | 1534 |
| 1692 throw new StateError('More than two items is not supported: $parts'); | 1535 return mdnComment(_Generator._rootDirectory, _Generator.logger, domName); |
| 1693 } | 1536 } |
| 1694 | 1537 |
| 1695 String get packagePrefix => owner.packagePrefix; | 1538 String get packagePrefix => owner.packagePrefix; |
| 1696 } | 1539 } |
| 1697 | 1540 |
| 1698 /// A class containing contents of a Dart class. | 1541 /// A class containing contents of a Dart class. |
| 1699 class Class extends OwnedIndexable implements Comparable { | 1542 class Class extends OwnedIndexable implements Comparable { |
| 1700 | 1543 |
| 1701 /// List of the names of interfaces that this class implements. | 1544 /// List of the names of interfaces that this class implements. |
| 1702 List<Class> interfaces = []; | 1545 List<Class> interfaces = []; |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1761 var superinterfaces = classMirror.superinterfaces.map( | 1604 var superinterfaces = classMirror.superinterfaces.map( |
| 1762 (interface) => new Class._possiblyDifferentOwner(interface, owner)); | 1605 (interface) => new Class._possiblyDifferentOwner(interface, owner)); |
| 1763 this.superclass = classMirror.superclass == null? null : | 1606 this.superclass = classMirror.superclass == null? null : |
| 1764 new Class._possiblyDifferentOwner(classMirror.superclass, owner); | 1607 new Class._possiblyDifferentOwner(classMirror.superclass, owner); |
| 1765 | 1608 |
| 1766 interfaces = superinterfaces.toList(); | 1609 interfaces = superinterfaces.toList(); |
| 1767 variables = _createVariables( | 1610 variables = _createVariables( |
| 1768 dart2js_util.variablesOf(classMirror.declarations), this); | 1611 dart2js_util.variablesOf(classMirror.declarations), this); |
| 1769 methods = _createMethods(classMirror.declarations.values.where( | 1612 methods = _createMethods(classMirror.declarations.values.where( |
| 1770 (mirror) => mirror is MethodMirror), this); | 1613 (mirror) => mirror is MethodMirror), this); |
| 1771 annotations = MirrorBased._createAnnotations(classMirror, _getOwningLibrary( owner)); | 1614 annotations = _createAnnotations(classMirror, _getOwningLibrary(owner)); |
| 1772 generics = _createGenerics(classMirror); | 1615 generics = _createGenerics(classMirror); |
| 1773 isAbstract = classMirror.isAbstract; | 1616 isAbstract = classMirror.isAbstract; |
| 1774 inheritedMethods = new Map<String, Method>(); | 1617 inheritedMethods = new Map<String, Method>(); |
| 1775 | 1618 |
| 1776 // Tell superclass that you are a subclass, unless you are not | 1619 // Tell superclass that you are a subclass, unless you are not |
| 1777 // visible or an intermediary mixin class. | 1620 // visible or an intermediary mixin class. |
| 1778 if (!classMirror.isNameSynthetic && _isVisible && superclass != null) { | 1621 if (!classMirror.isNameSynthetic && _isVisible && superclass != null) { |
| 1779 superclass.addSubclass(this); | 1622 superclass.addSubclass(this); |
| 1780 } | 1623 } |
| 1781 | 1624 |
| 1782 if (this.superclass != null) addInherited(superclass); | 1625 if (this.superclass != null) addInherited(superclass); |
| 1783 interfaces.forEach((interface) => addInherited(interface)); | 1626 interfaces.forEach((interface) => addInherited(interface)); |
| 1784 } | 1627 } |
| 1785 | 1628 |
| 1786 String _lookupInClassAndSuperclasses(String name) { | 1629 String _lookupInClassAndSuperclasses(String name) { |
| 1787 var lookupFunc = Indexable.determineLookupFunc(name); | 1630 var lookupFunc = determineLookupFunc(name); |
| 1788 var classScope = this; | 1631 var classScope = this; |
| 1789 while (classScope != null) { | 1632 while (classScope != null) { |
| 1790 var classFunc = lookupFunc(classScope.mirror, name); | 1633 var classFunc = lookupFunc(classScope.mirror, name); |
| 1791 if (classFunc != null) { | 1634 if (classFunc != null) { |
| 1792 return packagePrefix + Indexable.getDocgenObject(classFunc, owner).docNa me; | 1635 return packagePrefix + Indexable.getDocgenObject(classFunc, owner).docNa me; |
| 1793 } | 1636 } |
| 1794 classScope = classScope.superclass; | 1637 classScope = classScope.superclass; |
| 1795 } | 1638 } |
| 1796 return null; | 1639 return null; |
| 1797 } | 1640 } |
| 1798 | 1641 |
| 1799 /// Look for the specified name starting with the current member, and | 1642 /// Look for the specified name starting with the current member, and |
| 1800 /// progressively working outward to the current library scope. | 1643 /// progressively working outward to the current library scope. |
| 1801 String findElementInScope(String name) { | 1644 String findElementInScope(String name) { |
| 1802 var lookupFunc = Indexable.determineLookupFunc(name); | 1645 var lookupFunc = determineLookupFunc(name); |
| 1803 var result = _lookupInClassAndSuperclasses(name); | 1646 var result = _lookupInClassAndSuperclasses(name); |
| 1804 if (result != null) { | 1647 if (result != null) { |
| 1805 return result; | 1648 return result; |
| 1806 } | 1649 } |
| 1807 result = owner.findElementInScope(name); | 1650 result = owner.findElementInScope(name); |
| 1808 return result == null ? super.findElementInScope(name) : result; | 1651 return result == null ? super.findElementInScope(name) : result; |
| 1809 } | 1652 } |
| 1810 | 1653 |
| 1811 String get typeName => 'class'; | 1654 String get typeName => 'class'; |
| 1812 | 1655 |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1944 aTypedef = new Typedef._(mirror, owningLibrary); | 1787 aTypedef = new Typedef._(mirror, owningLibrary); |
| 1945 } | 1788 } |
| 1946 return aTypedef; | 1789 return aTypedef; |
| 1947 } | 1790 } |
| 1948 | 1791 |
| 1949 Typedef._(TypedefMirror mirror, Library owningLibrary) : | 1792 Typedef._(TypedefMirror mirror, Library owningLibrary) : |
| 1950 super(mirror, owningLibrary) { | 1793 super(mirror, owningLibrary) { |
| 1951 returnType = Indexable.getDocgenObject(mirror.referent.returnType).docName; | 1794 returnType = Indexable.getDocgenObject(mirror.referent.returnType).docName; |
| 1952 generics = _createGenerics(mirror); | 1795 generics = _createGenerics(mirror); |
| 1953 parameters = _createParameters(mirror.referent.parameters, owningLibrary); | 1796 parameters = _createParameters(mirror.referent.parameters, owningLibrary); |
| 1954 annotations = MirrorBased._createAnnotations(mirror, owningLibrary); | 1797 annotations = _createAnnotations(mirror, owningLibrary); |
|
Emily Fortuna
2014/03/06 22:05:38
is having a bunch of random global functions reall
kevmoo
2014/03/06 22:20:17
Random top-level methods make dependencies clear.
Alan Knight
2014/03/12 18:17:56
I don't think it's about strict dependency require
kevmoo
2014/03/17 02:01:29
Since MirrorBased is in another library and we wan
| |
| 1955 } | 1798 } |
| 1956 | 1799 |
| 1957 Map toMap() { | 1800 Map toMap() { |
| 1958 var map = { | 1801 var map = { |
| 1959 'name': name, | 1802 'name': name, |
| 1960 'qualifiedName': qualifiedName, | 1803 'qualifiedName': qualifiedName, |
| 1961 'comment': comment, | 1804 'comment': comment, |
| 1962 'return': returnType, | 1805 'return': returnType, |
| 1963 'parameters': recurseMap(parameters), | 1806 'parameters': recurseMap(parameters), |
| 1964 'annotations': annotations.map((a) => a.toMap()).toList(), | 1807 'annotations': annotations.map((a) => a.toMap()).toList(), |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1997 } | 1840 } |
| 1998 return variable; | 1841 return variable; |
| 1999 } | 1842 } |
| 2000 | 1843 |
| 2001 Variable._(this._variableName, VariableMirror mirror, Indexable owner) : | 1844 Variable._(this._variableName, VariableMirror mirror, Indexable owner) : |
| 2002 super(mirror, owner) { | 1845 super(mirror, owner) { |
| 2003 isFinal = mirror.isFinal; | 1846 isFinal = mirror.isFinal; |
| 2004 isStatic = mirror.isStatic; | 1847 isStatic = mirror.isStatic; |
| 2005 isConst = mirror.isConst; | 1848 isConst = mirror.isConst; |
| 2006 type = new Type(mirror.type, _getOwningLibrary(owner)); | 1849 type = new Type(mirror.type, _getOwningLibrary(owner)); |
| 2007 annotations = MirrorBased._createAnnotations(mirror, _getOwningLibrary(owner )); | 1850 annotations = _createAnnotations(mirror, _getOwningLibrary(owner)); |
| 2008 } | 1851 } |
| 2009 | 1852 |
| 2010 String get name => _variableName; | 1853 String get name => _variableName; |
| 2011 | 1854 |
| 2012 /// Generates a map describing the [Variable] object. | 1855 /// Generates a map describing the [Variable] object. |
| 2013 Map toMap() => { | 1856 Map toMap() => { |
| 2014 'name': name, | 1857 'name': name, |
| 2015 'qualifiedName': qualifiedName, | 1858 'qualifiedName': qualifiedName, |
| 2016 'comment': comment, | 1859 'comment': comment, |
| 2017 'final': isFinal, | 1860 'final': isFinal, |
| 2018 'static': isStatic, | 1861 'static': isStatic, |
| 2019 'constant': isConst, | 1862 'constant': isConst, |
| 2020 'type': new List.filled(1, type.toMap()), | 1863 'type': new List.filled(1, type.toMap()), |
| 2021 'annotations': annotations.map((a) => a.toMap()).toList() | 1864 'annotations': annotations.map((a) => a.toMap()).toList() |
| 2022 }; | 1865 }; |
| 2023 | 1866 |
| 2024 String get typeName => 'property'; | 1867 String get typeName => 'property'; |
| 2025 | 1868 |
| 2026 get comment { | 1869 get comment { |
| 2027 if (_comment != null) return _comment; | 1870 if (_comment != null) return _comment; |
| 2028 if (owner is Class) { | 1871 if (owner is Class) { |
| 2029 (owner as Class).ensureComments(); | 1872 (owner as Class).ensureComments(); |
| 2030 } | 1873 } |
| 2031 return super.comment; | 1874 return super.comment; |
| 2032 } | 1875 } |
| 2033 | 1876 |
| 2034 String findElementInScope(String name) { | 1877 String findElementInScope(String name) { |
| 2035 var lookupFunc = Indexable.determineLookupFunc(name); | 1878 var lookupFunc = determineLookupFunc(name); |
| 2036 var result = lookupFunc(mirror, name); | 1879 var result = lookupFunc(mirror, name); |
| 2037 if (result != null) { | 1880 if (result != null) { |
| 2038 result = Indexable.getDocgenObject(result); | 1881 result = Indexable.getDocgenObject(result); |
| 2039 if (result is DummyMirror) return packagePrefix + result.docName; | 1882 if (result is DummyMirror) return packagePrefix + result.docName; |
| 2040 return result.packagePrefix + result.docName; | 1883 return result.packagePrefix + result.docName; |
| 2041 } | 1884 } |
| 2042 | 1885 |
| 2043 if (owner != null) { | 1886 if (owner != null) { |
| 2044 var result = owner.findElementInScope(name); | 1887 var result = owner.findElementInScope(name); |
| 2045 if (result != null) { | 1888 if (result != null) { |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 2076 return method; | 1919 return method; |
| 2077 } | 1920 } |
| 2078 | 1921 |
| 2079 Method._(MethodMirror mirror, Indexable owner, this.methodInheritedFrom) | 1922 Method._(MethodMirror mirror, Indexable owner, this.methodInheritedFrom) |
| 2080 : super(mirror, owner) { | 1923 : super(mirror, owner) { |
| 2081 isStatic = mirror.isStatic; | 1924 isStatic = mirror.isStatic; |
| 2082 isAbstract = mirror.isAbstract; | 1925 isAbstract = mirror.isAbstract; |
| 2083 isConst = mirror.isConstConstructor; | 1926 isConst = mirror.isConstConstructor; |
| 2084 returnType = new Type(mirror.returnType, _getOwningLibrary(owner)); | 1927 returnType = new Type(mirror.returnType, _getOwningLibrary(owner)); |
| 2085 parameters = _createParameters(mirror.parameters, owner); | 1928 parameters = _createParameters(mirror.parameters, owner); |
| 2086 annotations = MirrorBased._createAnnotations(mirror, _getOwningLibrary(owner )); | 1929 annotations = _createAnnotations(mirror, _getOwningLibrary(owner)); |
| 2087 } | 1930 } |
| 2088 | 1931 |
| 2089 Method get originallyInheritedFrom => methodInheritedFrom == null ? | 1932 Method get originallyInheritedFrom => methodInheritedFrom == null ? |
| 2090 this : methodInheritedFrom.originallyInheritedFrom; | 1933 this : methodInheritedFrom.originallyInheritedFrom; |
| 2091 | 1934 |
| 2092 /// Look for the specified name starting with the current member, and | 1935 /// Look for the specified name starting with the current member, and |
| 2093 /// progressively working outward to the current library scope. | 1936 /// progressively working outward to the current library scope. |
| 2094 String findElementInScope(String name) { | 1937 String findElementInScope(String name) { |
| 2095 var lookupFunc = Indexable.determineLookupFunc(name); | 1938 var lookupFunc = determineLookupFunc(name); |
| 2096 | 1939 |
| 2097 var memberScope = lookupFunc(this.mirror, name); | 1940 var memberScope = lookupFunc(this.mirror, name); |
| 2098 if (memberScope != null) { | 1941 if (memberScope != null) { |
| 2099 // do we check for a dummy mirror returned here and look up with an owner | 1942 // do we check for a dummy mirror returned here and look up with an owner |
| 2100 // higher ooooor in getDocgenObject do we include more things in our | 1943 // higher ooooor in getDocgenObject do we include more things in our |
| 2101 // lookup | 1944 // lookup |
| 2102 var result = Indexable.getDocgenObject(memberScope, owner); | 1945 var result = Indexable.getDocgenObject(memberScope, owner); |
| 2103 if (result is DummyMirror && owner.owner != null | 1946 if (result is DummyMirror && owner.owner != null |
| 2104 && owner.owner is! DummyMirror) { | 1947 && owner.owner is! DummyMirror) { |
| 2105 var aresult = Indexable.getDocgenObject(memberScope, owner.owner); | 1948 var aresult = Indexable.getDocgenObject(memberScope, owner.owner); |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2205 final List<Annotation> annotations; | 2048 final List<Annotation> annotations; |
| 2206 | 2049 |
| 2207 Parameter(ParameterMirror mirror, Library owningLibrary) | 2050 Parameter(ParameterMirror mirror, Library owningLibrary) |
| 2208 : this.mirror = mirror, | 2051 : this.mirror = mirror, |
| 2209 name = dart2js_util.nameOf(mirror), | 2052 name = dart2js_util.nameOf(mirror), |
| 2210 isOptional = mirror.isOptional, | 2053 isOptional = mirror.isOptional, |
| 2211 isNamed = mirror.isNamed, | 2054 isNamed = mirror.isNamed, |
| 2212 hasDefaultValue = mirror.hasDefaultValue, | 2055 hasDefaultValue = mirror.hasDefaultValue, |
| 2213 defaultValue = '${mirror.defaultValue}', | 2056 defaultValue = '${mirror.defaultValue}', |
| 2214 type = new Type(mirror.type, owningLibrary), | 2057 type = new Type(mirror.type, owningLibrary), |
| 2215 annotations = MirrorBased._createAnnotations(mirror, owningLibrary); | 2058 annotations = _createAnnotations(mirror, owningLibrary); |
| 2216 | 2059 |
| 2217 /// Generates a map describing the [Parameter] object. | 2060 /// Generates a map describing the [Parameter] object. |
| 2218 Map toMap() => { | 2061 Map toMap() => { |
| 2219 'name': name, | 2062 'name': name, |
| 2220 'optional': isOptional, | 2063 'optional': isOptional, |
| 2221 'named': isNamed, | 2064 'named': isNamed, |
| 2222 'default': hasDefaultValue, | 2065 'default': hasDefaultValue, |
| 2223 'type': new List.filled(1, type.toMap()), | 2066 'type': new List.filled(1, type.toMap()), |
| 2224 'value': defaultValue, | 2067 'value': defaultValue, |
| 2225 'annotations': annotations.map((a) => a.toMap()).toList() | 2068 'annotations': annotations.map((a) => a.toMap()).toList() |
| 2226 }; | 2069 }; |
| 2227 } | 2070 } |
| 2228 | 2071 |
| 2229 /// A Docgen wrapper around the dart2js mirror for a generic type. | |
| 2230 class Generic extends MirrorBased { | |
| 2231 final TypeVariableMirror mirror; | |
| 2232 Generic(this.mirror); | |
| 2233 Map toMap() => { | |
| 2234 'name': dart2js_util.nameOf(mirror), | |
| 2235 'type': dart2js_util.qualifiedNameOf(mirror.upperBound) | |
| 2236 }; | |
| 2237 } | |
| 2238 | |
| 2239 /// Docgen wrapper around the mirror for a return type, and/or its generic | 2072 /// Docgen wrapper around the mirror for a return type, and/or its generic |
| 2240 /// type parameters. | 2073 /// type parameters. |
| 2241 /// | 2074 /// |
| 2242 /// Return types are of a form [outer]<[inner]>. | 2075 /// Return types are of a form [outer]<[inner]>. |
| 2243 /// If there is no [inner] part, [inner] will be an empty list. | 2076 /// If there is no [inner] part, [inner] will be an empty list. |
| 2244 /// | 2077 /// |
| 2245 /// For example: | 2078 /// For example: |
| 2246 /// int size() | 2079 /// int size() |
| 2247 /// "return" : | 2080 /// "return" : |
| 2248 /// - "outer" : "dart-core.int" | 2081 /// - "outer" : "dart-core.int" |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2308 .map((e) => originalMirror.getField(e.simpleName).reflectee) | 2141 .map((e) => originalMirror.getField(e.simpleName).reflectee) |
| 2309 .where((e) => e != null) | 2142 .where((e) => e != null) |
| 2310 .toList(); | 2143 .toList(); |
| 2311 } | 2144 } |
| 2312 | 2145 |
| 2313 Map toMap() => { | 2146 Map toMap() => { |
| 2314 'name': Indexable.getDocgenObject(mirror, owningLibrary).docName, | 2147 'name': Indexable.getDocgenObject(mirror, owningLibrary).docName, |
| 2315 'parameters': parameters | 2148 'parameters': parameters |
| 2316 }; | 2149 }; |
| 2317 } | 2150 } |
| 2151 | |
| 2152 /// Returns a list of meta annotations assocated with a mirror. | |
| 2153 List<Annotation> _createAnnotations(DeclarationMirror mirror, | |
| 2154 Library owningLibrary) { | |
| 2155 var annotationMirrors = mirror.metadata.where((e) => | |
| 2156 e is dart2js_mirrors.Dart2JsConstructedConstantMirror); | |
| 2157 var annotations = []; | |
| 2158 annotationMirrors.forEach((annotation) { | |
| 2159 var docgenAnnotation = new Annotation(annotation, owningLibrary); | |
| 2160 if (!_SKIPPED_ANNOTATIONS.contains( | |
| 2161 dart2js_util.qualifiedNameOf(docgenAnnotation.mirror))) { | |
| 2162 annotations.add(docgenAnnotation); | |
| 2163 } | |
| 2164 }); | |
| 2165 return annotations; | |
| 2166 } | |
| OLD | NEW |