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 601 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 855 /// to them as concrete entities in a particular scope. | 836 /// to them as concrete entities in a particular scope. |
| 856 abstract class Indexable extends MirrorBased { | 837 abstract class Indexable extends MirrorBased { |
| 857 /// The dart:core library, which contains all types that are always available | 838 /// The dart:core library, which contains all types that are always available |
| 858 /// without import. | 839 /// without import. |
| 859 static Library _coreLibrary; | 840 static Library _coreLibrary; |
| 860 | 841 |
| 861 /// Set of libraries declared in the SDK, so libraries that can be accessed | 842 /// Set of libraries declared in the SDK, so libraries that can be accessed |
| 862 /// when running dart by default. | 843 /// when running dart by default. |
| 863 static Iterable<LibraryMirror> _sdkLibraries; | 844 static Iterable<LibraryMirror> _sdkLibraries; |
| 864 | 845 |
| 846 Library get _owningLibrary => owner._owningLibrary; | |
| 847 | |
| 865 String get qualifiedName => fileName; | 848 String get qualifiedName => fileName; |
| 866 bool isPrivate; | 849 final DeclarationMirror mirror; |
| 867 DeclarationMirror mirror; | 850 final bool isPrivate; |
| 868 /// The comment text pre-resolution. We keep this around because inherited | 851 /// The comment text pre-resolution. We keep this around because inherited |
| 869 /// methods need to resolve links differently from the superclass. | 852 /// methods need to resolve links differently from the superclass. |
| 870 String _unresolvedComment = ''; | 853 String _unresolvedComment = ''; |
| 871 | 854 |
| 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 | |
| 878 /// Index of all the dart2js mirrors examined to corresponding MirrorBased | 855 /// Index of all the dart2js mirrors examined to corresponding MirrorBased |
| 879 /// docgen objects. | 856 /// docgen objects. |
| 880 /// | 857 /// |
| 881 /// Used for lookup because of the dart2js mirrors exports | 858 /// Used for lookup because of the dart2js mirrors exports |
| 882 /// issue. The second level map is indexed by owner docName for faster lookup. | 859 /// issue. The second level map is indexed by owner docName for faster lookup. |
| 883 /// Why two levels of lookup? Speed, man. Speed. | 860 /// Why two levels of lookup? Speed, man. Speed. |
| 884 static Map<String, Map<String, Set<Indexable>>> _mirrorToDocgen = | 861 static Map<String, Map<String, Set<Indexable>>> _mirrorToDocgen = |
| 885 new Map<String, Map<String, Set<Indexable>>>(); | 862 new Map<String, Map<String, Set<Indexable>>>(); |
| 886 | 863 |
| 887 Indexable(this.mirror) { | 864 Indexable(DeclarationMirror mirror) |
| 888 this.isPrivate = _isHidden(mirror); | 865 : this.mirror = mirror, |
|
Emily Fortuna
2014/03/17 16:58:35
why not (this.mirror)?
kevmoo
2014/03/17 17:06:36
If you use this.mirror, you cannot use mirror in t
| |
| 866 this.isPrivate = isHidden(mirror) { | |
| 889 | 867 |
| 890 var map = _mirrorToDocgen[dart2js_util.qualifiedNameOf(this.mirror)]; | 868 var map = _mirrorToDocgen[dart2js_util.qualifiedNameOf(this.mirror)]; |
| 891 if (map == null) map = new Map<String, Set<Indexable>>(); | 869 if (map == null) map = new Map<String, Set<Indexable>>(); |
| 892 | 870 |
| 893 var set = map[owner.docName]; | 871 var set = map[owner.docName]; |
| 894 if (set == null) set = new Set<Indexable>(); | 872 if (set == null) set = new Set<Indexable>(); |
| 895 set.add(this); | 873 set.add(this); |
| 896 map[owner.docName] = set; | 874 map[owner.docName] = set; |
| 897 _mirrorToDocgen[dart2js_util.qualifiedNameOf(this.mirror)] = map; | 875 _mirrorToDocgen[dart2js_util.qualifiedNameOf(this.mirror)] = map; |
| 898 } | 876 } |
| 899 | 877 |
| 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) { | 878 static _initializeTopLevelLibraries(MirrorSystem mirrorSystem) { |
| 907 _sdkLibraries = mirrorSystem.libraries.values.where( | 879 _sdkLibraries = mirrorSystem.libraries.values.where( |
| 908 (each) => each.uri.scheme == 'dart'); | 880 (each) => each.uri.scheme == 'dart'); |
| 909 _coreLibrary = new Library(_sdkLibraries.singleWhere((lib) => | 881 _coreLibrary = new Library(_sdkLibraries.singleWhere((lib) => |
| 910 lib.uri.toString().startsWith('dart:core'))); | 882 lib.uri.toString().startsWith('dart:core'))); |
| 911 } | 883 } |
| 912 | 884 |
| 913 /// Returns this object's qualified name, but following the conventions | 885 /// 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 | 886 /// we're using in Dartdoc, which is that library names with dots in them |
| 915 /// have them replaced with hyphens. | 887 /// have them replaced with hyphens. |
| 916 String get docName; | 888 String get docName; |
| 917 | 889 |
| 918 /// Converts all [foo] references in comments to <a>libraryName.foo</a>. | 890 /// Converts all [foo] references in comments to <a>libraryName.foo</a>. |
| 919 markdown.Node fixReference(String name) { | 891 markdown.Node fixReference(String name) { |
| 920 // Attempt the look up the whole name up in the scope. | 892 // Attempt the look up the whole name up in the scope. |
| 921 String elementName = findElementInScope(name); | 893 String elementName = findElementInScope(name); |
| 922 if (elementName != null) { | 894 if (elementName != null) { |
| 923 return new markdown.Element.text('a', elementName); | 895 return new markdown.Element.text('a', elementName); |
| 924 } | 896 } |
| 925 return _fixComplexReference(name); | 897 return _fixComplexReference(name); |
| 926 } | 898 } |
| 927 | 899 |
| 928 /// Look for the specified name starting with the current member, and | 900 /// Look for the specified name starting with the current member, and |
| 929 /// progressively working outward to the current library scope. | 901 /// progressively working outward to the current library scope. |
| 930 String findElementInScope(String name) => | 902 String findElementInScope(String name) => |
| 931 _findElementInScope(name, packagePrefix); | 903 _findElementInScope(name, packagePrefix); |
| 932 | 904 |
| 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 | 905 /// 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. | 906 /// documentation file and also the unique URL to refer to this item. |
| 941 /// | 907 /// |
| 942 /// The qualified name (for URL purposes) and the file name are the same, | 908 /// The qualified name (for URL purposes) and the file name are the same, |
| 943 /// of the form packageName/ClassName or packageName/ClassName.methodName. | 909 /// of the form packageName/ClassName or packageName/ClassName.methodName. |
| 944 /// This defines both the URL and the directory structure. | 910 /// This defines both the URL and the directory structure. |
| 945 String get fileName => packagePrefix + ownerPrefix + name; | 911 String get fileName => packagePrefix + ownerPrefix + name; |
| 946 | 912 |
| 947 /// The full docName of the owner element, appended with a '.' for this | 913 /// The full docName of the owner element, appended with a '.' for this |
| 948 /// object's name to be appended. | 914 /// object's name to be appended. |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 979 /// | 945 /// |
| 980 /// "Owning" is defined as the object one scope-level above which this item | 946 /// "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 | 947 /// 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 | 948 /// library. The owner of a local variable in a method would be the enclosing |
| 983 /// method. | 949 /// method. |
| 984 Indexable get owner => new DummyMirror(mirror.owner); | 950 Indexable get owner => new DummyMirror(mirror.owner); |
| 985 | 951 |
| 986 /// Generates MDN comments from database.json. | 952 /// Generates MDN comments from database.json. |
| 987 String _mdnComment(); | 953 String _mdnComment(); |
| 988 | 954 |
| 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. | 955 /// The type of this member to be used in index.txt. |
| 1017 String get typeName => ''; | 956 String get typeName => ''; |
| 1018 | 957 |
| 1019 /// Creates a [Map] with this [Indexable]'s name and a preview comment. | 958 /// Creates a [Map] with this [Indexable]'s name and a preview comment. |
| 1020 Map get previewMap { | 959 Map get previewMap { |
| 1021 var finalMap = { 'name' : name, 'qualifiedName' : qualifiedName }; | 960 var finalMap = { 'name' : name, 'qualifiedName' : qualifiedName }; |
| 1022 var preview = _preview; | 961 var preview = _preview; |
| 1023 if(preview != null) finalMap['preview'] = preview; | 962 if(preview != null) finalMap['preview'] = preview; |
| 1024 return finalMap; | 963 return finalMap; |
| 1025 } | 964 } |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1074 /// Returns a map of [Variable] objects constructed from [mirrorMap]. | 1013 /// Returns a map of [Variable] objects constructed from [mirrorMap]. |
| 1075 /// The optional parameter [containingLibrary] is contains data for variables | 1014 /// The optional parameter [containingLibrary] is contains data for variables |
| 1076 /// defined at the top level of a library (potentially for exporting | 1015 /// defined at the top level of a library (potentially for exporting |
| 1077 /// purposes). | 1016 /// purposes). |
| 1078 Map<String, Variable> _createVariables(Iterable<VariableMirror> mirrors, | 1017 Map<String, Variable> _createVariables(Iterable<VariableMirror> mirrors, |
| 1079 Indexable owner) { | 1018 Indexable owner) { |
| 1080 var data = {}; | 1019 var data = {}; |
| 1081 // TODO(janicejl): When map to map feature is created, replace the below | 1020 // TODO(janicejl): When map to map feature is created, replace the below |
| 1082 // with a filter. Issue(#9590). | 1021 // with a filter. Issue(#9590). |
| 1083 mirrors.forEach((VariableMirror mirror) { | 1022 mirrors.forEach((VariableMirror mirror) { |
| 1084 if (_Generator._includePrivate || !_isHidden(mirror)) { | 1023 if (_Generator._includePrivate || !isHidden(mirror)) { |
| 1085 var mirrorName = dart2js_util.nameOf(mirror); | 1024 var mirrorName = dart2js_util.nameOf(mirror); |
| 1086 data[mirrorName] = new Variable(mirrorName, mirror, owner); | 1025 data[mirrorName] = new Variable(mirrorName, mirror, owner); |
| 1087 } | 1026 } |
| 1088 }); | 1027 }); |
| 1089 return data; | 1028 return data; |
| 1090 } | 1029 } |
| 1091 | 1030 |
| 1092 /// Returns a map of [Method] objects constructed from [mirrorMap]. | 1031 /// Returns a map of [Method] objects constructed from [mirrorMap]. |
| 1093 /// The optional parameter [containingLibrary] is contains data for variables | 1032 /// The optional parameter [containingLibrary] is contains data for variables |
| 1094 /// defined at the top level of a library (potentially for exporting | 1033 /// defined at the top level of a library (potentially for exporting |
| 1095 /// purposes). | 1034 /// purposes). |
| 1096 Map<String, Method> _createMethods(Iterable<MethodMirror> mirrors, | 1035 Map<String, Method> _createMethods(Iterable<MethodMirror> mirrors, |
| 1097 Indexable owner) { | 1036 Indexable owner) { |
| 1098 var group = new Map<String, Method>(); | 1037 var group = new Map<String, Method>(); |
| 1099 mirrors.forEach((MethodMirror mirror) { | 1038 mirrors.forEach((MethodMirror mirror) { |
| 1100 if (_Generator._includePrivate || !mirror.isPrivate) { | 1039 if (_Generator._includePrivate || !mirror.isPrivate) { |
| 1101 group[dart2js_util.nameOf(mirror)] = new Method(mirror, owner); | 1040 group[dart2js_util.nameOf(mirror)] = new Method(mirror, owner); |
| 1102 } | 1041 } |
| 1103 }); | 1042 }); |
| 1104 return group; | 1043 return group; |
| 1105 } | 1044 } |
| 1106 | 1045 |
| 1107 /// Returns a map of [Parameter] objects constructed from [mirrorList]. | 1046 /// Returns a map of [Parameter] objects constructed from [mirrorList]. |
| 1108 Map<String, Parameter> _createParameters(List<ParameterMirror> mirrorList, | 1047 Map<String, Parameter> _createParameters(List<ParameterMirror> mirrorList, |
| 1109 Indexable owner) { | 1048 Indexable owner) { |
| 1110 var data = {}; | 1049 var data = {}; |
| 1111 mirrorList.forEach((ParameterMirror mirror) { | 1050 mirrorList.forEach((ParameterMirror mirror) { |
| 1112 data[dart2js_util.nameOf(mirror)] = | 1051 data[dart2js_util.nameOf(mirror)] = |
| 1113 new Parameter(mirror, _getOwningLibrary(owner)); | 1052 new Parameter(mirror, owner._owningLibrary); |
| 1114 }); | 1053 }); |
| 1115 return data; | 1054 return data; |
| 1116 } | 1055 } |
| 1117 | 1056 |
| 1118 /// Returns a map of [Generic] objects constructed from the class mirror. | 1057 /// Returns a map of [Generic] objects constructed from the class mirror. |
| 1119 Map<String, Generic> _createGenerics(TypeMirror mirror) { | 1058 Map<String, Generic> _createGenerics(TypeMirror mirror) { |
| 1120 return new Map.fromIterable(mirror.typeVariables, | 1059 return new Map.fromIterable(mirror.typeVariables, |
| 1121 key: (e) => dart2js_util.nameOf(e), | 1060 key: (e) => dart2js_util.nameOf(e), |
| 1122 value: (e) => new Generic(e)); | 1061 value: (e) => new Generic(e)); |
| 1123 } | 1062 } |
| 1124 | 1063 |
| 1125 /// Return an informative [Object.toString] for debugging. | 1064 /// Return an informative [Object.toString] for debugging. |
| 1126 String toString() => "${super.toString()}(${name.toString()})"; | 1065 String toString() => "${super.toString()}(${name.toString()})"; |
| 1127 | 1066 |
| 1128 /// Return a map representation of this type. | 1067 /// Return a map representation of this type. |
| 1129 Map toMap(); | 1068 Map toMap(); |
| 1130 | 1069 |
| 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 | 1070 |
| 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 | 1071 |
| 1163 ////// Top level resolution functions | 1072 ////// Top level resolution functions |
| 1164 /// Converts all [foo] references in comments to <a>libraryName.foo</a>. | 1073 /// Converts all [foo] references in comments to <a>libraryName.foo</a>. |
| 1165 static markdown.Node globalFixReference(String name) { | 1074 static markdown.Node globalFixReference(String name) { |
| 1166 // Attempt the look up the whole name up in the scope. | 1075 // Attempt the look up the whole name up in the scope. |
| 1167 String elementName = _findElementInScope(name, ''); | 1076 String elementName = _findElementInScope(name, ''); |
| 1168 if (elementName != null) { | 1077 if (elementName != null) { |
| 1169 return new markdown.Element.text('a', elementName); | 1078 return new markdown.Element.text('a', elementName); |
| 1170 } | 1079 } |
| 1171 return _fixComplexReference(name); | 1080 return _fixComplexReference(name); |
| 1172 } | 1081 } |
| 1173 | 1082 |
| 1174 /// This is a more complex reference. Try to break up if its of the form A<B> | 1083 /// 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"), | 1084 /// 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, | 1085 /// 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 | 1086 /// 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>. | 1087 /// the * is interpreted literally as a *, not as a indicator for bold <em>. |
| 1179 /// | 1088 /// |
| 1180 /// Example: [foo<_bar_>] will produce | 1089 /// Example: [foo<_bar_>] will produce |
| 1181 /// <a>resolvedFoo</a><<a>resolved_bar_</a>> rather than an italicized | 1090 /// <a>resolvedFoo</a><<a>resolved_bar_</a>> rather than an italicized |
| 1182 /// version of resolvedBar. | 1091 /// version of resolvedBar. |
| 1183 static markdown.Node _fixComplexReference(String name) { | 1092 static markdown.Node _fixComplexReference(String name) { |
| 1184 // Parse into multiple elements we can try to resolve. | 1093 // Parse into multiple elements we can try to resolve. |
| 1185 var tokens = _tokenizeComplexReference(name); | 1094 var tokens = tokenizeComplexReference(name); |
| 1186 | 1095 |
| 1187 // Produce an html representation of our elements. Group unresolved and | 1096 // Produce an html representation of our elements. Group unresolved and |
| 1188 // plain text are grouped into "link" elements so they display as code. | 1097 // plain text are grouped into "link" elements so they display as code. |
| 1189 final textElements = [' ', ',', '>', _LESS_THAN]; | 1098 final textElements = [' ', ',', '>', LESS_THAN]; |
| 1190 var accumulatedHtml = ''; | 1099 var accumulatedHtml = ''; |
| 1191 | 1100 |
| 1192 for (var token in tokens) { | 1101 for (var token in tokens) { |
| 1193 bool added = false; | 1102 bool added = false; |
| 1194 if (!textElements.contains(token)) { | 1103 if (!textElements.contains(token)) { |
| 1195 String elementName = _findElementInScope(token, ''); | 1104 String elementName = _findElementInScope(token, ''); |
| 1196 if (elementName != null) { | 1105 if (elementName != null) { |
| 1197 accumulatedHtml += markdown.renderToHtml([new markdown.Element.text( | 1106 accumulatedHtml += markdown.renderToHtml([new markdown.Element.text( |
| 1198 'a', elementName)]); | 1107 'a', elementName)]); |
| 1199 added = true; | 1108 added = true; |
| 1200 } | 1109 } |
| 1201 } | 1110 } |
| 1202 if (!added) { | 1111 if (!added) { |
| 1203 accumulatedHtml += token; | 1112 accumulatedHtml += token; |
| 1204 } | 1113 } |
| 1205 } | 1114 } |
| 1206 return new markdown.Text(accumulatedHtml); | 1115 return new markdown.Text(accumulatedHtml); |
| 1207 } | 1116 } |
| 1208 | 1117 |
| 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) { | 1118 static String _findElementInScope(String name, String packagePrefix) { |
| 1247 var lookupFunc = determineLookupFunc(name); | 1119 var lookupFunc = determineLookupFunc(name); |
| 1248 // Look in the dart core library scope. | 1120 // Look in the dart core library scope. |
| 1249 var coreScope = _coreLibrary == null? null : | 1121 var coreScope = _coreLibrary == null? null : |
| 1250 lookupFunc(_coreLibrary.mirror, name); | 1122 lookupFunc(_coreLibrary.mirror, name); |
| 1251 if (coreScope != null) return packagePrefix + _coreLibrary.docName; | 1123 if (coreScope != null) return packagePrefix + _coreLibrary.docName; |
| 1252 | 1124 |
| 1253 // If it's a reference that starts with a another library name, then it | 1125 // 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. | 1126 // looks for a match of that library name in the other sdk libraries. |
| 1255 if(name.contains('.')) { | 1127 if(name.contains('.')) { |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 1271 } | 1143 } |
| 1272 } | 1144 } |
| 1273 } | 1145 } |
| 1274 } | 1146 } |
| 1275 return null; | 1147 return null; |
| 1276 } | 1148 } |
| 1277 | 1149 |
| 1278 /// Expand the method map [mapToExpand] into a more detailed map that | 1150 /// Expand the method map [mapToExpand] into a more detailed map that |
| 1279 /// separates out setters, getters, constructors, operators, and methods. | 1151 /// separates out setters, getters, constructors, operators, and methods. |
| 1280 Map _expandMethodMap(Map<String, Method> mapToExpand) => { | 1152 Map _expandMethodMap(Map<String, Method> mapToExpand) => { |
| 1281 'setters': recurseMap(_filterMap(mapToExpand, | 1153 'setters': recurseMap(filterMap(mapToExpand, |
| 1282 (key, val) => val.mirror.isSetter)), | 1154 (key, val) => val.mirror.isSetter)), |
| 1283 'getters': recurseMap(_filterMap(mapToExpand, | 1155 'getters': recurseMap(filterMap(mapToExpand, |
| 1284 (key, val) => val.mirror.isGetter)), | 1156 (key, val) => val.mirror.isGetter)), |
| 1285 'constructors': recurseMap(_filterMap(mapToExpand, | 1157 'constructors': recurseMap(filterMap(mapToExpand, |
| 1286 (key, val) => val.mirror.isConstructor)), | 1158 (key, val) => val.mirror.isConstructor)), |
| 1287 'operators': recurseMap(_filterMap(mapToExpand, | 1159 'operators': recurseMap(filterMap(mapToExpand, |
| 1288 (key, val) => val.mirror.isOperator)), | 1160 (key, val) => val.mirror.isOperator)), |
| 1289 'methods': recurseMap(_filterMap(mapToExpand, | 1161 'methods': recurseMap(filterMap(mapToExpand, |
| 1290 (key, val) => val.mirror.isRegularMethod && !val.mirror.isOperator)) | 1162 (key, val) => val.mirror.isRegularMethod && !val.mirror.isOperator)) |
| 1291 }; | 1163 }; |
| 1292 | 1164 |
| 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. | 1165 /// Accessor to determine if this item and all of its owners are visible. |
| 1315 bool get _isVisible => _Generator._isFullChainVisible(this); | 1166 bool get _isVisible => _Generator._isFullChainVisible(this); |
| 1316 | 1167 |
| 1317 /// Given a Dart2jsMirror, find the corresponding Docgen [MirrorBased] object. | 1168 /// Given a Dart2jsMirror, find the corresponding Docgen [MirrorBased] object. |
| 1318 /// | 1169 /// |
| 1319 /// We have this global lookup function to avoid re-implementing looking up | 1170 /// 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 | 1171 /// the scoping rules for comment resolution here (it is currently done in |
| 1321 /// mirrors). If no corresponding MirrorBased object is found, we return a | 1172 /// mirrors). If no corresponding MirrorBased object is found, we return a |
| 1322 /// [DummyMirror] that simply returns the original mirror's qualifiedName | 1173 /// [DummyMirror] that simply returns the original mirror's qualifiedName |
| 1323 /// while behaving like a MirrorBased object. | 1174 /// while behaving like a MirrorBased object. |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1373 Map<String, Method> functions; | 1224 Map<String, Method> functions; |
| 1374 | 1225 |
| 1375 Map<String, Class> classes = {}; | 1226 Map<String, Class> classes = {}; |
| 1376 Map<String, Typedef> typedefs = {}; | 1227 Map<String, Typedef> typedefs = {}; |
| 1377 Map<String, Class> errors = {}; | 1228 Map<String, Class> errors = {}; |
| 1378 | 1229 |
| 1379 String packageName = ''; | 1230 String packageName = ''; |
| 1380 bool _hasBeenCheckedForPackage = false; | 1231 bool _hasBeenCheckedForPackage = false; |
| 1381 String packageIntro; | 1232 String packageIntro; |
| 1382 | 1233 |
| 1234 Library get _owningLibrary => this; | |
| 1235 | |
| 1383 /// Returns the [Library] for the given [mirror] if it has already been | 1236 /// Returns the [Library] for the given [mirror] if it has already been |
| 1384 /// created, else creates it. | 1237 /// created, else creates it. |
| 1385 factory Library(LibraryMirror mirror) { | 1238 factory Library(LibraryMirror mirror) { |
| 1386 var library = Indexable.getDocgenObject(mirror); | 1239 var library = Indexable.getDocgenObject(mirror); |
| 1387 if (library is DummyMirror) { | 1240 if (library is DummyMirror) { |
| 1388 library = new Library._(mirror); | 1241 library = new Library._(mirror); |
| 1389 } | 1242 } |
| 1390 return library; | 1243 return library; |
| 1391 } | 1244 } |
| 1392 | 1245 |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 1421 this.functions = _createMethods(_addAll(exported['methods'], | 1274 this.functions = _createMethods(_addAll(exported['methods'], |
| 1422 libraryMirror.declarations.values.where( | 1275 libraryMirror.declarations.values.where( |
| 1423 (mirror) => mirror is MethodMirror)).values, this); | 1276 (mirror) => mirror is MethodMirror)).values, this); |
| 1424 this.variables = _createVariables(_addAll(exported['variables'], | 1277 this.variables = _createVariables(_addAll(exported['variables'], |
| 1425 dart2js_util.variablesOf(libraryMirror.declarations)).values, this); | 1278 dart2js_util.variablesOf(libraryMirror.declarations)).values, this); |
| 1426 } | 1279 } |
| 1427 | 1280 |
| 1428 /// Look for the specified name starting with the current member, and | 1281 /// Look for the specified name starting with the current member, and |
| 1429 /// progressively working outward to the current library scope. | 1282 /// progressively working outward to the current library scope. |
| 1430 String findElementInScope(String name) { | 1283 String findElementInScope(String name) { |
| 1431 var lookupFunc = Indexable.determineLookupFunc(name); | 1284 var lookupFunc = determineLookupFunc(name); |
| 1432 var libraryScope = lookupFunc(mirror, name); | 1285 var libraryScope = lookupFunc(mirror, name); |
| 1433 if (libraryScope != null) { | 1286 if (libraryScope != null) { |
| 1434 var result = Indexable.getDocgenObject(libraryScope, this); | 1287 var result = Indexable.getDocgenObject(libraryScope, this); |
| 1435 if (result is DummyMirror) return packagePrefix + result.docName; | 1288 if (result is DummyMirror) return packagePrefix + result.docName; |
| 1436 return result.packagePrefix + result.docName; | 1289 return result.packagePrefix + result.docName; |
| 1437 } | 1290 } |
| 1438 return super.findElementInScope(name); | 1291 return super.findElementInScope(name); |
| 1439 } | 1292 } |
| 1440 | 1293 |
| 1441 String _mdnComment() => ''; | 1294 String _mdnComment() => ''; |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1562 /// corresponding to the actual DeclarationMirror. | 1415 /// corresponding to the actual DeclarationMirror. |
| 1563 Map<String, Map<String, DeclarationMirror>> _calcExportedItems( | 1416 Map<String, Map<String, DeclarationMirror>> _calcExportedItems( |
| 1564 LibrarySourceMirror library) { | 1417 LibrarySourceMirror library) { |
| 1565 var exports = {}; | 1418 var exports = {}; |
| 1566 exports['classes'] = {}; | 1419 exports['classes'] = {}; |
| 1567 exports['methods'] = {}; | 1420 exports['methods'] = {}; |
| 1568 exports['variables'] = {}; | 1421 exports['variables'] = {}; |
| 1569 | 1422 |
| 1570 // Determine the classes, variables and methods that are exported for a | 1423 // Determine the classes, variables and methods that are exported for a |
| 1571 // specific dependency. | 1424 // specific dependency. |
| 1572 _populateExports(LibraryDependencyMirror export, bool showExport) { | 1425 void _populateExports(LibraryDependencyMirror export, bool showExport) { |
| 1573 if (!showExport) { | 1426 if (!showExport) { |
| 1574 // Add all items, and then remove the hidden ones. | 1427 // Add all items, and then remove the hidden ones. |
| 1575 // Ex: "export foo hide bar" | 1428 // Ex: "export foo hide bar" |
| 1576 _addAll(exports['classes'], | 1429 _addAll(exports['classes'], |
| 1577 dart2js_util.typesOf(export.targetLibrary.declarations)); | 1430 dart2js_util.typesOf(export.targetLibrary.declarations)); |
| 1578 _addAll(exports['methods'], | 1431 _addAll(exports['methods'], |
| 1579 export.targetLibrary.declarations.values.where( | 1432 export.targetLibrary.declarations.values.where( |
| 1580 (mirror) => mirror is MethodMirror)); | 1433 (mirror) => mirror is MethodMirror)); |
| 1581 _addAll(exports['variables'], | 1434 _addAll(exports['variables'], |
| 1582 dart2js_util.variablesOf(export.targetLibrary.declarations)); | 1435 dart2js_util.variablesOf(export.targetLibrary.declarations)); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1660 | 1513 |
| 1661 /// Returns this object's qualified name, but following the conventions | 1514 /// 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 | 1515 /// we're using in Dartdoc, which is that library names with dots in them |
| 1663 /// have them replaced with hyphens. | 1516 /// have them replaced with hyphens. |
| 1664 String get docName => owner.docName + '.' + dart2js_util.nameOf(mirror); | 1517 String get docName => owner.docName + '.' + dart2js_util.nameOf(mirror); |
| 1665 | 1518 |
| 1666 OwnedIndexable(DeclarationMirror mirror, this.owner) : super(mirror); | 1519 OwnedIndexable(DeclarationMirror mirror, this.owner) : super(mirror); |
| 1667 | 1520 |
| 1668 /// Generates MDN comments from database.json. | 1521 /// Generates MDN comments from database.json. |
| 1669 String _mdnComment() { | 1522 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( | 1523 var domAnnotation = this.annotations.firstWhere( |
| 1684 (e) => e.mirror.qualifiedName == #metadata.DomName, | 1524 (e) => e.mirror.qualifiedName == #metadata.DomName, |
| 1685 orElse: () => null); | 1525 orElse: () => null); |
| 1686 if (domAnnotation == null) return ''; | 1526 if (domAnnotation == null) return ''; |
| 1687 var domName = domAnnotation.parameters.single; | 1527 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 | 1528 |
| 1692 throw new StateError('More than two items is not supported: $parts'); | 1529 return mdnComment(_Generator._rootDirectory, _Generator.logger, domName); |
| 1693 } | 1530 } |
| 1694 | 1531 |
| 1695 String get packagePrefix => owner.packagePrefix; | 1532 String get packagePrefix => owner.packagePrefix; |
| 1696 } | 1533 } |
| 1697 | 1534 |
| 1698 /// A class containing contents of a Dart class. | 1535 /// A class containing contents of a Dart class. |
| 1699 class Class extends OwnedIndexable implements Comparable { | 1536 class Class extends OwnedIndexable implements Comparable { |
| 1700 | 1537 |
| 1701 /// List of the names of interfaces that this class implements. | 1538 /// List of the names of interfaces that this class implements. |
| 1702 List<Class> interfaces = []; | 1539 List<Class> interfaces = []; |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1761 var superinterfaces = classMirror.superinterfaces.map( | 1598 var superinterfaces = classMirror.superinterfaces.map( |
| 1762 (interface) => new Class._possiblyDifferentOwner(interface, owner)); | 1599 (interface) => new Class._possiblyDifferentOwner(interface, owner)); |
| 1763 this.superclass = classMirror.superclass == null? null : | 1600 this.superclass = classMirror.superclass == null? null : |
| 1764 new Class._possiblyDifferentOwner(classMirror.superclass, owner); | 1601 new Class._possiblyDifferentOwner(classMirror.superclass, owner); |
| 1765 | 1602 |
| 1766 interfaces = superinterfaces.toList(); | 1603 interfaces = superinterfaces.toList(); |
| 1767 variables = _createVariables( | 1604 variables = _createVariables( |
| 1768 dart2js_util.variablesOf(classMirror.declarations), this); | 1605 dart2js_util.variablesOf(classMirror.declarations), this); |
| 1769 methods = _createMethods(classMirror.declarations.values.where( | 1606 methods = _createMethods(classMirror.declarations.values.where( |
| 1770 (mirror) => mirror is MethodMirror), this); | 1607 (mirror) => mirror is MethodMirror), this); |
| 1771 annotations = MirrorBased._createAnnotations(classMirror, _getOwningLibrary( owner)); | 1608 annotations = _createAnnotations(classMirror, owner._owningLibrary); |
| 1772 generics = _createGenerics(classMirror); | 1609 generics = _createGenerics(classMirror); |
| 1773 isAbstract = classMirror.isAbstract; | 1610 isAbstract = classMirror.isAbstract; |
| 1774 inheritedMethods = new Map<String, Method>(); | 1611 inheritedMethods = new Map<String, Method>(); |
| 1775 | 1612 |
| 1776 // Tell superclass that you are a subclass, unless you are not | 1613 // Tell superclass that you are a subclass, unless you are not |
| 1777 // visible or an intermediary mixin class. | 1614 // visible or an intermediary mixin class. |
| 1778 if (!classMirror.isNameSynthetic && _isVisible && superclass != null) { | 1615 if (!classMirror.isNameSynthetic && _isVisible && superclass != null) { |
| 1779 superclass.addSubclass(this); | 1616 superclass.addSubclass(this); |
| 1780 } | 1617 } |
| 1781 | 1618 |
| 1782 if (this.superclass != null) addInherited(superclass); | 1619 if (this.superclass != null) addInherited(superclass); |
| 1783 interfaces.forEach((interface) => addInherited(interface)); | 1620 interfaces.forEach((interface) => addInherited(interface)); |
| 1784 } | 1621 } |
| 1785 | 1622 |
| 1786 String _lookupInClassAndSuperclasses(String name) { | 1623 String _lookupInClassAndSuperclasses(String name) { |
| 1787 var lookupFunc = Indexable.determineLookupFunc(name); | 1624 var lookupFunc = determineLookupFunc(name); |
| 1788 var classScope = this; | 1625 var classScope = this; |
| 1789 while (classScope != null) { | 1626 while (classScope != null) { |
| 1790 var classFunc = lookupFunc(classScope.mirror, name); | 1627 var classFunc = lookupFunc(classScope.mirror, name); |
| 1791 if (classFunc != null) { | 1628 if (classFunc != null) { |
| 1792 return packagePrefix + Indexable.getDocgenObject(classFunc, owner).docNa me; | 1629 return packagePrefix + Indexable.getDocgenObject(classFunc, owner).docNa me; |
| 1793 } | 1630 } |
| 1794 classScope = classScope.superclass; | 1631 classScope = classScope.superclass; |
| 1795 } | 1632 } |
| 1796 return null; | 1633 return null; |
| 1797 } | 1634 } |
| 1798 | 1635 |
| 1799 /// Look for the specified name starting with the current member, and | 1636 /// Look for the specified name starting with the current member, and |
| 1800 /// progressively working outward to the current library scope. | 1637 /// progressively working outward to the current library scope. |
| 1801 String findElementInScope(String name) { | 1638 String findElementInScope(String name) { |
| 1802 var lookupFunc = Indexable.determineLookupFunc(name); | 1639 var lookupFunc = determineLookupFunc(name); |
| 1803 var result = _lookupInClassAndSuperclasses(name); | 1640 var result = _lookupInClassAndSuperclasses(name); |
| 1804 if (result != null) { | 1641 if (result != null) { |
| 1805 return result; | 1642 return result; |
| 1806 } | 1643 } |
| 1807 result = owner.findElementInScope(name); | 1644 result = owner.findElementInScope(name); |
| 1808 return result == null ? super.findElementInScope(name) : result; | 1645 return result == null ? super.findElementInScope(name) : result; |
| 1809 } | 1646 } |
| 1810 | 1647 |
| 1811 String get typeName => 'class'; | 1648 String get typeName => 'class'; |
| 1812 | 1649 |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1944 aTypedef = new Typedef._(mirror, owningLibrary); | 1781 aTypedef = new Typedef._(mirror, owningLibrary); |
| 1945 } | 1782 } |
| 1946 return aTypedef; | 1783 return aTypedef; |
| 1947 } | 1784 } |
| 1948 | 1785 |
| 1949 Typedef._(TypedefMirror mirror, Library owningLibrary) : | 1786 Typedef._(TypedefMirror mirror, Library owningLibrary) : |
| 1950 super(mirror, owningLibrary) { | 1787 super(mirror, owningLibrary) { |
| 1951 returnType = Indexable.getDocgenObject(mirror.referent.returnType).docName; | 1788 returnType = Indexable.getDocgenObject(mirror.referent.returnType).docName; |
| 1952 generics = _createGenerics(mirror); | 1789 generics = _createGenerics(mirror); |
| 1953 parameters = _createParameters(mirror.referent.parameters, owningLibrary); | 1790 parameters = _createParameters(mirror.referent.parameters, owningLibrary); |
| 1954 annotations = MirrorBased._createAnnotations(mirror, owningLibrary); | 1791 annotations = _createAnnotations(mirror, owningLibrary); |
| 1955 } | 1792 } |
| 1956 | 1793 |
| 1957 Map toMap() { | 1794 Map toMap() { |
| 1958 var map = { | 1795 var map = { |
| 1959 'name': name, | 1796 'name': name, |
| 1960 'qualifiedName': qualifiedName, | 1797 'qualifiedName': qualifiedName, |
| 1961 'comment': comment, | 1798 'comment': comment, |
| 1962 'return': returnType, | 1799 'return': returnType, |
| 1963 'parameters': recurseMap(parameters), | 1800 'parameters': recurseMap(parameters), |
| 1964 'annotations': annotations.map((a) => a.toMap()).toList(), | 1801 'annotations': annotations.map((a) => a.toMap()).toList(), |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1996 return new Variable._(variableName, mirror, owner); | 1833 return new Variable._(variableName, mirror, owner); |
| 1997 } | 1834 } |
| 1998 return variable; | 1835 return variable; |
| 1999 } | 1836 } |
| 2000 | 1837 |
| 2001 Variable._(this._variableName, VariableMirror mirror, Indexable owner) : | 1838 Variable._(this._variableName, VariableMirror mirror, Indexable owner) : |
| 2002 super(mirror, owner) { | 1839 super(mirror, owner) { |
| 2003 isFinal = mirror.isFinal; | 1840 isFinal = mirror.isFinal; |
| 2004 isStatic = mirror.isStatic; | 1841 isStatic = mirror.isStatic; |
| 2005 isConst = mirror.isConst; | 1842 isConst = mirror.isConst; |
| 2006 type = new Type(mirror.type, _getOwningLibrary(owner)); | 1843 type = new Type(mirror.type, owner._owningLibrary); |
| 2007 annotations = MirrorBased._createAnnotations(mirror, _getOwningLibrary(owner )); | 1844 annotations = _createAnnotations(mirror, owner._owningLibrary); |
| 2008 } | 1845 } |
| 2009 | 1846 |
| 2010 String get name => _variableName; | 1847 String get name => _variableName; |
| 2011 | 1848 |
| 2012 /// Generates a map describing the [Variable] object. | 1849 /// Generates a map describing the [Variable] object. |
| 2013 Map toMap() => { | 1850 Map toMap() => { |
| 2014 'name': name, | 1851 'name': name, |
| 2015 'qualifiedName': qualifiedName, | 1852 'qualifiedName': qualifiedName, |
| 2016 'comment': comment, | 1853 'comment': comment, |
| 2017 'final': isFinal, | 1854 'final': isFinal, |
| 2018 'static': isStatic, | 1855 'static': isStatic, |
| 2019 'constant': isConst, | 1856 'constant': isConst, |
| 2020 'type': new List.filled(1, type.toMap()), | 1857 'type': new List.filled(1, type.toMap()), |
| 2021 'annotations': annotations.map((a) => a.toMap()).toList() | 1858 'annotations': annotations.map((a) => a.toMap()).toList() |
| 2022 }; | 1859 }; |
| 2023 | 1860 |
| 2024 String get typeName => 'property'; | 1861 String get typeName => 'property'; |
| 2025 | 1862 |
| 2026 get comment { | 1863 get comment { |
| 2027 if (_comment != null) return _comment; | 1864 if (_comment != null) return _comment; |
| 2028 if (owner is Class) { | 1865 if (owner is Class) { |
| 2029 (owner as Class).ensureComments(); | 1866 (owner as Class).ensureComments(); |
| 2030 } | 1867 } |
| 2031 return super.comment; | 1868 return super.comment; |
| 2032 } | 1869 } |
| 2033 | 1870 |
| 2034 String findElementInScope(String name) { | 1871 String findElementInScope(String name) { |
| 2035 var lookupFunc = Indexable.determineLookupFunc(name); | 1872 var lookupFunc = determineLookupFunc(name); |
| 2036 var result = lookupFunc(mirror, name); | 1873 var result = lookupFunc(mirror, name); |
| 2037 if (result != null) { | 1874 if (result != null) { |
| 2038 result = Indexable.getDocgenObject(result); | 1875 result = Indexable.getDocgenObject(result); |
| 2039 if (result is DummyMirror) return packagePrefix + result.docName; | 1876 if (result is DummyMirror) return packagePrefix + result.docName; |
| 2040 return result.packagePrefix + result.docName; | 1877 return result.packagePrefix + result.docName; |
| 2041 } | 1878 } |
| 2042 | 1879 |
| 2043 if (owner != null) { | 1880 if (owner != null) { |
| 2044 var result = owner.findElementInScope(name); | 1881 var result = owner.findElementInScope(name); |
| 2045 if (result != null) { | 1882 if (result != null) { |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 2074 method = new Method._(mirror, owner, methodInheritedFrom); | 1911 method = new Method._(mirror, owner, methodInheritedFrom); |
| 2075 } | 1912 } |
| 2076 return method; | 1913 return method; |
| 2077 } | 1914 } |
| 2078 | 1915 |
| 2079 Method._(MethodMirror mirror, Indexable owner, this.methodInheritedFrom) | 1916 Method._(MethodMirror mirror, Indexable owner, this.methodInheritedFrom) |
| 2080 : super(mirror, owner) { | 1917 : super(mirror, owner) { |
| 2081 isStatic = mirror.isStatic; | 1918 isStatic = mirror.isStatic; |
| 2082 isAbstract = mirror.isAbstract; | 1919 isAbstract = mirror.isAbstract; |
| 2083 isConst = mirror.isConstConstructor; | 1920 isConst = mirror.isConstConstructor; |
| 2084 returnType = new Type(mirror.returnType, _getOwningLibrary(owner)); | 1921 returnType = new Type(mirror.returnType, owner._owningLibrary); |
| 2085 parameters = _createParameters(mirror.parameters, owner); | 1922 parameters = _createParameters(mirror.parameters, owner); |
| 2086 annotations = MirrorBased._createAnnotations(mirror, _getOwningLibrary(owner )); | 1923 annotations = _createAnnotations(mirror, owner._owningLibrary); |
| 2087 } | 1924 } |
| 2088 | 1925 |
| 2089 Method get originallyInheritedFrom => methodInheritedFrom == null ? | 1926 Method get originallyInheritedFrom => methodInheritedFrom == null ? |
| 2090 this : methodInheritedFrom.originallyInheritedFrom; | 1927 this : methodInheritedFrom.originallyInheritedFrom; |
| 2091 | 1928 |
| 2092 /// Look for the specified name starting with the current member, and | 1929 /// Look for the specified name starting with the current member, and |
| 2093 /// progressively working outward to the current library scope. | 1930 /// progressively working outward to the current library scope. |
| 2094 String findElementInScope(String name) { | 1931 String findElementInScope(String name) { |
| 2095 var lookupFunc = Indexable.determineLookupFunc(name); | 1932 var lookupFunc = determineLookupFunc(name); |
| 2096 | 1933 |
| 2097 var memberScope = lookupFunc(this.mirror, name); | 1934 var memberScope = lookupFunc(this.mirror, name); |
| 2098 if (memberScope != null) { | 1935 if (memberScope != null) { |
| 2099 // do we check for a dummy mirror returned here and look up with an owner | 1936 // 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 | 1937 // higher ooooor in getDocgenObject do we include more things in our |
| 2101 // lookup | 1938 // lookup |
| 2102 var result = Indexable.getDocgenObject(memberScope, owner); | 1939 var result = Indexable.getDocgenObject(memberScope, owner); |
| 2103 if (result is DummyMirror && owner.owner != null | 1940 if (result is DummyMirror && owner.owner != null |
| 2104 && owner.owner is! DummyMirror) { | 1941 && owner.owner is! DummyMirror) { |
| 2105 var aresult = Indexable.getDocgenObject(memberScope, owner.owner); | 1942 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; | 2042 final List<Annotation> annotations; |
| 2206 | 2043 |
| 2207 Parameter(ParameterMirror mirror, Library owningLibrary) | 2044 Parameter(ParameterMirror mirror, Library owningLibrary) |
| 2208 : this.mirror = mirror, | 2045 : this.mirror = mirror, |
| 2209 name = dart2js_util.nameOf(mirror), | 2046 name = dart2js_util.nameOf(mirror), |
| 2210 isOptional = mirror.isOptional, | 2047 isOptional = mirror.isOptional, |
| 2211 isNamed = mirror.isNamed, | 2048 isNamed = mirror.isNamed, |
| 2212 hasDefaultValue = mirror.hasDefaultValue, | 2049 hasDefaultValue = mirror.hasDefaultValue, |
| 2213 defaultValue = '${mirror.defaultValue}', | 2050 defaultValue = '${mirror.defaultValue}', |
| 2214 type = new Type(mirror.type, owningLibrary), | 2051 type = new Type(mirror.type, owningLibrary), |
| 2215 annotations = MirrorBased._createAnnotations(mirror, owningLibrary); | 2052 annotations = _createAnnotations(mirror, owningLibrary); |
| 2216 | 2053 |
| 2217 /// Generates a map describing the [Parameter] object. | 2054 /// Generates a map describing the [Parameter] object. |
| 2218 Map toMap() => { | 2055 Map toMap() => { |
| 2219 'name': name, | 2056 'name': name, |
| 2220 'optional': isOptional, | 2057 'optional': isOptional, |
| 2221 'named': isNamed, | 2058 'named': isNamed, |
| 2222 'default': hasDefaultValue, | 2059 'default': hasDefaultValue, |
| 2223 'type': new List.filled(1, type.toMap()), | 2060 'type': new List.filled(1, type.toMap()), |
| 2224 'value': defaultValue, | 2061 'value': defaultValue, |
| 2225 'annotations': annotations.map((a) => a.toMap()).toList() | 2062 'annotations': annotations.map((a) => a.toMap()).toList() |
| 2226 }; | 2063 }; |
| 2227 } | 2064 } |
| 2228 | 2065 |
| 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 | 2066 /// Docgen wrapper around the mirror for a return type, and/or its generic |
| 2240 /// type parameters. | 2067 /// type parameters. |
| 2241 /// | 2068 /// |
| 2242 /// Return types are of a form [outer]<[inner]>. | 2069 /// Return types are of a form [outer]<[inner]>. |
| 2243 /// If there is no [inner] part, [inner] will be an empty list. | 2070 /// If there is no [inner] part, [inner] will be an empty list. |
| 2244 /// | 2071 /// |
| 2245 /// For example: | 2072 /// For example: |
| 2246 /// int size() | 2073 /// int size() |
| 2247 /// "return" : | 2074 /// "return" : |
| 2248 /// - "outer" : "dart-core.int" | 2075 /// - "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) | 2135 .map((e) => originalMirror.getField(e.simpleName).reflectee) |
| 2309 .where((e) => e != null) | 2136 .where((e) => e != null) |
| 2310 .toList(); | 2137 .toList(); |
| 2311 } | 2138 } |
| 2312 | 2139 |
| 2313 Map toMap() => { | 2140 Map toMap() => { |
| 2314 'name': Indexable.getDocgenObject(mirror, owningLibrary).docName, | 2141 'name': Indexable.getDocgenObject(mirror, owningLibrary).docName, |
| 2315 'parameters': parameters | 2142 'parameters': parameters |
| 2316 }; | 2143 }; |
| 2317 } | 2144 } |
| 2145 | |
| 2146 /// Returns a list of meta annotations assocated with a mirror. | |
| 2147 List<Annotation> _createAnnotations(DeclarationMirror mirror, | |
| 2148 Library owningLibrary) { | |
| 2149 var annotationMirrors = mirror.metadata.where((e) => | |
| 2150 e is dart2js_mirrors.Dart2JsConstructedConstantMirror); | |
| 2151 var annotations = []; | |
| 2152 annotationMirrors.forEach((annotation) { | |
| 2153 var docgenAnnotation = new Annotation(annotation, owningLibrary); | |
| 2154 if (!_SKIPPED_ANNOTATIONS.contains( | |
| 2155 dart2js_util.qualifiedNameOf(docgenAnnotation.mirror))) { | |
| 2156 annotations.add(docgenAnnotation); | |
| 2157 } | |
| 2158 }); | |
| 2159 return annotations; | |
| 2160 } | |
| OLD | NEW |