Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(809)

Side by Side Diff: pkg/docgen/lib/docgen.dart

Issue 35743002: Make docgen able to generate pkg docs and save the package names (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Make sure we have an ending newline in index.txt, also write a JSON index, and include packageName … Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « pkg/docgen/bin/upload_docgen.py ('k') | pkg/docgen/pubspec.yaml » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 /** 5 /**
6 * **docgen** is a tool for creating machine readable representations of Dart 6 * **docgen** is a tool for creating machine readable representations of Dart
7 * code metadata, including: classes, members, comments and annotations. 7 * code metadata, including: classes, members, comments and annotations.
8 * 8 *
9 * docgen is run on a `.dart` file or a directory containing `.dart` files. 9 * docgen is run on a `.dart` file or a directory containing `.dart` files.
10 * 10 *
11 * $ dart docgen.dart [OPTIONS] [FILE/DIR] 11 * $ dart docgen.dart [OPTIONS] [FILE/DIR]
12 * 12 *
13 * This creates files called `docs/<library_name>.yaml` in your current 13 * This creates files called `docs/<library_name>.yaml` in your current
14 * working directory. 14 * working directory.
15 */ 15 */
16 library docgen; 16 library docgen;
17 17
18 import 'dart:convert'; 18 import 'dart:convert';
19 import 'dart:io'; 19 import 'dart:io';
20 import 'dart:async'; 20 import 'dart:async';
21 21
22 import 'package:logging/logging.dart'; 22 import 'package:logging/logging.dart';
23 import 'package:markdown/markdown.dart' as markdown; 23 import 'package:markdown/markdown.dart' as markdown;
24 import 'package:path/path.dart' as path; 24 import 'package:path/path.dart' as path;
25 import 'package:yaml/yaml.dart';
25 26
26 import 'dart2yaml.dart'; 27 import 'dart2yaml.dart';
27 import 'src/io.dart'; 28 import 'src/io.dart';
28 import '../../../sdk/lib/_internal/compiler/compiler.dart' as api; 29 import '../../../sdk/lib/_internal/compiler/compiler.dart' as api;
29 import '../../../sdk/lib/_internal/compiler/implementation/filenames.dart'; 30 import '../../../sdk/lib/_internal/compiler/implementation/filenames.dart';
30 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirro r.dart' 31 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirro r.dart'
31 as dart2js; 32 as dart2js;
32 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors.dart' ; 33 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors.dart' ;
33 import '../../../sdk/lib/_internal/compiler/implementation/source_file_provider. dart'; 34 import '../../../sdk/lib/_internal/compiler/implementation/source_file_provider. dart';
34 import '../../../sdk/lib/_internal/libraries.dart'; 35 import '../../../sdk/lib/_internal/libraries.dart';
35 36
36 var logger = new Logger('Docgen'); 37 var logger = new Logger('Docgen');
37 38
38 const String USAGE = 'Usage: dart docgen.dart [OPTIONS] [fooDir/barFile]'; 39 const String USAGE = 'Usage: dart docgen.dart [OPTIONS] [fooDir/barFile]';
39 40
40 41
41 List<String> validAnnotations = const ['metadata.Experimental', 42 List<String> validAnnotations = const ['metadata.Experimental',
42 'metadata.DomName', 'metadata.Deprecated', 'metadata.Unstable', 43 'metadata.DomName', 'metadata.Deprecated', 'metadata.Unstable',
43 'meta.deprecated', 'metadata.SupportedBrowser']; 44 'meta.deprecated', 'metadata.SupportedBrowser'];
44 45
45 /// Current library being documented to be used for comment links. 46 /// Current library being documented to be used for comment links.
46 LibraryMirror _currentLibrary; 47 LibraryMirror _currentLibrary;
47 48
48 /// Current class being documented to be used for comment links. 49 /// Current class being documented to be used for comment links.
49 ClassMirror _currentClass; 50 ClassMirror _currentClass;
50 51
51 /// Current member being documented to be used for comment links. 52 /// Current member being documented to be used for comment links.
52 MemberMirror _currentMember; 53 MemberMirror _currentMember;
53 54
54 /// Support for [:foo:]-style code comments to the markdown parser. 55 /// Support for [:foo:]-style code comments to the markdown parser.
55 List<markdown.InlineSyntax> markdownSyntaxes = 56 List<markdown.InlineSyntax> markdownSyntaxes =
56 [new markdown.CodeSyntax(r'\[:\s?((?:.|\n)*?)\s?:\]')]; 57 [new markdown.CodeSyntax(r'\[:\s?((?:.|\n)*?)\s?:\]')];
57 58
58 /// Resolves reference links in doc comments. 59 /// Resolves reference links in doc comments.
59 markdown.Resolver linkResolver; 60 markdown.Resolver linkResolver;
60 61
61 /// Index of all indexable items. This also ensures that no class is 62 /// Index of all indexable items. This also ensures that no class is
62 /// created more than once. 63 /// created more than once.
63 Map<String, Indexable> entityMap = new Map<String, Indexable>(); 64 Map<String, Indexable> entityMap = new Map<String, Indexable>();
64 65
65 /// This is set from the command line arguments flag --include-private 66 /// This is set from the command line arguments flag --include-private
66 bool _includePrivate = false; 67 bool _includePrivate = false;
67 68
68 // TODO(janicejl): Make MDN content generic or pluggable. Maybe move 69 // TODO(janicejl): Make MDN content generic or pluggable. Maybe move
69 // MDN-specific code to its own library that is imported into the default impl? 70 // MDN-specific code to its own library that is imported into the default impl?
70 /// Map of all the comments for dom elements from MDN. 71 /// Map of all the comments for dom elements from MDN.
71 Map _mdn; 72 Map _mdn;
72 73
73 /** 74 /**
74 * Docgen constructor initializes the link resolver for markdown parsing. 75 * Docgen constructor initializes the link resolver for markdown parsing.
75 * Also initializes the command line arguments. 76 * Also initializes the command line arguments.
76 * 77 *
77 * [packageRoot] is the packages directory of the directory being analyzed. 78 * [packageRoot] is the packages directory of the directory being analyzed.
78 * If [includeSdk] is `true`, then any SDK libraries explicitly imported will 79 * If [includeSdk] is `true`, then any SDK libraries explicitly imported will
79 * also be documented. 80 * also be documented.
80 * If [parseSdk] is `true`, then all Dart SDK libraries will be documented. 81 * If [parseSdk] is `true`, then all Dart SDK libraries will be documented.
(...skipping 21 matching lines...) Expand all
102 } 103 }
103 logger.info('Package Root: ${packageRoot}'); 104 logger.info('Package Root: ${packageRoot}');
104 linkResolver = (name) => 105 linkResolver = (name) =>
105 fixReference(name, _currentLibrary, _currentClass, _currentMember); 106 fixReference(name, _currentLibrary, _currentClass, _currentMember);
106 107
107 return getMirrorSystem(files, packageRoot: packageRoot, parseSdk: parseSdk) 108 return getMirrorSystem(files, packageRoot: packageRoot, parseSdk: parseSdk)
108 .then((MirrorSystem mirrorSystem) { 109 .then((MirrorSystem mirrorSystem) {
109 if (mirrorSystem.libraries.isEmpty) { 110 if (mirrorSystem.libraries.isEmpty) {
110 throw new StateError('No library mirrors were created.'); 111 throw new StateError('No library mirrors were created.');
111 } 112 }
112 _documentLibraries(mirrorSystem.libraries.values,includeSdk: includeSdk, 113 var librariesWeAskedFor = _listLibraries(files);
113 outputToYaml: outputToYaml, append: append, parseSdk: parseSdk, 114 var librariesWeGot = mirrorSystem.libraries.values.where((each)
115 => each.uri.scheme == 'file');
116 var sdkLibraries = mirrorSystem.libraries.values.where(
117 (each) => each.uri.scheme == 'dart');
118 var librariesWeGotByPath = new Map.fromIterables(
119 librariesWeGot.map((each) => each.uri.toFilePath()),
120 librariesWeGot);
121 var librariesToDocument = librariesWeAskedFor.map((each) =>
122 librariesWeGotByPath
123 .putIfAbsent(each, () => throw "Missing library $each")).toList();
124 librariesToDocument.addAll((includeSdk || parseSdk) ? sdkLibraries : []);
125 _documentLibraries(librariesToDocument, includeSdk: includeSdk,
126 outputToYaml: outputToYaml, append: append, parseSdk: parseSdk,
114 introduction: introduction); 127 introduction: introduction);
115
116 return true; 128 return true;
117 }); 129 });
118 } 130 }
119 131
132 /// For a [library] and its corresponding [mirror] that we believe come
133 /// from a package (because it has a file
134 /// URI) look for the package name and set it on [library].
135 _findPackage(Library library, LibraryMirror mirror) {
136 if (mirror.uri.scheme != 'file') return;
137 var filePath = mirror.uri.toFilePath();
138 // We assume that we are documenting only libraries under package/lib
139 var rootdir = path.dirname((path.dirname(filePath)));
140 var pubspec = path.join(rootdir, 'pubspec.yaml');
141 library.packageName = _packageName(pubspec);
142 }
143
120 List<String> _listLibraries(List<String> args) { 144 List<String> _listLibraries(List<String> args) {
121 if (args.length != 1) throw new UnsupportedError(USAGE);
122 var libraries = new List<String>(); 145 var libraries = new List<String>();
123 var type = FileSystemEntity.typeSync(args[0]); 146 for (var arg in args) {
147 var type = FileSystemEntity.typeSync(arg);
124 148
125 if (type == FileSystemEntityType.FILE) { 149 if (type == FileSystemEntityType.FILE) {
126 if (args[0].endsWith('.dart')) { 150 if (arg.endsWith('.dart')) {
127 libraries.add(path.absolute(args[0])); 151 libraries.add(path.absolute(arg));
128 logger.info('Added to libraries: ${libraries.last}'); 152 logger.info('Added to libraries: ${libraries.last}');
153 }
154 } else {
155 libraries.addAll(_listDartFromDir(arg));
129 } 156 }
130 } else {
131 libraries.addAll(_listDartFromDir(args[0]));
132 } 157 }
133 return libraries; 158 return libraries;
134 } 159 }
135 160
136 List<String> _listDartFromDir(String args) { 161 List<String> _listDartFromDir(String args) {
137 var libraries = []; 162 var libraries = [];
138 // To avoid anaylzing package files twice, only files with paths not 163 // To avoid anaylzing package files twice, only files with paths not
139 // containing '/packages' will be added. The only exception is if the file to 164 // containing '/packages' will be added. The only exception is if the file to
140 // analyze already has a '/package' in its path. 165 // analyze already has a '/package' in its path.
141 var files = listDir(args, recursive: true).where((f) => f.endsWith('.dart') && 166 var files = listDir(args, recursive: true).where((f) => f.endsWith('.dart') &&
142 (!f.contains('${path.separator}packages') || 167 (!f.contains('${path.separator}packages') ||
143 args.contains('${path.separator}packages'))).toList(); 168 args.contains('${path.separator}packages'))).toList();
144 169
145 files.forEach((f) { 170 files.forEach((String f) {
146 // Only add the file if it does not contain 'part of' 171 // Only include libraries at the top level of "lib"
147 // TODO(janicejl): Remove when Issue(12406) is resolved. 172 if (path.basename(path.dirname(f)) == 'lib') {
148 var contents = new File(f).readAsStringSync(); 173 // Only add the file if it does not contain 'part of'
149 if (!(contents.contains(new RegExp('\npart of ')) || 174 // TODO(janicejl): Remove when Issue(12406) is resolved.
150 contents.startsWith(new RegExp('part of ')))) { 175 var contents = new File(f).readAsStringSync();
151 libraries.add(f); 176 if (!(contents.contains(new RegExp('\npart of ')) ||
152 logger.info('Added to libraries: $f'); 177 contents.startsWith(new RegExp('part of ')))) {
178 libraries.add(f);
179 logger.info('Added to libraries: $f');
180 }
153 } 181 }
154 }); 182 });
155 return libraries; 183 return libraries;
156 } 184 }
157 185
158 String _findPackageRoot(String directory) { 186 String _findPackageRoot(String directory) {
159 var files = listDir(directory, recursive: true); 187 var files = listDir(directory, recursive: true);
160 // Return '' means that there was no pubspec.yaml and therefor no packageRoot. 188 // Return '' means that there was no pubspec.yaml and therefor no packageRoot.
161 String packageRoot = files.firstWhere((f) => 189 String packageRoot = files.firstWhere((f) =>
162 f.endsWith('${path.separator}pubspec.yaml'), orElse: () => ''); 190 f.endsWith('${path.separator}pubspec.yaml'), orElse: () => '');
163 if (packageRoot != '') { 191 if (packageRoot != '') {
164 packageRoot = path.join(path.dirname(packageRoot), 'packages'); 192 packageRoot = path.join(path.dirname(packageRoot), 'packages');
165 } 193 }
166 return packageRoot; 194 return packageRoot;
167 } 195 }
168 196
197 /**
198 * Read a pubspec and return the library name.
199 */
200 String _packageName(String pubspecName) {
201 File pubspec = new File(pubspecName);
202 if (!pubspec.existsSync()) return '';
203 var contents = pubspec.readAsStringSync();
204 var spec = loadYaml(contents);
205 return spec["name"];
206 }
207
169 List<String> _listSdk() { 208 List<String> _listSdk() {
170 var sdk = new List<String>(); 209 var sdk = new List<String>();
171 LIBRARIES.forEach((String name, LibraryInfo info) { 210 LIBRARIES.forEach((String name, LibraryInfo info) {
172 if (info.documented) { 211 if (info.documented) {
173 sdk.add('dart:$name'); 212 sdk.add('dart:$name');
174 logger.info('Add to SDK: ${sdk.last}'); 213 logger.info('Add to SDK: ${sdk.last}');
175 } 214 }
176 }); 215 });
177 return sdk; 216 return sdk;
178 } 217 }
(...skipping 14 matching lines...) Expand all
193 } 232 }
194 233
195 /** 234 /**
196 * Analyzes set of libraries and provides a mirror system which can be used 235 * Analyzes set of libraries and provides a mirror system which can be used
197 * for static inspection of the source code. 236 * for static inspection of the source code.
198 */ 237 */
199 Future<MirrorSystem> _analyzeLibraries(List<String> libraries, 238 Future<MirrorSystem> _analyzeLibraries(List<String> libraries,
200 String libraryRoot, {String packageRoot}) { 239 String libraryRoot, {String packageRoot}) {
201 SourceFileProvider provider = new CompilerSourceFileProvider(); 240 SourceFileProvider provider = new CompilerSourceFileProvider();
202 api.DiagnosticHandler diagnosticHandler = 241 api.DiagnosticHandler diagnosticHandler =
203 new FormattingDiagnosticHandler(provider).diagnosticHandler; 242 (new FormattingDiagnosticHandler(provider)
243 ..showHints = false
244 ..showWarnings = false)
245 .diagnosticHandler;
204 Uri libraryUri = new Uri(scheme: 'file', path: appendSlash(libraryRoot)); 246 Uri libraryUri = new Uri(scheme: 'file', path: appendSlash(libraryRoot));
205 Uri packageUri = null; 247 Uri packageUri = null;
206 if (packageRoot != null) { 248 if (packageRoot != null) {
207 packageUri = new Uri(scheme: 'file', path: appendSlash(packageRoot)); 249 packageUri = new Uri(scheme: 'file', path: appendSlash(packageRoot));
208 } 250 }
209 List<Uri> librariesUri = <Uri>[]; 251 List<Uri> librariesUri = <Uri>[];
210 libraries.forEach((library) { 252 libraries.forEach((library) {
211 librariesUri.add(currentDirectory.resolve(library)); 253 librariesUri.add(currentDirectory.resolve(library));
212 }); 254 });
213 return dart2js.analyze(librariesUri, libraryUri, packageUri, 255 return dart2js.analyze(librariesUri, libraryUri, packageUri,
214 provider.readStringFromUri, diagnosticHandler, 256 provider.readStringFromUri, diagnosticHandler,
215 ['--preserve-comments', '--categories=Client,Server']) 257 ['--preserve-comments', '--categories=Client,Server'])
216 ..catchError((error) { 258 ..catchError((error) {
217 logger.severe('Error: Failed to create mirror system. '); 259 logger.severe('Error: Failed to create mirror system. ');
218 // TODO(janicejl): Use the stack trace package when bug is resolved. 260 // TODO(janicejl): Use the stack trace package when bug is resolved.
219 // Currently, a string is thrown when it fails to create a mirror 261 // Currently, a string is thrown when it fails to create a mirror
220 // system, and it is not possible to use the stack trace. BUG(#11622) 262 // system, and it is not possible to use the stack trace. BUG(#11622)
221 // To avoid printing the stack trace. 263 // To avoid printing the stack trace.
222 exit(1); 264 exit(1);
223 }); 265 });
224 } 266 }
225 267
226 /** 268 /**
227 * Creates documentation for filtered libraries. 269 * Creates documentation for filtered libraries.
228 */ 270 */
229 void _documentLibraries(List<LibraryMirror> libs, {bool includeSdk: false, 271 void _documentLibraries(List<LibraryMirror> libs, {bool includeSdk: false,
230 bool outputToYaml: true, bool append: false, bool parseSdk: false, 272 bool outputToYaml: true, bool append: false, bool parseSdk: false,
231 String introduction: ''}) { 273 String introduction: ''}) {
232 libs.forEach((lib) { 274 libs.forEach((lib) {
233 // Files belonging to the SDK have a uri that begins with 'dart:'. 275 // Files belonging to the SDK have a uri that begins with 'dart:'.
234 if (includeSdk || !lib.uri.toString().startsWith('dart:')) { 276 if (includeSdk || !lib.uri.toString().startsWith('dart:')) {
235 var library = generateLibrary(lib); 277 var library = generateLibrary(lib);
236 entityMap[library.qualifiedName] = library; 278 entityMap[library.qualifiedName] = library;
237 } 279 }
238 }); 280 });
239 // After everything is created, do a pass through all classes to make sure no 281 // After everything is created, do a pass through all classes to make sure no
240 // intermediate classes created by mixins are included. 282 // intermediate classes created by mixins are included.
241 entityMap.values.where((e) => e is Class).forEach((c) => c.makeValid()); 283 entityMap.values.where((e) => e is Class).forEach((c) => c.makeValid());
242 // Everything is a subclass of Object, therefore empty the list to avoid a 284 // Everything is a subclass of Object, therefore empty the list to avoid a
243 // giant list of subclasses to be printed out. 285 // giant list of subclasses to be printed out.
244 if (parseSdk) entityMap['dart.core.Object'].subclasses.clear(); 286 if (parseSdk) entityMap['dart.core.Object'].subclasses.clear();
245 287
246 var filteredEntities = entityMap.values.where(_isVisible); 288 var filteredEntities = entityMap.values.where(_isVisible);
247 289
248 // Outputs a JSON file with all libraries and their preview comments. 290 // Outputs a JSON file with all libraries and their preview comments.
249 // This will help the viewer know what libraries are available to read in. 291 // This will help the viewer know what libraries are available to read in.
250 var libraryMap; 292 var libraryMap;
251 if (append) { 293 if (append) {
252 var docsDir = listDir('docs'); 294 var docsDir = listDir('docs');
253 if (!docsDir.contains('docs/library_list.json')) { 295 if (!docsDir.contains('docs/library_list.json')) {
254 throw new StateError('No library_list.json'); 296 throw new StateError('No library_list.json');
255 } 297 }
256 libraryMap = 298 libraryMap =
257 JSON.decode(new File('docs/library_list.json').readAsStringSync()); 299 JSON.decode(new File('docs/library_list.json').readAsStringSync());
258 libraryMap['libraries'].addAll(filteredEntities 300 libraryMap['libraries'].addAll(filteredEntities
259 .where((e) => e is Library) 301 .where((e) => e is Library)
260 .map((e) => e.previewMap)); 302 .map((e) => e.previewMap));
261 if (introduction.isNotEmpty) { 303 if (introduction.isNotEmpty) {
262 var intro = libraryMap['introduction']; 304 var intro = libraryMap['introduction'];
263 if (intro.isNotEmpty) intro += '<br/><br/>'; 305 if (intro.isNotEmpty) intro += '<br/><br/>';
264 intro += markdown.markdownToHtml( 306 intro += markdown.markdownToHtml(
265 new File(introduction).readAsStringSync(), 307 new File(introduction).readAsStringSync(),
266 linkResolver: linkResolver, inlineSyntaxes: markdownSyntaxes); 308 linkResolver: linkResolver, inlineSyntaxes: markdownSyntaxes);
267 libraryMap['introduction'] = intro; 309 libraryMap['introduction'] = intro;
268 } 310 }
269 outputToYaml = libraryMap['filetype'] == 'yaml'; 311 outputToYaml = libraryMap['filetype'] == 'yaml';
270 } else { 312 } else {
271 libraryMap = { 313 libraryMap = {
272 'libraries' : filteredEntities.where((e) => 314 'libraries' : filteredEntities.where((e) =>
273 e is Library).map((e) => e.previewMap).toList(), 315 e is Library).map((e) => e.previewMap).toList(),
274 'introduction' : introduction == '' ? 316 'introduction' : introduction == '' ?
275 '' : markdown.markdownToHtml(new File(introduction) 317 '' : markdown.markdownToHtml(new File(introduction)
276 .readAsStringSync(), linkResolver: linkResolver, 318 .readAsStringSync(), linkResolver: linkResolver,
277 inlineSyntaxes: markdownSyntaxes), 319 inlineSyntaxes: markdownSyntaxes),
278 'filetype' : outputToYaml ? 'yaml' : 'json' 320 'filetype' : outputToYaml ? 'yaml' : 'json'
279 }; 321 };
280 } 322 }
281 _writeToFile(JSON.encode(libraryMap), 'library_list.json'); 323 _writeToFile(JSON.encode(libraryMap), 'library_list.json');
282 // Output libraries and classes to file after all information is generated. 324 // Output libraries and classes to file after all information is generated.
283 filteredEntities.where((e) => e is Class || e is Library).forEach((output) { 325 filteredEntities.where((e) => e is Class || e is Library).forEach((output) {
284 _writeIndexableToFile(output, outputToYaml); 326 _writeIndexableToFile(output, outputToYaml);
285 }); 327 });
286 // Outputs all the qualified names documented with their type. 328 // Outputs all the qualified names documented with their type.
287 // This will help generate search results. 329 // This will help generate search results.
288 _writeToFile(filteredEntities.map((e) => 330 _writeToFile(filteredEntities.map((e) =>
289 '${e.qualifiedName} ${e.typeName}').join('\n'), 331 '${e.qualifiedName} ${e.typeName}').join('\n') + '\n',
290 'index.txt', append: append); 332 'index.txt', append: append);
333 var index = new Map.fromIterables(
334 filteredEntities.map((e) => e.qualifiedName),
335 filteredEntities.map((e) => e.typeName));
terry 2013/10/24 14:17:30 Minor point, I'm sure it's not a perf issue now, b
336 if (append) {
337 var previousIndex =
338 JSON.decode(new File('docs/index.json').readAsStringSync());
339 index.addAll(previousIndex);
340 }
341 _writeToFile(JSON.encode(index), 'index.json');
291 } 342 }
292 343
293 Library generateLibrary(dart2js.Dart2JsLibraryMirror library) { 344 Library generateLibrary(dart2js.Dart2JsLibraryMirror library) {
294 _currentLibrary = library; 345 _currentLibrary = library;
295 var result = new Library(library.qualifiedName, _commentToHtml(library), 346 var result = new Library(library.qualifiedName, _commentToHtml(library),
296 _variables(library.variables), 347 _variables(library.variables),
297 _methods(library.functions), 348 _methods(library.functions),
298 _classes(library.classes), _isHidden(library)); 349 _classes(library.classes), _isHidden(library));
350 _findPackage(result, library);
299 logger.fine('Generated library for ${result.name}'); 351 logger.fine('Generated library for ${result.name}');
300 return result; 352 return result;
301 } 353 }
302 354
303 void _writeIndexableToFile(Indexable result, bool outputToYaml) { 355 void _writeIndexableToFile(Indexable result, bool outputToYaml) {
304 if (outputToYaml) { 356 if (outputToYaml) {
305 _writeToFile(getYamlString(result.toMap()), '${result.qualifiedName}.yaml'); 357 _writeToFile(getYamlString(result.toMap()), '${result.qualifiedName}.yaml');
306 } else { 358 } else {
307 _writeToFile(JSON.encode(result.toMap()), '${result.qualifiedName}.json'); 359 _writeToFile(JSON.encode(result.toMap()), '${result.qualifiedName}.json');
308 } 360 }
309 } 361 }
310 362
311 /** 363 /**
312 * Returns true if a library name starts with an underscore, and false 364 * Returns true if a library name starts with an underscore, and false
313 * otherwise. 365 * otherwise.
314 * 366 *
315 * An example that starts with _ is _js_helper. 367 * An example that starts with _ is _js_helper.
316 * An example that contains ._ is dart._collection.dev 368 * An example that contains ._ is dart._collection.dev
317 */ 369 */
318 // This is because LibraryMirror.isPrivate returns `false` all the time. 370 // This is because LibraryMirror.isPrivate returns `false` all the time.
319 bool _isLibraryPrivate(LibraryMirror mirror) { 371 bool _isLibraryPrivate(LibraryMirror mirror) {
320 var sdkLibrary = LIBRARIES[mirror.simpleName]; 372 var sdkLibrary = LIBRARIES[mirror.simpleName];
321 if (sdkLibrary != null) { 373 if (sdkLibrary != null) {
322 return !sdkLibrary.documented; 374 return !sdkLibrary.documented;
323 } else if (mirror.simpleName.startsWith('_') || 375 } else if (mirror.simpleName.startsWith('_') ||
324 mirror.simpleName.contains('._')) { 376 mirror.simpleName.contains('._')) {
325 return true; 377 return true;
326 } 378 }
327 return false; 379 return false;
328 } 380 }
329 381
330 /** 382 /**
331 * A declaration is private if itself is private, or the owner is private. 383 * A declaration is private if itself is private, or the owner is private.
332 */ 384 */
333 // Issue(12202) - A declaration is public even if it's owner is private. 385 // Issue(12202) - A declaration is public even if it's owner is private.
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 } 437 }
386 }); 438 });
387 439
388 commentText = commentText == null ? '' : 440 commentText = commentText == null ? '' :
389 markdown.markdownToHtml(commentText.trim(), linkResolver: linkResolver, 441 markdown.markdownToHtml(commentText.trim(), linkResolver: linkResolver,
390 inlineSyntaxes: markdownSyntaxes); 442 inlineSyntaxes: markdownSyntaxes);
391 return commentText; 443 return commentText;
392 } 444 }
393 445
394 /** 446 /**
395 * Generates MDN comments from database.json. 447 * Generates MDN comments from database.json.
396 */ 448 */
397 void _mdnComment(Indexable item) { 449 void _mdnComment(Indexable item) {
398 //Check if MDN is loaded. 450 //Check if MDN is loaded.
399 if (_mdn == null) { 451 if (_mdn == null) {
400 // Reading in MDN related json file. 452 // Reading in MDN related json file.
401 var mdnDir = path.join(path.dirname(path.dirname(path.dirname(path.dirname( 453 var mdnDir = path.join(path.dirname(path.dirname(path.dirname(path.dirname(
402 path.absolute(new Options().script))))), 'utils', 'apidoc', 'mdn'); 454 path.absolute(new Options().script))))), 'utils', 'apidoc', 'mdn');
403 _mdn = JSON.decode(new File(path.join(mdnDir, 'database.json')) 455 _mdn = JSON.decode(new File(path.join(mdnDir, 'database.json'))
404 .readAsStringSync()); 456 .readAsStringSync());
405 } 457 }
406 if (item.comment.isNotEmpty) return; 458 if (item.comment.isNotEmpty) return;
407 var domAnnotation = item.annotations.firstWhere( 459 var domAnnotation = item.annotations.firstWhere(
408 (e) => e.qualifiedName == 'metadata.DomName', orElse: () => null); 460 (e) => e.qualifiedName == 'metadata.DomName', orElse: () => null);
409 if (domAnnotation == null) return; 461 if (domAnnotation == null) return;
410 var domName = domAnnotation.parameters.single; 462 var domName = domAnnotation.parameters.single;
411 var parts = domName.split('.'); 463 var parts = domName.split('.');
412 if (parts.length == 2) item.comment = _mdnMemberComment(parts[0], parts[1]); 464 if (parts.length == 2) item.comment = _mdnMemberComment(parts[0], parts[1]);
413 if (parts.length == 1) item.comment = _mdnTypeComment(parts[0]); 465 if (parts.length == 1) item.comment = _mdnTypeComment(parts[0]);
414 } 466 }
415 467
416 /** 468 /**
417 * Generates the MDN Comment for variables and method DOM elements. 469 * Generates the MDN Comment for variables and method DOM elements.
418 */ 470 */
419 String _mdnMemberComment(String type, String member) { 471 String _mdnMemberComment(String type, String member) {
420 var mdnType = _mdn[type]; 472 var mdnType = _mdn[type];
421 if (mdnType == null) return ''; 473 if (mdnType == null) return '';
422 var mdnMember = mdnType['members'].firstWhere((e) => e['name'] == member, 474 var mdnMember = mdnType['members'].firstWhere((e) => e['name'] == member,
423 orElse: () => null); 475 orElse: () => null);
424 if (mdnMember == null) return ''; 476 if (mdnMember == null) return '';
425 if (mdnMember['help'] == null || mdnMember['help'] == '') return ''; 477 if (mdnMember['help'] == null || mdnMember['help'] == '') return '';
426 if (mdnMember['url'] == null) return ''; 478 if (mdnMember['url'] == null) return '';
427 return _htmlMdn(mdnMember['help'], mdnMember['url']); 479 return _htmlMdn(mdnMember['help'], mdnMember['url']);
428 } 480 }
429 481
430 /** 482 /**
431 * Generates the MDN Comment for class DOM elements. 483 * Generates the MDN Comment for class DOM elements.
432 */ 484 */
433 String _mdnTypeComment(String type) { 485 String _mdnTypeComment(String type) {
434 var mdnType = _mdn[type]; 486 var mdnType = _mdn[type];
435 if (mdnType == null) return ''; 487 if (mdnType == null) return '';
436 if (mdnType['summary'] == null || mdnType['summary'] == "") return ''; 488 if (mdnType['summary'] == null || mdnType['summary'] == "") return '';
437 if (mdnType['srcUrl'] == null) return ''; 489 if (mdnType['srcUrl'] == null) return '';
438 return _htmlMdn(mdnType['summary'], mdnType['srcUrl']); 490 return _htmlMdn(mdnType['summary'], mdnType['srcUrl']);
439 } 491 }
440 492
441 String _htmlMdn(String content, String url) { 493 String _htmlMdn(String content, String url) {
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
620 672
621 /// Documentation comment with converted markdown. 673 /// Documentation comment with converted markdown.
622 String comment; 674 String comment;
623 675
624 /// Qualified Name of the owner of this Indexable Item. 676 /// Qualified Name of the owner of this Indexable Item.
625 /// For Library, owner will be ""; 677 /// For Library, owner will be "";
626 String owner; 678 String owner;
627 679
628 Indexable(this.name, this.comment, this.qualifiedName, this.isPrivate, 680 Indexable(this.name, this.comment, this.qualifiedName, this.isPrivate,
629 this.owner); 681 this.owner);
630 682
631 /// The type of this member to be used in index.txt. 683 /// The type of this member to be used in index.txt.
632 String get typeName => ''; 684 String get typeName => '';
633 685
634 /** 686 /**
635 * Creates a [Map] with this [Indexable]'s name and a preview comment. 687 * Creates a [Map] with this [Indexable]'s name and a preview comment.
636 */ 688 */
637 Map get previewMap { 689 Map get previewMap {
638 var finalMap = { 'name' : qualifiedName }; 690 var finalMap = { 'name' : qualifiedName };
639 if (comment != '') { 691 if (comment != '') {
640 var index = comment.indexOf('</p>'); 692 var index = comment.indexOf('</p>');
641 finalMap['preview'] = '${comment.substring(0, index)}</p>'; 693 finalMap['preview'] = '${comment.substring(0, index)}</p>';
642 } 694 }
643 return finalMap; 695 return finalMap;
644 } 696 }
645 } 697 }
646 698
647 /** 699 /**
648 * A class containing contents of a Dart library. 700 * A class containing contents of a Dart library.
649 */ 701 */
650 class Library extends Indexable { 702 class Library extends Indexable {
651 703
652 /// Top-level variables in the library. 704 /// Top-level variables in the library.
653 Map<String, Variable> variables; 705 Map<String, Variable> variables;
654 706
655 /// Top-level functions in the library. 707 /// Top-level functions in the library.
656 MethodGroup functions; 708 MethodGroup functions;
657 709
658 /// Classes defined within the library 710 /// Classes defined within the library
659 ClassGroup classes; 711 ClassGroup classes;
660 712
713 String packageName = '';
714
715 Map get previewMap => super.previewMap..['packageName'] = packageName;
716
661 Library(String name, String comment, this.variables, 717 Library(String name, String comment, this.variables,
662 this.functions, this.classes, bool isPrivate) : super(name, comment, 718 this.functions, this.classes, bool isPrivate) : super(name, comment,
663 name, isPrivate, "") {} 719 name, isPrivate, "") {}
664 720
665 /// Generates a map describing the [Library] object. 721 /// Generates a map describing the [Library] object.
666 Map toMap() => { 722 Map toMap() => {
667 'name': name, 723 'name': name,
668 'qualifiedName': qualifiedName, 724 'qualifiedName': qualifiedName,
669 'comment': comment, 725 'comment': comment,
670 'variables': recurseMap(variables), 726 'variables': recurseMap(variables),
671 'functions': functions.toMap(), 727 'functions': functions.toMap(),
672 'classes': classes.toMap() 728 'classes': classes.toMap(),
729 'packageName': packageName,
673 }; 730 };
674 731
675 String get typeName => 'library'; 732 String get typeName => 'library';
676 } 733 }
677 734
678 /** 735 /**
679 * A class containing contents of a Dart class. 736 * A class containing contents of a Dart class.
680 */ 737 */
681 class Class extends Indexable { 738 class Class extends Indexable {
682 739
683 /// List of the names of interfaces that this class implements. 740 /// List of the names of interfaces that this class implements.
684 List<Class> interfaces = []; 741 List<Class> interfaces = [];
(...skipping 17 matching lines...) Expand all
702 Map<String, Generic> generics; 759 Map<String, Generic> generics;
703 760
704 Class superclass; 761 Class superclass;
705 bool isAbstract; 762 bool isAbstract;
706 763
707 /// List of the meta annotations on the class. 764 /// List of the meta annotations on the class.
708 List<Annotation> annotations; 765 List<Annotation> annotations;
709 766
710 Class(String name, this.superclass, String comment, this.interfaces, 767 Class(String name, this.superclass, String comment, this.interfaces,
711 this.variables, this.methods, this.annotations, this.generics, 768 this.variables, this.methods, this.annotations, this.generics,
712 String qualifiedName, bool isPrivate, String owner, this.isAbstract) 769 String qualifiedName, bool isPrivate, String owner, this.isAbstract)
713 : super(name, comment, qualifiedName, isPrivate, owner) { 770 : super(name, comment, qualifiedName, isPrivate, owner) {
714 _mdnComment(this); 771 _mdnComment(this);
715 } 772 }
716 773
717 String get typeName => 'class'; 774 String get typeName => 'class';
718 775
719 /** 776 /**
720 * Returns a list of all the parent classes. 777 * Returns a list of all the parent classes.
721 */ 778 */
722 List<Class> parent() { 779 List<Class> parent() {
723 var parent = superclass == null ? [] : [superclass]; 780 var parent = superclass == null ? [] : [superclass];
724 parent.addAll(interfaces); 781 parent.addAll(interfaces);
725 return parent; 782 return parent;
726 } 783 }
727 784
728 /** 785 /**
(...skipping 16 matching lines...) Expand all
745 void addSubclass(Class subclass) { 802 void addSubclass(Class subclass) {
746 if (!_includePrivate && isPrivate) { 803 if (!_includePrivate && isPrivate) {
747 if (superclass != null) superclass.addSubclass(subclass); 804 if (superclass != null) superclass.addSubclass(subclass);
748 interfaces.forEach((interface) { 805 interfaces.forEach((interface) {
749 interface.addSubclass(subclass); 806 interface.addSubclass(subclass);
750 }); 807 });
751 } else { 808 } else {
752 subclasses.add(subclass.qualifiedName); 809 subclasses.add(subclass.qualifiedName);
753 } 810 }
754 } 811 }
755 812
756 /** 813 /**
757 * Check if this [Class] is an error or exception. 814 * Check if this [Class] is an error or exception.
758 */ 815 */
759 bool isError() { 816 bool isError() {
760 if (qualifiedName == 'dart.core.Error' || 817 if (qualifiedName == 'dart.core.Error' ||
761 qualifiedName == 'dart.core.Exception') 818 qualifiedName == 'dart.core.Exception')
762 return true; 819 return true;
763 for (var interface in interfaces) { 820 for (var interface in interfaces) {
764 if (interface.isError()) return true; 821 if (interface.isError()) return true;
765 } 822 }
766 if (superclass == null) return false; 823 if (superclass == null) return false;
767 return superclass.isError(); 824 return superclass.isError();
768 } 825 }
769 826
770 /** 827 /**
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
840 if (_includePrivate || !mirror.isPrivate) { 897 if (_includePrivate || !mirror.isPrivate) {
841 entityMap[mirror.qualifiedName] = new Typedef(mirror.simpleName, 898 entityMap[mirror.qualifiedName] = new Typedef(mirror.simpleName,
842 mirror.value.returnType.qualifiedName, _commentToHtml(mirror), 899 mirror.value.returnType.qualifiedName, _commentToHtml(mirror),
843 _generics(mirror), _parameters(mirror.value.parameters), 900 _generics(mirror), _parameters(mirror.value.parameters),
844 _annotations(mirror), mirror.qualifiedName, _isHidden(mirror), 901 _annotations(mirror), mirror.qualifiedName, _isHidden(mirror),
845 mirror.owner.qualifiedName); 902 mirror.owner.qualifiedName);
846 typedefs[mirror.simpleName] = entityMap[mirror.qualifiedName]; 903 typedefs[mirror.simpleName] = entityMap[mirror.qualifiedName];
847 } 904 }
848 } else { 905 } else {
849 var clazz = _class(mirror); 906 var clazz = _class(mirror);
850 907
851 // Adding inherited parent variables and methods. 908 // Adding inherited parent variables and methods.
852 clazz.parent().forEach((parent) { 909 clazz.parent().forEach((parent) {
853 if (_isVisible(clazz)) { 910 if (_isVisible(clazz)) {
854 parent.addSubclass(clazz); 911 parent.addSubclass(clazz);
855 } 912 }
856 }); 913 });
857 914
858 clazz.ensureComments(); 915 clazz.ensureComments();
859 916
860 if (clazz.isError()) { 917 if (clazz.isError()) {
861 errors[mirror.simpleName] = clazz; 918 errors[mirror.simpleName] = clazz;
862 } else if (mirror.isClass) { 919 } else if (mirror.isClass) {
863 classes[mirror.simpleName] = clazz; 920 classes[mirror.simpleName] = clazz;
864 } else { 921 } else {
865 throw new ArgumentError('${mirror.simpleName} - no class type match. '); 922 throw new ArgumentError('${mirror.simpleName} - no class type match. ');
866 } 923 }
867 } 924 }
868 } 925 }
869 926
870 /** 927 /**
871 * Checks if the given name is a key for any of the Class Maps. 928 * Checks if the given name is a key for any of the Class Maps.
872 */ 929 */
873 bool containsKey(String name) { 930 bool containsKey(String name) {
874 return classes.containsKey(name) || errors.containsKey(name); 931 return classes.containsKey(name) || errors.containsKey(name);
875 } 932 }
876 933
877 Map toMap() => { 934 Map toMap() => {
878 'class': classes.values.where(_isVisible) 935 'class': classes.values.where(_isVisible)
879 .map((e) => e.previewMap).toList(), 936 .map((e) => e.previewMap).toList(),
880 'typedef': recurseMap(typedefs), 937 'typedef': recurseMap(typedefs),
881 'error': errors.values.where(_isVisible) 938 'error': errors.values.where(_isVisible)
882 .map((e) => e.previewMap).toList() 939 .map((e) => e.previewMap).toList()
883 }; 940 };
884 } 941 }
885 942
886 class Typedef extends Indexable { 943 class Typedef extends Indexable {
887 String returnType; 944 String returnType;
888 945
889 Map<String, Parameter> parameters; 946 Map<String, Parameter> parameters;
890 947
891 /// Generic information about the typedef. 948 /// Generic information about the typedef.
892 Map<String, Generic> generics; 949 Map<String, Generic> generics;
893 950
894 /// List of the meta annotations on the typedef. 951 /// List of the meta annotations on the typedef.
895 List<Annotation> annotations; 952 List<Annotation> annotations;
896 953
897 Typedef(String name, this.returnType, String comment, this.generics, 954 Typedef(String name, this.returnType, String comment, this.generics,
898 this.parameters, this.annotations, 955 this.parameters, this.annotations,
899 String qualifiedName, bool isPrivate, String owner) 956 String qualifiedName, bool isPrivate, String owner)
900 : super(name, comment, qualifiedName, isPrivate, owner); 957 : super(name, comment, qualifiedName, isPrivate, owner);
901 958
902 Map toMap() => { 959 Map toMap() => {
903 'name': name, 960 'name': name,
904 'qualifiedName': qualifiedName, 961 'qualifiedName': qualifiedName,
905 'comment': comment, 962 'comment': comment,
906 'return': returnType, 963 'return': returnType,
907 'parameters': recurseMap(parameters), 964 'parameters': recurseMap(parameters),
908 'annotations': annotations.map((a) => a.toMap()).toList(), 965 'annotations': annotations.map((a) => a.toMap()).toList(),
909 'generics': recurseMap(generics) 966 'generics': recurseMap(generics)
910 }; 967 };
911 968
912 String get typeName => 'typedef'; 969 String get typeName => 'typedef';
913 } 970 }
914 971
915 /** 972 /**
916 * A class containing properties of a Dart variable. 973 * A class containing properties of a Dart variable.
917 */ 974 */
918 class Variable extends Indexable { 975 class Variable extends Indexable {
919 976
920 bool isFinal; 977 bool isFinal;
921 bool isStatic; 978 bool isStatic;
(...skipping 13 matching lines...) Expand all
935 Map toMap() => { 992 Map toMap() => {
936 'name': name, 993 'name': name,
937 'qualifiedName': qualifiedName, 994 'qualifiedName': qualifiedName,
938 'comment': comment, 995 'comment': comment,
939 'final': isFinal.toString(), 996 'final': isFinal.toString(),
940 'static': isStatic.toString(), 997 'static': isStatic.toString(),
941 'constant': isConst.toString(), 998 'constant': isConst.toString(),
942 'type': new List.filled(1, type.toMap()), 999 'type': new List.filled(1, type.toMap()),
943 'annotations': annotations.map((a) => a.toMap()).toList() 1000 'annotations': annotations.map((a) => a.toMap()).toList()
944 }; 1001 };
945 1002
946 String get typeName => 'property'; 1003 String get typeName => 'property';
947 } 1004 }
948 1005
949 /** 1006 /**
950 * A class containing properties of a Dart method. 1007 * A class containing properties of a Dart method.
951 */ 1008 */
952 class Method extends Indexable { 1009 class Method extends Indexable {
953 1010
954 /// Parameters for this method. 1011 /// Parameters for this method.
955 Map<String, Parameter> parameters; 1012 Map<String, Parameter> parameters;
956 1013
957 bool isStatic; 1014 bool isStatic;
958 bool isAbstract; 1015 bool isAbstract;
959 bool isConst; 1016 bool isConst;
960 bool isConstructor; 1017 bool isConstructor;
961 bool isGetter; 1018 bool isGetter;
962 bool isSetter; 1019 bool isSetter;
963 bool isOperator; 1020 bool isOperator;
964 Type returnType; 1021 Type returnType;
965 1022
966 /// Qualified name to state where the comment is inherited from. 1023 /// Qualified name to state where the comment is inherited from.
967 String commentInheritedFrom = ""; 1024 String commentInheritedFrom = "";
968 1025
969 /// List of the meta annotations on the method. 1026 /// List of the meta annotations on the method.
970 List<Annotation> annotations; 1027 List<Annotation> annotations;
971 1028
972 Method(String name, this.isStatic, this.isAbstract, this.isConst, 1029 Method(String name, this.isStatic, this.isAbstract, this.isConst,
973 this.returnType, String comment, this.parameters, this.annotations, 1030 this.returnType, String comment, this.parameters, this.annotations,
974 String qualifiedName, bool isPrivate, String owner, this.isConstructor, 1031 String qualifiedName, bool isPrivate, String owner, this.isConstructor,
975 this.isGetter, this.isSetter, this.isOperator) 1032 this.isGetter, this.isSetter, this.isOperator)
976 : super(name, comment, qualifiedName, isPrivate, owner) { 1033 : super(name, comment, qualifiedName, isPrivate, owner) {
977 _mdnComment(this); 1034 _mdnComment(this);
978 } 1035 }
979 1036
980 /** 1037 /**
981 * Makes sure that the method with an inherited equivalent have comments. 1038 * Makes sure that the method with an inherited equivalent have comments.
982 */ 1039 */
983 void ensureCommentFor(Method inheritedMethod) { 1040 void ensureCommentFor(Method inheritedMethod) {
984 if (comment.isNotEmpty) return; 1041 if (comment.isNotEmpty) return;
985 entityMap[inheritedMethod.owner].ensureComments(); 1042 entityMap[inheritedMethod.owner].ensureComments();
986 comment = inheritedMethod.comment; 1043 comment = inheritedMethod.comment;
987 commentInheritedFrom = inheritedMethod.commentInheritedFrom == '' ? 1044 commentInheritedFrom = inheritedMethod.commentInheritedFrom == '' ?
988 inheritedMethod.qualifiedName : inheritedMethod.commentInheritedFrom; 1045 inheritedMethod.qualifiedName : inheritedMethod.commentInheritedFrom;
989 } 1046 }
990 1047
991 /// Generates a map describing the [Method] object. 1048 /// Generates a map describing the [Method] object.
992 Map toMap() => { 1049 Map toMap() => {
993 'name': name, 1050 'name': name,
994 'qualifiedName': qualifiedName, 1051 'qualifiedName': qualifiedName,
995 'comment': comment, 1052 'comment': comment,
996 'commentFrom': commentInheritedFrom, 1053 'commentFrom': commentInheritedFrom,
997 'static': isStatic.toString(), 1054 'static': isStatic.toString(),
998 'abstract': isAbstract.toString(), 1055 'abstract': isAbstract.toString(),
999 'constant': isConst.toString(), 1056 'constant': isConst.toString(),
1000 'return': new List.filled(1, returnType.toMap()), 1057 'return': new List.filled(1, returnType.toMap()),
1001 'parameters': recurseMap(parameters), 1058 'parameters': recurseMap(parameters),
1002 'annotations': annotations.map((a) => a.toMap()).toList() 1059 'annotations': annotations.map((a) => a.toMap()).toList()
1003 }; 1060 };
1004 1061
1005 String get typeName => isConstructor ? 'constructor' : 1062 String get typeName => isConstructor ? 'constructor' :
1006 isGetter ? 'getter' : isSetter ? 'setter' : 1063 isGetter ? 'getter' : isSetter ? 'setter' :
1007 isOperator ? 'operator' : 'method'; 1064 isOperator ? 'operator' : 'method';
1008 } 1065 }
1009 1066
1010 /** 1067 /**
1011 * A container to categorize methods into the following groups: setters, 1068 * A container to categorize methods into the following groups: setters,
1012 * getters, constructors, operators, regular methods. 1069 * getters, constructors, operators, regular methods.
1013 */ 1070 */
1014 class MethodGroup { 1071 class MethodGroup {
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
1173 String qualifiedName; 1230 String qualifiedName;
1174 List<String> parameters; 1231 List<String> parameters;
1175 1232
1176 Annotation(this.qualifiedName, this.parameters); 1233 Annotation(this.qualifiedName, this.parameters);
1177 1234
1178 Map toMap() => { 1235 Map toMap() => {
1179 'name': qualifiedName, 1236 'name': qualifiedName,
1180 'parameters': parameters 1237 'parameters': parameters
1181 }; 1238 };
1182 } 1239 }
OLDNEW
« no previous file with comments | « pkg/docgen/bin/upload_docgen.py ('k') | pkg/docgen/pubspec.yaml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698