| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | |
| 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. | |
| 4 | |
| 5 library docgen.model_helpers; | |
| 6 | |
| 7 import 'dart:collection'; | |
| 8 | |
| 9 import '../../../../sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mi
rrors.dart' | |
| 10 as dart2js_mirrors; | |
| 11 import '../../../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors_ut
il.dart' | |
| 12 as dart2js_util; | |
| 13 import '../../../../sdk/lib/_internal/compiler/implementation/mirrors/source_mir
rors.dart'; | |
| 14 import '../../../../sdk/lib/_internal/libraries.dart'; | |
| 15 | |
| 16 import 'library_helpers.dart' show includePrivateMembers; | |
| 17 import 'models.dart'; | |
| 18 import 'package_helpers.dart'; | |
| 19 | |
| 20 String getDefaultValue(ParameterMirror mirror) { | |
| 21 if (!mirror.hasDefaultValue) return null; | |
| 22 return getDefaultValueFromConstMirror(mirror.defaultValue); | |
| 23 } | |
| 24 | |
| 25 String getDefaultValueFromConstMirror( | |
| 26 dart2js_mirrors.Dart2JsConstantMirror valueMirror) { | |
| 27 | |
| 28 if (valueMirror is dart2js_mirrors.Dart2JsStringConstantMirror) { | |
| 29 return '"${valueMirror.reflectee}"'; | |
| 30 } | |
| 31 | |
| 32 if (valueMirror is dart2js_mirrors.Dart2JsListConstantMirror) { | |
| 33 var buffer = new StringBuffer('['); | |
| 34 | |
| 35 var values = new Iterable.generate(valueMirror.length, | |
| 36 (i) => valueMirror.getElement(i)) | |
| 37 .map((e) => getDefaultValueFromConstMirror(e)); | |
| 38 | |
| 39 buffer.writeAll(values, ', '); | |
| 40 | |
| 41 buffer.write(']'); | |
| 42 return buffer.toString(); | |
| 43 } | |
| 44 | |
| 45 if (valueMirror is dart2js_mirrors.Dart2JsMapConstantMirror) { | |
| 46 // TODO(kevmoo) Handle non-empty case | |
| 47 if (valueMirror.length == 0) return '{}'; | |
| 48 } | |
| 49 | |
| 50 // TODO(kevmoo) Handle consts of non-core types | |
| 51 | |
| 52 return '${valueMirror}'; | |
| 53 } | |
| 54 | |
| 55 /// Returns a list of meta annotations assocated with a mirror. | |
| 56 List<Annotation> createAnnotations(DeclarationMirror mirror, | |
| 57 Library owningLibrary) { | |
| 58 var annotationMirrors = mirror.metadata | |
| 59 .where((e) => e is dart2js_mirrors.Dart2JsConstructedConstantMirror); | |
| 60 var annotations = []; | |
| 61 annotationMirrors.forEach((annotation) { | |
| 62 var docgenAnnotation = new Annotation(annotation, owningLibrary); | |
| 63 if (!_SKIPPED_ANNOTATIONS.contains(dart2js_util.qualifiedNameOf( | |
| 64 docgenAnnotation.mirror))) { | |
| 65 annotations.add(docgenAnnotation); | |
| 66 } | |
| 67 }); | |
| 68 return annotations; | |
| 69 } | |
| 70 | |
| 71 /// A declaration is private if itself is private, or the owner is private. | |
| 72 // Issue(12202) - A declaration is public even if it's owner is private. | |
| 73 bool isHidden(DeclarationSourceMirror mirror) { | |
| 74 if (mirror is LibraryMirror) { | |
| 75 return _isLibraryPrivate(mirror); | |
| 76 } else if (mirror.owner is LibraryMirror) { | |
| 77 return (mirror.isPrivate || _isLibraryPrivate(mirror.owner) || | |
| 78 mirror.isNameSynthetic); | |
| 79 } else { | |
| 80 return (mirror.isPrivate || isHidden(mirror.owner) || | |
| 81 mirror.isNameSynthetic); | |
| 82 } | |
| 83 } | |
| 84 | |
| 85 /// Transforms the map by calling toMap on each value in it. | |
| 86 Map recurseMap(Map inputMap) { | |
| 87 var outputMap = new SplayTreeMap(); | |
| 88 inputMap.forEach((key, value) { | |
| 89 if (value is Map) { | |
| 90 outputMap[key] = recurseMap(value); | |
| 91 } else { | |
| 92 outputMap[key] = value.toMap(); | |
| 93 } | |
| 94 }); | |
| 95 return outputMap; | |
| 96 } | |
| 97 | |
| 98 Map filterMap(Map map, Function test) { | |
| 99 var exported = new Map(); | |
| 100 map.forEach((key, value) { | |
| 101 if (test(key, value)) exported[key] = value; | |
| 102 }); | |
| 103 return exported; | |
| 104 } | |
| 105 | |
| 106 /// Read a pubspec and return the library name given a [LibraryMirror]. | |
| 107 String getPackageName(LibraryMirror mirror) { | |
| 108 if (mirror.uri.scheme != 'file') return ''; | |
| 109 var rootdir = getPackageDirectory(mirror); | |
| 110 if (rootdir == null) return ''; | |
| 111 return packageNameFor(rootdir); | |
| 112 } | |
| 113 | |
| 114 | |
| 115 /// Helper that maps [mirrors] to their simple name in map. | |
| 116 Map addAll(Map map, Iterable<DeclarationMirror> mirrors) { | |
| 117 for (var mirror in mirrors) { | |
| 118 map[dart2js_util.nameOf(mirror)] = mirror; | |
| 119 } | |
| 120 return map; | |
| 121 } | |
| 122 | |
| 123 /// For the given library determine what items (if any) are exported. | |
| 124 /// | |
| 125 /// Returns a Map with three keys: "classes", "methods", and "variables" the | |
| 126 /// values of which point to a map of exported name identifiers with values | |
| 127 /// corresponding to the actual DeclarationMirror. | |
| 128 Map<String, Map<String, DeclarationMirror>> calcExportedItems( | |
| 129 LibrarySourceMirror library) { | |
| 130 var exports = {}; | |
| 131 exports['classes'] = {}; | |
| 132 exports['methods'] = {}; | |
| 133 exports['variables'] = {}; | |
| 134 | |
| 135 // Determine the classes, variables and methods that are exported for a | |
| 136 // specific dependency. | |
| 137 void _populateExports(LibraryDependencyMirror export, bool showExport) { | |
| 138 if (!showExport) { | |
| 139 // Add all items, and then remove the hidden ones. | |
| 140 // Ex: "export foo hide bar" | |
| 141 addAll(exports['classes'], | |
| 142 dart2js_util.typesOf(export.targetLibrary.declarations)); | |
| 143 addAll(exports['methods'], | |
| 144 export.targetLibrary.declarations.values.where( | |
| 145 (mirror) => mirror is MethodMirror)); | |
| 146 addAll(exports['variables'], | |
| 147 dart2js_util.variablesOf(export.targetLibrary.declarations)); | |
| 148 } | |
| 149 for (CombinatorMirror combinator in export.combinators) { | |
| 150 for (String identifier in combinator.identifiers) { | |
| 151 var librarySourceMirror = | |
| 152 export.targetLibrary as DeclarationSourceMirror; | |
| 153 var declaration = librarySourceMirror.lookupInScope(identifier); | |
| 154 if (declaration == null) { | |
| 155 // Technically this should be a bug, but some of our packages | |
| 156 // (such as the polymer package) are curently broken in this | |
| 157 // way, so we just produce a warning. | |
| 158 print('Warning identifier $identifier not found in library ' | |
| 159 '${dart2js_util.qualifiedNameOf(export.targetLibrary)}'); | |
| 160 } else { | |
| 161 var subMap = exports['classes']; | |
| 162 if (declaration is MethodMirror) { | |
| 163 subMap = exports['methods']; | |
| 164 } else if (declaration is VariableMirror) { | |
| 165 subMap = exports['variables']; | |
| 166 } | |
| 167 if (showExport) { | |
| 168 subMap[identifier] = declaration; | |
| 169 } else { | |
| 170 subMap.remove(identifier); | |
| 171 } | |
| 172 } | |
| 173 } | |
| 174 } | |
| 175 } | |
| 176 | |
| 177 Iterable<LibraryDependencyMirror> exportList = | |
| 178 library.libraryDependencies.where((lib) => lib.isExport); | |
| 179 for (LibraryDependencyMirror export in exportList) { | |
| 180 // If there is a show in the export, add only the show items to the | |
| 181 // library. Ex: "export foo show bar" | |
| 182 // Otherwise, add all items, and then remove the hidden ones. | |
| 183 // Ex: "export foo hide bar" | |
| 184 _populateExports(export, | |
| 185 export.combinators.any((combinator) => combinator.isShow)); | |
| 186 } | |
| 187 return exports; | |
| 188 } | |
| 189 | |
| 190 | |
| 191 /// Returns a map of [Variable] objects constructed from [mirrorMap]. | |
| 192 /// The optional parameter [containingLibrary] is contains data for variables | |
| 193 /// defined at the top level of a library (potentially for exporting | |
| 194 /// purposes). | |
| 195 Map<String, Variable> createVariables(Iterable<VariableMirror> mirrors, | |
| 196 Indexable owner) { | |
| 197 var data = {}; | |
| 198 // TODO(janicejl): When map to map feature is created, replace the below | |
| 199 // with a filter. Issue(#9590). | |
| 200 mirrors.forEach((dart2js_mirrors.Dart2JsFieldMirror mirror) { | |
| 201 if (includePrivateMembers || !isHidden(mirror)) { | |
| 202 var mirrorName = dart2js_util.nameOf(mirror); | |
| 203 data[mirrorName] = new Variable(mirrorName, mirror, owner); | |
| 204 } | |
| 205 }); | |
| 206 return data; | |
| 207 } | |
| 208 | |
| 209 /// Returns a map of [Method] objects constructed from [mirrorMap]. | |
| 210 /// The optional parameter [containingLibrary] is contains data for variables | |
| 211 /// defined at the top level of a library (potentially for exporting | |
| 212 /// purposes). | |
| 213 Map<String, Method> createMethods(Iterable<MethodMirror> mirrors, | |
| 214 Indexable owner) { | |
| 215 var group = new Map<String, Method>(); | |
| 216 mirrors.forEach((MethodMirror mirror) { | |
| 217 if (includePrivateMembers || !mirror.isPrivate) { | |
| 218 group[dart2js_util.nameOf(mirror)] = new Method(mirror, owner); | |
| 219 } | |
| 220 }); | |
| 221 return group; | |
| 222 } | |
| 223 | |
| 224 /// Returns a map of [Parameter] objects constructed from [mirrorList]. | |
| 225 Map<String, Parameter> createParameters(List<ParameterMirror> mirrorList, | |
| 226 Indexable owner) { | |
| 227 var data = {}; | |
| 228 mirrorList.forEach((ParameterMirror mirror) { | |
| 229 data[dart2js_util.nameOf(mirror)] = | |
| 230 new Parameter(mirror, owner.owningLibrary); | |
| 231 }); | |
| 232 return data; | |
| 233 } | |
| 234 | |
| 235 /// Returns a map of [Generic] objects constructed from the class mirror. | |
| 236 Map<String, Generic> createGenerics(TypeMirror mirror) { | |
| 237 return new Map.fromIterable(mirror.typeVariables, | |
| 238 key: (e) => dart2js_util.nameOf(e), | |
| 239 value: (e) => new Generic(e)); | |
| 240 } | |
| 241 | |
| 242 /// Annotations that we do not display in the viewer. | |
| 243 const List<String> _SKIPPED_ANNOTATIONS = const [ | |
| 244 'metadata.DocsEditable', '_js_helper.JSName', '_js_helper.Creates', | |
| 245 '_js_helper.Returns' | |
| 246 ]; | |
| 247 | |
| 248 /// Returns true if a library name starts with an underscore, and false | |
| 249 /// otherwise. | |
| 250 /// | |
| 251 /// An example that starts with _ is _js_helper. | |
| 252 /// An example that contains ._ is dart._collection.dev | |
| 253 bool _isLibraryPrivate(dart2js_mirrors.Dart2JsLibraryMirror mirror) { | |
| 254 // This method is needed because LibraryMirror.isPrivate returns `false` all | |
| 255 // the time. | |
| 256 var sdkLibrary = LIBRARIES[dart2js_util.nameOf(mirror)]; | |
| 257 if (sdkLibrary != null) { | |
| 258 return !sdkLibrary.documented; | |
| 259 } else if (dart2js_util.nameOf(mirror).startsWith('_') || dart2js_util.nameOf( | |
| 260 mirror).contains('._')) { | |
| 261 return true; | |
| 262 } | |
| 263 return false; | |
| 264 } | |
| OLD | NEW |