| 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.models.library; | |
| 6 | |
| 7 import 'dart:io'; | |
| 8 | |
| 9 import 'package:markdown/markdown.dart' as markdown; | |
| 10 | |
| 11 import '../exports/source_mirrors.dart'; | |
| 12 import '../exports/mirrors_util.dart' as dart2js_util; | |
| 13 | |
| 14 import '../library_helpers.dart'; | |
| 15 import '../package_helpers.dart'; | |
| 16 | |
| 17 import 'class.dart'; | |
| 18 import 'dummy_mirror.dart'; | |
| 19 import 'indexable.dart'; | |
| 20 import 'method.dart'; | |
| 21 import 'model_helpers.dart'; | |
| 22 import 'typedef.dart'; | |
| 23 import 'variable.dart'; | |
| 24 | |
| 25 /// A class containing contents of a Dart library. | |
| 26 class Library extends Indexable { | |
| 27 final Map<String, Class> classes = {}; | |
| 28 final Map<String, Typedef> typedefs = {}; | |
| 29 final Map<String, Class> errors = {}; | |
| 30 | |
| 31 /// Top-level variables in the library. | |
| 32 Map<String, Variable> variables; | |
| 33 | |
| 34 /// Top-level functions in the library. | |
| 35 Map<String, Method> functions; | |
| 36 | |
| 37 String packageName = ''; | |
| 38 bool _hasBeenCheckedForPackage = false; | |
| 39 String packageIntro; | |
| 40 | |
| 41 Indexable get owner => const _LibraryOwner(); | |
| 42 | |
| 43 Library get owningLibrary => this; | |
| 44 | |
| 45 /// Returns the [Library] for the given [mirror] if it has already been | |
| 46 /// created, else creates it. | |
| 47 factory Library(LibraryMirror mirror) { | |
| 48 var library = getDocgenObject(mirror); | |
| 49 if (library is DummyMirror) { | |
| 50 library = new Library._(mirror); | |
| 51 } | |
| 52 return library; | |
| 53 } | |
| 54 | |
| 55 Library._(LibraryMirror libraryMirror) : super(libraryMirror) { | |
| 56 var exported = calcExportedItems(libraryMirror, {}); | |
| 57 var exportedClasses = addAll(exported['classes'], | |
| 58 dart2js_util.typesOf(libraryMirror.declarations)); | |
| 59 updateLibraryPackage(mirror); | |
| 60 exportedClasses.forEach((String mirrorName, TypeMirror mirror) { | |
| 61 if (mirror is TypedefMirror) { | |
| 62 // This is actually a Dart2jsTypedefMirror, and it does define value, | |
| 63 // but we don't have visibility to that type. | |
| 64 if (includePrivateMembers || !mirror.isPrivate) { | |
| 65 typedefs[dart2js_util.nameOf(mirror)] = new Typedef(mirror, this); | |
| 66 } | |
| 67 } else if (mirror is ClassMirror) { | |
| 68 var clazz = new Class(mirror, this); | |
| 69 | |
| 70 if (clazz.isError()) { | |
| 71 errors[dart2js_util.nameOf(mirror)] = clazz; | |
| 72 } else { | |
| 73 classes[dart2js_util.nameOf(mirror)] = clazz; | |
| 74 } | |
| 75 } else { | |
| 76 throw new ArgumentError( | |
| 77 '${dart2js_util.nameOf(mirror)} - no class type match. '); | |
| 78 } | |
| 79 }); | |
| 80 this.functions = createMethods(addAll(exported['methods'], | |
| 81 libraryMirror.declarations.values.where( | |
| 82 (mirror) => mirror is MethodMirror)).values, this); | |
| 83 this.variables = createVariables(addAll(exported['variables'], | |
| 84 dart2js_util.variablesOf(libraryMirror.declarations)).values, this); | |
| 85 } | |
| 86 | |
| 87 /// Look for the specified name starting with the current member, and | |
| 88 /// progressively working outward to the current library scope. | |
| 89 String findElementInScope(String name) { | |
| 90 var lookupFunc = determineLookupFunc(name); | |
| 91 var libraryScope = lookupFunc(mirror, name); | |
| 92 if (libraryScope != null) { | |
| 93 var result = getDocgenObject(libraryScope, this); | |
| 94 if (result is DummyMirror) return packagePrefix + result.docName; | |
| 95 return result.packagePrefix + result.docName; | |
| 96 } | |
| 97 return super.findElementInScope(name); | |
| 98 } | |
| 99 | |
| 100 String getMdnComment() => ''; | |
| 101 | |
| 102 /// For a library's [mirror], determine the name of the package (if any) we | |
| 103 /// believe it came from (because of its file URI). | |
| 104 /// | |
| 105 /// If no package could be determined, we return an empty string. | |
| 106 void updateLibraryPackage(LibraryMirror mirror) { | |
| 107 if (mirror == null) return; | |
| 108 if (_hasBeenCheckedForPackage) return; | |
| 109 _hasBeenCheckedForPackage = true; | |
| 110 if (mirror.uri.scheme != 'file') return; | |
| 111 packageName = getPackageName(mirror); | |
| 112 // Associate the package readme with all the libraries. This is a bit | |
| 113 // wasteful, but easier than trying to figure out which partial match | |
| 114 // is best. | |
| 115 packageIntro = _packageIntro(getPackageDirectory(mirror)); | |
| 116 } | |
| 117 | |
| 118 String _packageIntro(packageDir) { | |
| 119 if (packageDir == null) return null; | |
| 120 var dir = new Directory(packageDir); | |
| 121 var files = dir.listSync(); | |
| 122 var readmes = files.where((FileSystemEntity each) => (each is File && | |
| 123 each.path.substring(packageDir.length + 1, each.path.length) | |
| 124 .startsWith('README'))).toList(); | |
| 125 if (readmes.isEmpty) return ''; | |
| 126 // If there are multiples, pick the shortest name. | |
| 127 readmes.sort((a, b) => a.path.length.compareTo(b.path.length)); | |
| 128 var readme = readmes.first; | |
| 129 var linkResolver = (name) => globalFixReference(name); | |
| 130 var contents = markdown.markdownToHtml(readme | |
| 131 .readAsStringSync(), linkResolver: linkResolver, | |
| 132 inlineSyntaxes: MARKDOWN_SYNTAXES); | |
| 133 return contents; | |
| 134 } | |
| 135 | |
| 136 String get packagePrefix => packageName == null || packageName.isEmpty ? | |
| 137 '' : '$packageName/'; | |
| 138 | |
| 139 Map get previewMap { | |
| 140 var map = {'packageName': packageName}; | |
| 141 map.addAll(super.previewMap); | |
| 142 if (packageIntro != null) { | |
| 143 map['packageIntro'] = packageIntro; | |
| 144 } | |
| 145 var version = packageVersion(mirror); | |
| 146 if (version != '' && version != null) map['version'] = version; | |
| 147 return map; | |
| 148 } | |
| 149 | |
| 150 String get name => docName; | |
| 151 | |
| 152 String get docName => getLibraryDocName(mirror); | |
| 153 | |
| 154 /// Generates a map describing the [Library] object. | |
| 155 Map toMap() => { | |
| 156 'name': name, | |
| 157 'qualifiedName': qualifiedName, | |
| 158 'comment': comment, | |
| 159 'variables': recurseMap(variables), | |
| 160 'functions': expandMethodMap(functions), | |
| 161 'classes': { | |
| 162 'class': classes.values.where((c) => c.isVisible) | |
| 163 .map((e) => e.previewMap).toList(), | |
| 164 'typedef': recurseMap(typedefs), | |
| 165 'error': errors.values.where((e) => e.isVisible) | |
| 166 .map((e) => e.previewMap).toList() | |
| 167 }, | |
| 168 'packageName': packageName, | |
| 169 'packageIntro': packageIntro | |
| 170 }; | |
| 171 | |
| 172 String get typeName => 'library'; | |
| 173 | |
| 174 bool isValidMirror(DeclarationMirror mirror) => mirror is LibraryMirror; | |
| 175 } | |
| 176 | |
| 177 /// Dummy implementation of Indexable to represent the owner of a Library. | |
| 178 class _LibraryOwner implements Indexable { | |
| 179 const _LibraryOwner(); | |
| 180 | |
| 181 String get docName => ''; | |
| 182 | |
| 183 bool get isPrivate => false; | |
| 184 | |
| 185 Indexable get owner => null; | |
| 186 | |
| 187 // This is a known incomplete implementation of Indexable | |
| 188 // overriding noSuchMethod to remove static warnings | |
| 189 noSuchMethod(Invocation invocation) { | |
| 190 throw new UnimplementedError(invocation.memberName.toString()); | |
| 191 } | |
| 192 } | |
| OLD | NEW |