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

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

Issue 22284003: pkg: analysis aided cleanup (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: nits Created 7 years, 4 months 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 | « no previous file | 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 *
(...skipping 12 matching lines...) Expand all
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 25
26 import 'dart2yaml.dart'; 26 import 'dart2yaml.dart';
27 import 'src/io.dart'; 27 import 'src/io.dart';
28 import '../../../sdk/lib/_internal/compiler/compiler.dart' as api; 28 import '../../../sdk/lib/_internal/compiler/compiler.dart' as api;
29 import '../../../sdk/lib/_internal/compiler/implementation/filenames.dart'; 29 import '../../../sdk/lib/_internal/compiler/implementation/filenames.dart';
30 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirro r.dart' 30 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirro r.dart'
31 as dart2js; 31 as dart2js;
32 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors.dart' ; 32 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors.dart' ;
33 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors_util. dart';
34 import '../../../sdk/lib/_internal/compiler/implementation/source_file_provider. dart'; 33 import '../../../sdk/lib/_internal/compiler/implementation/source_file_provider. dart';
35 import '../../../sdk/lib/_internal/libraries.dart'; 34 import '../../../sdk/lib/_internal/libraries.dart';
36 35
37 var logger = new Logger('Docgen'); 36 var logger = new Logger('Docgen');
38 37
39 const String USAGE = 'Usage: dart docgen.dart [OPTIONS] [fooDir/barFile]'; 38 const String USAGE = 'Usage: dart docgen.dart [OPTIONS] [fooDir/barFile]';
40 39
41 /// Current library being documented to be used for comment links. 40 /// Current library being documented to be used for comment links.
42 LibraryMirror _currentLibrary; 41 LibraryMirror _currentLibrary;
43 42
44 /// Current class being documented to be used for comment links. 43 /// Current class being documented to be used for comment links.
45 ClassMirror _currentClass; 44 ClassMirror _currentClass;
46 45
47 /// Current member being documented to be used for comment links. 46 /// Current member being documented to be used for comment links.
48 MemberMirror _currentMember; 47 MemberMirror _currentMember;
49 48
50 /// Support for [:foo:]-style code comments to the markdown parser. 49 /// Support for [:foo:]-style code comments to the markdown parser.
51 List<markdown.InlineSyntax> markdownSyntaxes = 50 List<markdown.InlineSyntax> markdownSyntaxes =
52 [new markdown.CodeSyntax(r'\[:\s?((?:.|\n)*?)\s?:\]')]; 51 [new markdown.CodeSyntax(r'\[:\s?((?:.|\n)*?)\s?:\]')];
53 52
54 /// Resolves reference links in doc comments. 53 /// Resolves reference links in doc comments.
55 markdown.Resolver linkResolver; 54 markdown.Resolver linkResolver;
56 55
57 /// Index of all indexable items. This also ensures that no class is 56 /// Index of all indexable items. This also ensures that no class is
58 /// created more than once. 57 /// created more than once.
59 Map<String, Indexable> entityMap = new Map<String, Indexable>(); 58 Map<String, Indexable> entityMap = new Map<String, Indexable>();
60 59
61 /// This is set from the command line arguments flag --include-private 60 /// This is set from the command line arguments flag --include-private
62 bool _includePrivate = false; 61 bool _includePrivate = false;
63 62
64 /** 63 /**
65 * Docgen constructor initializes the link resolver for markdown parsing. 64 * Docgen constructor initializes the link resolver for markdown parsing.
66 * Also initializes the command line arguments. 65 * Also initializes the command line arguments.
67 * 66 *
68 * [packageRoot] is the packages directory of the directory being analyzed. 67 * [packageRoot] is the packages directory of the directory being analyzed.
69 * If [includeSdk] is `true`, then any SDK libraries explicitly imported will 68 * If [includeSdk] is `true`, then any SDK libraries explicitly imported will
70 * also be documented. 69 * also be documented.
71 * If [parseSdk] is `true`, then all Dart SDK libraries will be documented. 70 * If [parseSdk] is `true`, then all Dart SDK libraries will be documented.
72 * This option is useful when only the SDK libraries are needed. 71 * This option is useful when only the SDK libraries are needed.
73 * 72 *
74 * Returns `true` if docgen sucessfuly completes. 73 * Returns `true` if docgen sucessfuly completes.
75 */ 74 */
76 Future<bool> docgen(List<String> files, {String packageRoot, 75 Future<bool> docgen(List<String> files, {String packageRoot,
77 bool outputToYaml: true, bool includePrivate: false, bool includeSdk: false, 76 bool outputToYaml: true, bool includePrivate: false, bool includeSdk: false,
78 bool parseSdk: false, bool append: false}) { 77 bool parseSdk: false, bool append: false}) {
79 _includePrivate = includePrivate; 78 _includePrivate = includePrivate;
80 if (!append) { 79 if (!append) {
81 var dir = new Directory('docs'); 80 var dir = new Directory('docs');
82 if (dir.existsSync()) dir.deleteSync(recursive: true); 81 if (dir.existsSync()) dir.deleteSync(recursive: true);
83 } 82 }
84 83
85 if (packageRoot == null && !parseSdk) { 84 if (packageRoot == null && !parseSdk) {
86 var type = FileSystemEntity.typeSync(files.first); 85 var type = FileSystemEntity.typeSync(files.first);
87 if (type == FileSystemEntityType.DIRECTORY) { 86 if (type == FileSystemEntityType.DIRECTORY) {
88 packageRoot = _findPackageRoot(files.first); 87 packageRoot = _findPackageRoot(files.first);
89 } else if (type == FileSystemEntityType.FILE) { 88 } else if (type == FileSystemEntityType.FILE) {
90 logger.warning('WARNING: No package root defined. If Docgen fails, try ' 89 logger.warning('WARNING: No package root defined. If Docgen fails, try '
91 'again by setting the --package-root option.'); 90 'again by setting the --package-root option.');
92 } 91 }
93 } 92 }
94 logger.info('Package Root: ${packageRoot}'); 93 logger.info('Package Root: ${packageRoot}');
(...skipping 26 matching lines...) Expand all
121 } 120 }
122 return libraries; 121 return libraries;
123 } 122 }
124 123
125 List<String> _listDartFromDir(String args) { 124 List<String> _listDartFromDir(String args) {
126 var files = listDir(args, recursive: true); 125 var files = listDir(args, recursive: true);
127 // To avoid anaylzing package files twice, only files with paths not 126 // To avoid anaylzing package files twice, only files with paths not
128 // containing '/packages' will be added. The only exception is if the file to 127 // containing '/packages' will be added. The only exception is if the file to
129 // analyze already has a '/package' in its path. 128 // analyze already has a '/package' in its path.
130 return files.where((f) => f.endsWith('.dart') && 129 return files.where((f) => f.endsWith('.dart') &&
131 (!f.contains('${path.separator}packages') || 130 (!f.contains('${path.separator}packages') ||
132 args.contains('${path.separator}packages'))).toList() 131 args.contains('${path.separator}packages'))).toList()
133 ..forEach((lib) => logger.info('Added to libraries: $lib')); 132 ..forEach((lib) => logger.info('Added to libraries: $lib'));
134 } 133 }
135 134
136 String _findPackageRoot(String directory) { 135 String _findPackageRoot(String directory) {
137 var files = listDir(directory, recursive: true); 136 var files = listDir(directory, recursive: true);
138 // Return '' means that there was no pubspec.yaml and therefor no packageRoot. 137 // Return '' means that there was no pubspec.yaml and therefor no packageRoot.
139 String packageRoot = files.firstWhere((f) => 138 String packageRoot = files.firstWhere((f) =>
140 f.endsWith('${path.separator}pubspec.yaml'), orElse: () => ''); 139 f.endsWith('${path.separator}pubspec.yaml'), orElse: () => '');
141 if (packageRoot != '') { 140 if (packageRoot != '') {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 * for static inspection of the source code. 174 * for static inspection of the source code.
176 */ 175 */
177 Future<MirrorSystem> _analyzeLibraries(List<String> libraries, 176 Future<MirrorSystem> _analyzeLibraries(List<String> libraries,
178 String libraryRoot, {String packageRoot}) { 177 String libraryRoot, {String packageRoot}) {
179 SourceFileProvider provider = new SourceFileProvider(); 178 SourceFileProvider provider = new SourceFileProvider();
180 api.DiagnosticHandler diagnosticHandler = 179 api.DiagnosticHandler diagnosticHandler =
181 new FormattingDiagnosticHandler(provider).diagnosticHandler; 180 new FormattingDiagnosticHandler(provider).diagnosticHandler;
182 Uri libraryUri = new Uri(scheme: 'file', path: appendSlash(libraryRoot)); 181 Uri libraryUri = new Uri(scheme: 'file', path: appendSlash(libraryRoot));
183 Uri packageUri = null; 182 Uri packageUri = null;
184 if (packageRoot != null) { 183 if (packageRoot != null) {
185 packageUri = new Uri(scheme: 'file', path: appendSlash(packageRoot)); 184 packageUri = new Uri(scheme: 'file', path: appendSlash(packageRoot));
186 } 185 }
187 List<Uri> librariesUri = <Uri>[]; 186 List<Uri> librariesUri = <Uri>[];
188 libraries.forEach((library) { 187 libraries.forEach((library) {
189 librariesUri.add(currentDirectory.resolve(library)); 188 librariesUri.add(currentDirectory.resolve(library));
190 }); 189 });
191 return dart2js.analyze(librariesUri, libraryUri, packageUri, 190 return dart2js.analyze(librariesUri, libraryUri, packageUri,
192 provider.readStringFromUri, diagnosticHandler, 191 provider.readStringFromUri, diagnosticHandler,
193 ['--preserve-comments', '--categories=Client,Server']) 192 ['--preserve-comments', '--categories=Client,Server'])
194 ..catchError((error) { 193 ..catchError((error) {
195 logger.severe('Error: Failed to create mirror system. '); 194 logger.severe('Error: Failed to create mirror system. ');
(...skipping 11 matching lines...) Expand all
207 void _documentLibraries(List<LibraryMirror> libs, {bool includeSdk: false, 206 void _documentLibraries(List<LibraryMirror> libs, {bool includeSdk: false,
208 bool outputToYaml: true, bool append: false, bool parseSdk: false}) { 207 bool outputToYaml: true, bool append: false, bool parseSdk: false}) {
209 libs.forEach((lib) { 208 libs.forEach((lib) {
210 // Files belonging to the SDK have a uri that begins with 'dart:'. 209 // Files belonging to the SDK have a uri that begins with 'dart:'.
211 if (includeSdk || !lib.uri.toString().startsWith('dart:')) { 210 if (includeSdk || !lib.uri.toString().startsWith('dart:')) {
212 var library = generateLibrary(lib); 211 var library = generateLibrary(lib);
213 entityMap[library.qualifiedName] = library; 212 entityMap[library.qualifiedName] = library;
214 } 213 }
215 }); 214 });
216 // After everything is created, do a pass through all classes to make sure no 215 // After everything is created, do a pass through all classes to make sure no
217 // intermediate classes created by mixins are included. 216 // intermediate classes created by mixins are included.
218 entityMap.values.where((e) => e is Class).forEach((c) => c.makeValid()); 217 entityMap.values.where((e) => e is Class).forEach((c) => c.makeValid());
219 // Everything is a subclass of Object, therefore empty the list to avoid a 218 // Everything is a subclass of Object, therefore empty the list to avoid a
220 // giant list of subclasses to be printed out. 219 // giant list of subclasses to be printed out.
221 if (parseSdk) entityMap['dart.core.Object'].subclasses.clear(); 220 if (parseSdk) entityMap['dart.core.Object'].subclasses.clear();
222 221
223 var filteredEntities = entityMap.values.where(_isVisible); 222 var filteredEntities = entityMap.values.where(_isVisible);
224 // Output libraries and classes to file after all information is generated. 223 // Output libraries and classes to file after all information is generated.
225 filteredEntities.where((e) => e is Class || e is Library).forEach((output) { 224 filteredEntities.where((e) => e is Class || e is Library).forEach((output) {
226 _writeIndexableToFile(output, outputToYaml); 225 _writeIndexableToFile(output, outputToYaml);
227 }); 226 });
228 // Outputs a text file with a list of libraries available after creating all 227 // Outputs a text file with a list of libraries available after creating all
229 // the libraries. This will help the viewer know what libraries are available 228 // the libraries. This will help the viewer know what libraries are available
230 // to read in. 229 // to read in.
231 _writeToFile(filteredEntities.where((e) => e is Library) 230 _writeToFile(filteredEntities.where((e) => e is Library)
232 .map((e) => e.qualifiedName).join('\n'), 'library_list.txt', 231 .map((e) => e.qualifiedName).join('\n'), 'library_list.txt',
233 append: append); 232 append: append);
234 // Outputs all the qualified names documented. This will help generate search 233 // Outputs all the qualified names documented. This will help generate search
235 // results. 234 // results.
236 _writeToFile(filteredEntities.map((e) => e.qualifiedName).join('\n'), 235 _writeToFile(filteredEntities.map((e) => e.qualifiedName).join('\n'),
237 'index.txt', append: append); 236 'index.txt', append: append);
238 } 237 }
239 238
240 Library generateLibrary(dart2js.Dart2JsLibraryMirror library) { 239 Library generateLibrary(dart2js.Dart2JsLibraryMirror library) {
241 _currentLibrary = library; 240 _currentLibrary = library;
242 var result = new Library(library.qualifiedName, _commentToHtml(library), 241 var result = new Library(library.qualifiedName, _commentToHtml(library),
243 _variables(library.variables), 242 _variables(library.variables),
244 _methods(library.functions), 243 _methods(library.functions),
245 _classes(library.classes), _isHidden(library)); 244 _classes(library.classes), _isHidden(library));
246 logger.fine('Generated library for ${result.name}'); 245 logger.fine('Generated library for ${result.name}');
247 return result; 246 return result;
248 } 247 }
249 248
250 void _writeIndexableToFile(Indexable result, bool outputToYaml) { 249 void _writeIndexableToFile(Indexable result, bool outputToYaml) {
251 if (outputToYaml) { 250 if (outputToYaml) {
252 _writeToFile(getYamlString(result.toMap()), '${result.qualifiedName}.yaml'); 251 _writeToFile(getYamlString(result.toMap()), '${result.qualifiedName}.yaml');
253 } else { 252 } else {
254 _writeToFile(stringify(result.toMap()), '${result.qualifiedName}.json'); 253 _writeToFile(stringify(result.toMap()), '${result.qualifiedName}.json');
255 } 254 }
256 } 255 }
257 256
258 /** 257 /**
259 * Returns true if a library name starts with an underscore, and false 258 * Returns true if a library name starts with an underscore, and false
260 * otherwise. 259 * otherwise.
261 * 260 *
262 * An example that starts with _ is _js_helper. 261 * An example that starts with _ is _js_helper.
263 * An example that contains ._ is dart._collection.dev 262 * An example that contains ._ is dart._collection.dev
264 */ 263 */
265 // This is because LibraryMirror.isPrivate returns `false` all the time. 264 // This is because LibraryMirror.isPrivate returns `false` all the time.
266 bool _isLibraryPrivate(LibraryMirror mirror) { 265 bool _isLibraryPrivate(LibraryMirror mirror) {
267 if (mirror.simpleName.startsWith('_') || mirror.simpleName.contains('._')) { 266 if (mirror.simpleName.startsWith('_') || mirror.simpleName.contains('._')) {
268 return true; 267 return true;
269 } 268 }
270 return false; 269 return false;
271 } 270 }
272 271
273 /** 272 /**
274 * A declaration is private if itself is private, or the owner is private. 273 * A declaration is private if itself is private, or the owner is private.
275 */ 274 */
276 // Issue(12202) - A declaration is public even if it's owner is private. 275 // Issue(12202) - A declaration is public even if it's owner is private.
277 bool _isHidden(DeclarationMirror mirror) { 276 bool _isHidden(DeclarationMirror mirror) {
278 if (mirror is LibraryMirror) { 277 if (mirror is LibraryMirror) {
279 return _isLibraryPrivate(mirror); 278 return _isLibraryPrivate(mirror);
280 } else if (mirror.owner is LibraryMirror) { 279 } else if (mirror.owner is LibraryMirror) {
281 return (mirror.isPrivate || _isLibraryPrivate(mirror.owner)); 280 return (mirror.isPrivate || _isLibraryPrivate(mirror.owner));
282 } else { 281 } else {
283 return (mirror.isPrivate || _isHidden(mirror.owner)); 282 return (mirror.isPrivate || _isHidden(mirror.owner));
284 } 283 }
285 } 284 }
286 285
287 bool _isVisible(Indexable item) { 286 bool _isVisible(Indexable item) {
288 return _includePrivate || !item.isPrivate; 287 return _includePrivate || !item.isPrivate;
289 } 288 }
290 289
291 /** 290 /**
292 * Returns a list of meta annotations assocated with a mirror. 291 * Returns a list of meta annotations assocated with a mirror.
(...skipping 25 matching lines...) Expand all
318 CommentInstanceMirror comment = metadata; 317 CommentInstanceMirror comment = metadata;
319 if (comment.isDocComment) { 318 if (comment.isDocComment) {
320 if (commentText == null) { 319 if (commentText == null) {
321 commentText = comment.trimmedText; 320 commentText = comment.trimmedText;
322 } else { 321 } else {
323 commentText = '$commentText ${comment.trimmedText}'; 322 commentText = '$commentText ${comment.trimmedText}';
324 } 323 }
325 } 324 }
326 } 325 }
327 }); 326 });
328 327
329 commentText = commentText == null ? '' : 328 commentText = commentText == null ? '' :
330 markdown.markdownToHtml(commentText.trim(), linkResolver: linkResolver, 329 markdown.markdownToHtml(commentText.trim(), linkResolver: linkResolver,
331 inlineSyntaxes: markdownSyntaxes); 330 inlineSyntaxes: markdownSyntaxes);
332 return commentText; 331 return commentText;
333 } 332 }
334 333
335 /** 334 /**
336 * Converts all [foo] references in comments to <a>libraryName.foo</a>. 335 * Converts all [foo] references in comments to <a>libraryName.foo</a>.
337 */ 336 */
338 markdown.Node fixReference(String name, LibraryMirror currentLibrary, 337 markdown.Node fixReference(String name, LibraryMirror currentLibrary,
339 ClassMirror currentClass, MemberMirror currentMember) { 338 ClassMirror currentClass, MemberMirror currentMember) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
380 * Returns a map of [Method] objects constructed from [mirrorMap]. 379 * Returns a map of [Method] objects constructed from [mirrorMap].
381 */ 380 */
382 MethodGroup _methods(Map<String, MethodMirror> mirrorMap) { 381 MethodGroup _methods(Map<String, MethodMirror> mirrorMap) {
383 var group = new MethodGroup(); 382 var group = new MethodGroup();
384 mirrorMap.forEach((String mirrorName, MethodMirror mirror) { 383 mirrorMap.forEach((String mirrorName, MethodMirror mirror) {
385 if (_includePrivate || !_isHidden(mirror)) { 384 if (_includePrivate || !_isHidden(mirror)) {
386 group.addMethod(mirror); 385 group.addMethod(mirror);
387 } 386 }
388 }); 387 });
389 return group; 388 return group;
390 } 389 }
391 390
392 /** 391 /**
393 * Returns the [Class] for the given [mirror] has already been created, and if 392 * Returns the [Class] for the given [mirror] has already been created, and if
394 * it does not exist, creates it. 393 * it does not exist, creates it.
395 */ 394 */
396 Class _class(ClassMirror mirror) { 395 Class _class(ClassMirror mirror) {
397 var clazz = entityMap[mirror.qualifiedName]; 396 var clazz = entityMap[mirror.qualifiedName];
398 if (clazz == null) { 397 if (clazz == null) {
399 var superclass = mirror.superclass != null ? 398 var superclass = mirror.superclass != null ?
400 _class(mirror.superclass) : null; 399 _class(mirror.superclass) : null;
401 var interfaces = 400 var interfaces =
402 mirror.superinterfaces.map((interface) => _class(interface)); 401 mirror.superinterfaces.map((interface) => _class(interface));
403 clazz = new Class(mirror.simpleName, superclass, _commentToHtml(mirror), 402 clazz = new Class(mirror.simpleName, superclass, _commentToHtml(mirror),
404 interfaces.toList(), _variables(mirror.variables), 403 interfaces.toList(), _variables(mirror.variables),
405 _methods(mirror.methods), _annotations(mirror), _generics(mirror), 404 _methods(mirror.methods), _annotations(mirror), _generics(mirror),
406 mirror.qualifiedName, _isHidden(mirror), mirror.owner.qualifiedName); 405 mirror.qualifiedName, _isHidden(mirror), mirror.owner.qualifiedName);
407 entityMap[mirror.qualifiedName] = clazz; 406 entityMap[mirror.qualifiedName] = clazz;
408 } 407 }
409 return clazz; 408 return clazz;
410 } 409 }
411 410
412 /** 411 /**
413 * Returns a map of [Class] objects constructed from [mirrorMap]. 412 * Returns a map of [Class] objects constructed from [mirrorMap].
414 */ 413 */
415 ClassGroup _classes(Map<String, ClassMirror> mirrorMap) { 414 ClassGroup _classes(Map<String, ClassMirror> mirrorMap) {
416 var group = new ClassGroup(); 415 var group = new ClassGroup();
417 mirrorMap.forEach((String mirrorName, ClassMirror mirror) { 416 mirrorMap.forEach((String mirrorName, ClassMirror mirror) {
418 group.addClass(mirror); 417 group.addClass(mirror);
419 }); 418 });
420 return group; 419 return group;
421 } 420 }
422 421
423 /** 422 /**
424 * Returns a map of [Parameter] objects constructed from [mirrorList]. 423 * Returns a map of [Parameter] objects constructed from [mirrorList].
425 */ 424 */
426 Map<String, Parameter> _parameters(List<ParameterMirror> mirrorList) { 425 Map<String, Parameter> _parameters(List<ParameterMirror> mirrorList) {
427 var data = {}; 426 var data = {};
428 mirrorList.forEach((ParameterMirror mirror) { 427 mirrorList.forEach((ParameterMirror mirror) {
429 _currentMember = mirror; 428 _currentMember = mirror;
430 data[mirror.simpleName] = new Parameter(mirror.simpleName, 429 data[mirror.simpleName] = new Parameter(mirror.simpleName,
431 mirror.isOptional, mirror.isNamed, mirror.hasDefaultValue, 430 mirror.isOptional, mirror.isNamed, mirror.hasDefaultValue,
432 _type(mirror.type), mirror.defaultValue, 431 _type(mirror.type), mirror.defaultValue,
433 _annotations(mirror)); 432 _annotations(mirror));
434 }); 433 });
435 return data; 434 return data;
436 } 435 }
437 436
438 /** 437 /**
439 * Returns a map of [Generic] objects constructed from the class mirror. 438 * Returns a map of [Generic] objects constructed from the class mirror.
440 */ 439 */
441 Map<String, Generic> _generics(ClassMirror mirror) { 440 Map<String, Generic> _generics(ClassMirror mirror) {
442 return new Map.fromIterable(mirror.typeVariables, 441 return new Map.fromIterable(mirror.typeVariables,
443 key: (e) => e.toString(), 442 key: (e) => e.toString(),
444 value: (e) => new Generic(e.toString(), e.upperBound.qualifiedName)); 443 value: (e) => new Generic(e.toString(), e.upperBound.qualifiedName));
445 } 444 }
446 445
447 /** 446 /**
448 * Returns a single [Type] object constructed from the Method.returnType 447 * Returns a single [Type] object constructed from the Method.returnType
449 * Type mirror. 448 * Type mirror.
450 */ 449 */
451 Type _type(TypeMirror mirror) { 450 Type _type(TypeMirror mirror) {
452 return new Type(mirror.qualifiedName, _typeGenerics(mirror)); 451 return new Type(mirror.qualifiedName, _typeGenerics(mirror));
453 } 452 }
454 453
455 /** 454 /**
456 * Returns a list of [Type] objects constructed from TypeMirrors. 455 * Returns a list of [Type] objects constructed from TypeMirrors.
457 */ 456 */
458 List<Type> _typeGenerics(TypeMirror mirror) { 457 List<Type> _typeGenerics(TypeMirror mirror) {
459 if (mirror is ClassMirror && !mirror.isTypedef) { 458 if (mirror is ClassMirror && !mirror.isTypedef) {
460 var innerList = []; 459 var innerList = [];
461 mirror.typeArguments.forEach((e) { 460 mirror.typeArguments.forEach((e) {
462 innerList.add(new Type(e.qualifiedName, _typeGenerics(e))); 461 innerList.add(new Type(e.qualifiedName, _typeGenerics(e)));
463 }); 462 });
464 return innerList; 463 return innerList;
465 } 464 }
466 return []; 465 return [];
(...skipping 23 matching lines...) Expand all
490 if (value is Map) { 489 if (value is Map) {
491 outputMap[key] = recurseMap(value); 490 outputMap[key] = recurseMap(value);
492 } else { 491 } else {
493 outputMap[key] = value.toMap(); 492 outputMap[key] = value.toMap();
494 } 493 }
495 }); 494 });
496 return outputMap; 495 return outputMap;
497 } 496 }
498 497
499 bool isError(String qualifiedName) { 498 bool isError(String qualifiedName) {
500 return qualifiedName.toLowerCase().contains('error') || 499 return qualifiedName.toLowerCase().contains('error') ||
501 qualifiedName.toLowerCase().contains('exception'); 500 qualifiedName.toLowerCase().contains('exception');
502 } 501 }
503 502
504 /** 503 /**
505 * A class representing all programming constructs, like library or class. 504 * A class representing all programming constructs, like library or class.
506 */ 505 */
507 class Indexable { 506 class Indexable {
508 String name; 507 String name;
509 String qualifiedName; 508 String qualifiedName;
510 bool isPrivate; 509 bool isPrivate;
511 510
512 /// Documentation comment with converted markdown. 511 /// Documentation comment with converted markdown.
513 String comment; 512 String comment;
514 513
515 /// Qualified Name of the owner of this Indexable Item. 514 /// Qualified Name of the owner of this Indexable Item.
516 /// For Library, owner will be ""; 515 /// For Library, owner will be "";
517 String owner; 516 String owner;
518 517
519 Indexable(this.name, this.comment, this.qualifiedName, this.isPrivate, 518 Indexable(this.name, this.comment, this.qualifiedName, this.isPrivate,
520 this.owner); 519 this.owner);
521 } 520 }
522 521
523 /** 522 /**
524 * A class containing contents of a Dart library. 523 * A class containing contents of a Dart library.
525 */ 524 */
526 class Library extends Indexable { 525 class Library extends Indexable {
527 526
528 /// Top-level variables in the library. 527 /// Top-level variables in the library.
529 Map<String, Variable> variables; 528 Map<String, Variable> variables;
530 529
531 /// Top-level functions in the library. 530 /// Top-level functions in the library.
532 MethodGroup functions; 531 MethodGroup functions;
533 532
534 /// Classes defined within the library 533 /// Classes defined within the library
535 ClassGroup classes; 534 ClassGroup classes;
536 535
537 Library(String name, String comment, this.variables, 536 Library(String name, String comment, this.variables,
538 this.functions, this.classes, bool isPrivate) : super(name, comment, 537 this.functions, this.classes, bool isPrivate) : super(name, comment,
539 name, isPrivate, "") {} 538 name, isPrivate, "") {}
540 539
541 /// Generates a map describing the [Library] object. 540 /// Generates a map describing the [Library] object.
542 Map toMap() => { 541 Map toMap() => {
543 'name': name, 542 'name': name,
544 'qualifiedname': qualifiedName, 543 'qualifiedname': qualifiedName,
545 'comment': comment, 544 'comment': comment,
546 'variables': recurseMap(variables), 545 'variables': recurseMap(variables),
547 'functions': functions.toMap(), 546 'functions': functions.toMap(),
548 'classes': classes.toMap() 547 'classes': classes.toMap()
549 }; 548 };
550 } 549 }
551 550
552 /** 551 /**
553 * A class containing contents of a Dart class. 552 * A class containing contents of a Dart class.
554 */ 553 */
555 class Class extends Indexable { 554 class Class extends Indexable {
556 555
557 /// List of the names of interfaces that this class implements. 556 /// List of the names of interfaces that this class implements.
558 List<Class> interfaces = []; 557 List<Class> interfaces = [];
559 558
560 /// Names of classes that extends or implements this class. 559 /// Names of classes that extends or implements this class.
561 Set<String> subclasses = new Set<String>(); 560 Set<String> subclasses = new Set<String>();
562 561
563 /// Top-level variables in the class. 562 /// Top-level variables in the class.
564 Map<String, Variable> variables; 563 Map<String, Variable> variables;
565 564
566 /// Inherited variables in the class. 565 /// Inherited variables in the class.
567 Map<String, Variable> inheritedVariables = {}; 566 Map<String, Variable> inheritedVariables = {};
568 567
569 /// Methods in the class. 568 /// Methods in the class.
570 MethodGroup methods; 569 MethodGroup methods;
571 570
572 /// Inherited methods in the class. 571 /// Inherited methods in the class.
573 MethodGroup inheritedMethods = new MethodGroup(); 572 MethodGroup inheritedMethods = new MethodGroup();
574 573
575 /// Generic infomation about the class. 574 /// Generic infomation about the class.
576 Map<String, Generic> generics; 575 Map<String, Generic> generics;
577 576
578 Class superclass; 577 Class superclass;
579 578
580 /// List of the meta annotations on the class. 579 /// List of the meta annotations on the class.
581 List<String> annotations; 580 List<String> annotations;
582 581
583 Class(String name, this.superclass, String comment, this.interfaces, 582 Class(String name, this.superclass, String comment, this.interfaces,
584 this.variables, this.methods, this.annotations, this.generics, 583 this.variables, this.methods, this.annotations, this.generics,
585 String qualifiedName, bool isPrivate, String owner) : super(name, comment, 584 String qualifiedName, bool isPrivate, String owner) : super(name, comment,
586 qualifiedName, isPrivate, owner) {} 585 qualifiedName, isPrivate, owner) {}
587 586
588 /** 587 /**
589 * Returns a list of all the parent classes. 588 * Returns a list of all the parent classes.
590 */ 589 */
591 List<Class> parent() { 590 List<Class> parent() {
592 var parent = superclass == null ? [] : [superclass]; 591 var parent = superclass == null ? [] : [superclass];
593 parent.addAll(interfaces); 592 parent.addAll(interfaces);
594 return parent; 593 return parent;
595 } 594 }
596 595
597 /** 596 /**
598 * Add all inherited variables and methods from the provided superclass. 597 * Add all inherited variables and methods from the provided superclass.
599 * If [_includePrivate] is true, it also adds the variables and methods from 598 * If [_includePrivate] is true, it also adds the variables and methods from
600 * the superclass. 599 * the superclass.
601 */ 600 */
602 void addInherited(Class superclass) { 601 void addInherited(Class superclass) {
603 inheritedVariables.addAll(superclass.inheritedVariables); 602 inheritedVariables.addAll(superclass.inheritedVariables);
604 if (_isVisible(superclass)) { 603 if (_isVisible(superclass)) {
605 inheritedVariables.addAll(superclass.variables); 604 inheritedVariables.addAll(superclass.variables);
606 } 605 }
607 inheritedMethods.addInherited(superclass); 606 inheritedMethods.addInherited(superclass);
608 } 607 }
609 608
610 /** 609 /**
611 * Add the subclass to the class. 610 * Add the subclass to the class.
612 * 611 *
613 * If [this] is private, it will add the subclass to the list of subclasses in 612 * If [this] is private, it will add the subclass to the list of subclasses in
614 * the superclasses. 613 * the superclasses.
615 */ 614 */
616 void addSubclass(Class subclass) { 615 void addSubclass(Class subclass) {
617 if (!_includePrivate && isPrivate) { 616 if (!_includePrivate && isPrivate) {
618 if (superclass != null) superclass.addSubclass(subclass); 617 if (superclass != null) superclass.addSubclass(subclass);
619 interfaces.forEach((interface) { 618 interfaces.forEach((interface) {
620 interface.addSubclass(subclass); 619 interface.addSubclass(subclass);
621 }); 620 });
622 } else { 621 } else {
623 subclasses.add(subclass.qualifiedName); 622 subclasses.add(subclass.qualifiedName);
624 } 623 }
625 } 624 }
626 625
627 /** 626 /**
628 * Check that the class exists in the owner library. 627 * Check that the class exists in the owner library.
629 * 628 *
630 * If it does not exist in the owner library, it is a mixin applciation and 629 * If it does not exist in the owner library, it is a mixin applciation and
631 * should be removed. 630 * should be removed.
632 */ 631 */
633 void makeValid() { 632 void makeValid() {
634 var library = entityMap[owner]; 633 var library = entityMap[owner];
635 if (library != null && !library.classes.containsKey(name)) { 634 if (library != null && !library.classes.containsKey(name)) {
636 this.isPrivate = true; 635 this.isPrivate = true;
637 // Since we are now making the mixin a private class, make all elements 636 // Since we are now making the mixin a private class, make all elements
638 // with the mixin as an owner private too. 637 // with the mixin as an owner private too.
639 entityMap.values.where((e) => e.owner == qualifiedName) 638 entityMap.values.where((e) => e.owner == qualifiedName)
640 .forEach((element) => element.isPrivate = true); 639 .forEach((element) => element.isPrivate = true);
641 // Move the subclass up to the next public superclass 640 // Move the subclass up to the next public superclass
642 subclasses.forEach((subclass) => addSubclass(entityMap[subclass])); 641 subclasses.forEach((subclass) => addSubclass(entityMap[subclass]));
643 } 642 }
644 } 643 }
645 644
646 /** 645 /**
647 * Makes sure that all methods with inherited equivalents have comments. 646 * Makes sure that all methods with inherited equivalents have comments.
648 */ 647 */
649 void ensureComments() { 648 void ensureComments() {
650 inheritedMethods.forEach((qualifiedName, inheritedMethod) { 649 inheritedMethods.forEach((qualifiedName, inheritedMethod) {
651 var method = methods[qualifiedName]; 650 var method = methods[qualifiedName];
652 if (method != null) method.ensureCommentFor(inheritedMethod); 651 if (method != null) method.ensureCommentFor(inheritedMethod);
653 }); 652 });
654 } 653 }
655 654
656 /** 655 /**
657 * If a class extends a private superclass, find the closest public superclass 656 * If a class extends a private superclass, find the closest public superclass
658 * of the private superclass. 657 * of the private superclass.
659 */ 658 */
660 String validSuperclass() { 659 String validSuperclass() {
661 if (superclass == null) return 'dart.core.Object'; 660 if (superclass == null) return 'dart.core.Object';
662 if (_isVisible(superclass)) return superclass.qualifiedName; 661 if (_isVisible(superclass)) return superclass.qualifiedName;
663 return superclass.validSuperclass(); 662 return superclass.validSuperclass();
664 } 663 }
665 664
666 /// Generates a map describing the [Class] object. 665 /// Generates a map describing the [Class] object.
667 Map toMap() => { 666 Map toMap() => {
668 'name': name, 667 'name': name,
669 'qualifiedname': qualifiedName, 668 'qualifiedname': qualifiedName,
670 'comment': comment, 669 'comment': comment,
671 'superclass': validSuperclass(), 670 'superclass': validSuperclass(),
672 'implements': interfaces.where(_isVisible) 671 'implements': interfaces.where(_isVisible)
673 .map((e) => e.qualifiedName).toList(), 672 .map((e) => e.qualifiedName).toList(),
674 'subclass': subclasses.toList(), 673 'subclass': subclasses.toList(),
675 'variables': recurseMap(variables), 674 'variables': recurseMap(variables),
676 'inheritedvariables': recurseMap(inheritedVariables), 675 'inheritedvariables': recurseMap(inheritedVariables),
677 'methods': methods.toMap(), 676 'methods': methods.toMap(),
678 'inheritedmethods': inheritedMethods.toMap(), 677 'inheritedmethods': inheritedMethods.toMap(),
679 'annotations': annotations.map((a) => a.toMap()).toList(), 678 'annotations': annotations.map((a) => a.toMap()).toList(),
680 'generics': recurseMap(generics) 679 'generics': recurseMap(generics)
681 }; 680 };
682 } 681 }
683 682
684 /** 683 /**
685 * A container to categorize classes into the following groups: abstract 684 * A container to categorize classes into the following groups: abstract
686 * classes, regular classes, typedefs, and errors. 685 * classes, regular classes, typedefs, and errors.
687 */ 686 */
688 class ClassGroup { 687 class ClassGroup {
689 Map<String, Class> abstractClasses = {}; 688 Map<String, Class> abstractClasses = {};
690 Map<String, Class> regularClasses = {}; 689 Map<String, Class> regularClasses = {};
691 Map<String, Typedef> typedefs = {}; 690 Map<String, Typedef> typedefs = {};
692 Map<String, Class> errors = {}; 691 Map<String, Class> errors = {};
693 692
694 void addClass(ClassMirror mirror) { 693 void addClass(ClassMirror mirror) {
695 _currentClass = mirror; 694 _currentClass = mirror;
696 var clazz = _class(mirror); 695 var clazz = _class(mirror);
697 696
698 // Adding inherited parent variables and methods. 697 // Adding inherited parent variables and methods.
699 clazz.parent().forEach((parent) { 698 clazz.parent().forEach((parent) {
700 if (_isVisible(clazz)) { 699 if (_isVisible(clazz)) {
701 parent.addSubclass(clazz); 700 parent.addSubclass(clazz);
702 } 701 }
703 clazz.addInherited(parent); 702 clazz.addInherited(parent);
704 }); 703 });
705 704
706 clazz.ensureComments(); 705 clazz.ensureComments();
707 706
708 if (isError(mirror.qualifiedName)) { 707 if (isError(mirror.qualifiedName)) {
709 errors[mirror.simpleName] = clazz; 708 errors[mirror.simpleName] = clazz;
710 } else if (mirror.isTypedef) { 709 } else if (mirror.isTypedef) {
711 if (_includePrivate || !mirror.isPrivate) { 710 if (_includePrivate || !mirror.isPrivate) {
712 entityMap[mirror.qualifiedName] = new Typedef(mirror.simpleName, 711 entityMap[mirror.qualifiedName] = new Typedef(mirror.simpleName,
713 mirror.value.returnType.qualifiedName, _commentToHtml(mirror), 712 mirror.value.returnType.qualifiedName, _commentToHtml(mirror),
714 _generics(mirror), _parameters(mirror.value.parameters), 713 _generics(mirror), _parameters(mirror.value.parameters),
715 _annotations(mirror), mirror.qualifiedName, _isHidden(mirror), 714 _annotations(mirror), mirror.qualifiedName, _isHidden(mirror),
716 mirror.owner.qualifiedName); 715 mirror.owner.qualifiedName);
717 typedefs[mirror.simpleName] = entityMap[mirror.qualifiedName]; 716 typedefs[mirror.simpleName] = entityMap[mirror.qualifiedName];
718 } 717 }
719 } else if (mirror.isAbstract) { 718 } else if (mirror.isAbstract) {
720 abstractClasses[mirror.simpleName] = clazz; 719 abstractClasses[mirror.simpleName] = clazz;
721 } else if (mirror.isClass) { 720 } else if (mirror.isClass) {
722 regularClasses[mirror.simpleName] = clazz; 721 regularClasses[mirror.simpleName] = clazz;
723 } else { 722 } else {
724 throw new ArgumentError('${mirror.simpleName} - no class type match. '); 723 throw new ArgumentError('${mirror.simpleName} - no class type match. ');
725 } 724 }
726 } 725 }
727 726
728 /** 727 /**
729 * Checks if the given name is a key for any of the Class Maps. 728 * Checks if the given name is a key for any of the Class Maps.
730 */ 729 */
731 bool containsKey(String name) { 730 bool containsKey(String name) {
732 return abstractClasses.containsKey(name) || 731 return abstractClasses.containsKey(name) ||
733 regularClasses.containsKey(name) || 732 regularClasses.containsKey(name) ||
734 errors.containsKey(name); 733 errors.containsKey(name);
735 } 734 }
736 735
737 Map toMap() => { 736 Map toMap() => {
738 'abstract': abstractClasses.values.where(_isVisible) 737 'abstract': abstractClasses.values.where(_isVisible)
739 .map((e) => e.qualifiedName).toList(), 738 .map((e) => e.qualifiedName).toList(),
740 'class': regularClasses.values.where(_isVisible) 739 'class': regularClasses.values.where(_isVisible)
741 .map((e) => e.qualifiedName).toList(), 740 .map((e) => e.qualifiedName).toList(),
742 'typedef': recurseMap(typedefs), 741 'typedef': recurseMap(typedefs),
743 'error': errors.values.where(_isVisible) 742 'error': errors.values.where(_isVisible)
744 .map((e) => e.qualifiedName).toList() 743 .map((e) => e.qualifiedName).toList()
745 }; 744 };
746 } 745 }
747 746
748 class Typedef extends Indexable { 747 class Typedef extends Indexable {
749 String returnType; 748 String returnType;
750 749
751 Map<String, Parameter> parameters; 750 Map<String, Parameter> parameters;
752 751
753 /// Generic information about the typedef. 752 /// Generic information about the typedef.
754 Map<String, Generic> generics; 753 Map<String, Generic> generics;
755 754
756 /// List of the meta annotations on the typedef. 755 /// List of the meta annotations on the typedef.
757 List<String> annotations; 756 List<String> annotations;
758 757
759 Typedef(String name, this.returnType, String comment, this.generics, 758 Typedef(String name, this.returnType, String comment, this.generics,
760 this.parameters, this.annotations, 759 this.parameters, this.annotations,
761 String qualifiedName, bool isPrivate, String owner) : super(name, comment, 760 String qualifiedName, bool isPrivate, String owner) : super(name, comment,
762 qualifiedName, isPrivate, owner) {} 761 qualifiedName, isPrivate, owner) {}
763 762
764 Map toMap() => { 763 Map toMap() => {
765 'name': name, 764 'name': name,
766 'qualifiedname': qualifiedName, 765 'qualifiedname': qualifiedName,
767 'comment': comment, 766 'comment': comment,
768 'return': returnType, 767 'return': returnType,
769 'parameters': recurseMap(parameters), 768 'parameters': recurseMap(parameters),
770 'annotations': annotations.map((a) => a.toMap()).toList(), 769 'annotations': annotations.map((a) => a.toMap()).toList(),
771 'generics': recurseMap(generics) 770 'generics': recurseMap(generics)
772 }; 771 };
773 } 772 }
774 773
775 /** 774 /**
776 * A class containing properties of a Dart variable. 775 * A class containing properties of a Dart variable.
777 */ 776 */
778 class Variable extends Indexable { 777 class Variable extends Indexable {
779 778
780 bool isFinal; 779 bool isFinal;
781 bool isStatic; 780 bool isStatic;
782 bool isConst; 781 bool isConst;
783 Type type; 782 Type type;
784 783
785 /// List of the meta annotations on the variable. 784 /// List of the meta annotations on the variable.
786 List<String> annotations; 785 List<String> annotations;
787 786
788 Variable(String name, this.isFinal, this.isStatic, this.isConst, this.type, 787 Variable(String name, this.isFinal, this.isStatic, this.isConst, this.type,
789 String comment, this.annotations, String qualifiedName, bool isPrivate, 788 String comment, this.annotations, String qualifiedName, bool isPrivate,
790 String owner) : super(name, comment, qualifiedName, isPrivate, owner); 789 String owner) : super(name, comment, qualifiedName, isPrivate, owner);
791 790
792 /// Generates a map describing the [Variable] object. 791 /// Generates a map describing the [Variable] object.
793 Map toMap() => { 792 Map toMap() => {
794 'name': name, 793 'name': name,
795 'qualifiedname': qualifiedName, 794 'qualifiedname': qualifiedName,
796 'comment': comment, 795 'comment': comment,
797 'final': isFinal.toString(), 796 'final': isFinal.toString(),
798 'static': isStatic.toString(), 797 'static': isStatic.toString(),
799 'constant': isConst.toString(), 798 'constant': isConst.toString(),
800 'type': new List.filled(1, type.toMap()), 799 'type': new List.filled(1, type.toMap()),
801 'annotations': annotations.map((a) => a.toMap()).toList() 800 'annotations': annotations.map((a) => a.toMap()).toList()
802 }; 801 };
803 } 802 }
804 803
805 /** 804 /**
806 * A class containing properties of a Dart method. 805 * A class containing properties of a Dart method.
807 */ 806 */
808 class Method extends Indexable { 807 class Method extends Indexable {
809 808
810 /// Parameters for this method. 809 /// Parameters for this method.
811 Map<String, Parameter> parameters; 810 Map<String, Parameter> parameters;
812 811
813 bool isStatic; 812 bool isStatic;
814 bool isAbstract; 813 bool isAbstract;
815 bool isConst; 814 bool isConst;
816 Type returnType; 815 Type returnType;
817 816
818 /// Qualified name to state where the comment is inherited from. 817 /// Qualified name to state where the comment is inherited from.
819 String commentInheritedFrom = ""; 818 String commentInheritedFrom = "";
820 819
821 /// List of the meta annotations on the method. 820 /// List of the meta annotations on the method.
822 List<String> annotations; 821 List<String> annotations;
823 822
824 Method(String name, this.isStatic, this.isAbstract, this.isConst, 823 Method(String name, this.isStatic, this.isAbstract, this.isConst,
825 this.returnType, String comment, this.parameters, this.annotations, 824 this.returnType, String comment, this.parameters, this.annotations,
826 String qualifiedName, bool isPrivate, String owner) : super(name, comment, 825 String qualifiedName, bool isPrivate, String owner) : super(name, comment,
827 qualifiedName, isPrivate, owner); 826 qualifiedName, isPrivate, owner);
828 827
829 /** 828 /**
830 * Makes sure that the method with an inherited equivalent have comments. 829 * Makes sure that the method with an inherited equivalent have comments.
831 */ 830 */
832 void ensureCommentFor(Method inheritedMethod) { 831 void ensureCommentFor(Method inheritedMethod) {
833 if (comment.isNotEmpty) return; 832 if (comment.isNotEmpty) return;
834 entityMap[inheritedMethod.owner].ensureComments(); 833 entityMap[inheritedMethod.owner].ensureComments();
835 comment = inheritedMethod.comment; 834 comment = inheritedMethod.comment;
836 commentInheritedFrom = inheritedMethod.commentInheritedFrom == '' ? 835 commentInheritedFrom = inheritedMethod.commentInheritedFrom == '' ?
837 inheritedMethod.qualifiedName : inheritedMethod.commentInheritedFrom; 836 inheritedMethod.qualifiedName : inheritedMethod.commentInheritedFrom;
838 } 837 }
839 838
840 /// Generates a map describing the [Method] object. 839 /// Generates a map describing the [Method] object.
841 Map toMap() => { 840 Map toMap() => {
842 'name': name, 841 'name': name,
843 'qualifiedname': qualifiedName, 842 'qualifiedname': qualifiedName,
844 'comment': comment, 843 'comment': comment,
845 'commentfrom': commentInheritedFrom, 844 'commentfrom': commentInheritedFrom,
846 'static': isStatic.toString(), 845 'static': isStatic.toString(),
847 'abstract': isAbstract.toString(), 846 'abstract': isAbstract.toString(),
848 'constant': isConst.toString(), 847 'constant': isConst.toString(),
849 'return': new List.filled(1, returnType.toMap()), 848 'return': new List.filled(1, returnType.toMap()),
850 'parameters': recurseMap(parameters), 849 'parameters': recurseMap(parameters),
851 'annotations': annotations.map((a) => a.toMap()).toList() 850 'annotations': annotations.map((a) => a.toMap()).toList()
852 }; 851 };
853 } 852 }
854 853
855 /** 854 /**
856 * A container to categorize methods into the following groups: setters, 855 * A container to categorize methods into the following groups: setters,
857 * getters, constructors, operators, regular methods. 856 * getters, constructors, operators, regular methods.
858 */ 857 */
859 class MethodGroup { 858 class MethodGroup {
860 Map<String, Method> setters = {}; 859 Map<String, Method> setters = {};
861 Map<String, Method> getters = {}; 860 Map<String, Method> getters = {};
862 Map<String, Method> constructors = {}; 861 Map<String, Method> constructors = {};
863 Map<String, Method> operators = {}; 862 Map<String, Method> operators = {};
864 Map<String, Method> regularMethods = {}; 863 Map<String, Method> regularMethods = {};
865 864
866 void addMethod(MethodMirror mirror) { 865 void addMethod(MethodMirror mirror) {
867 var method = new Method(mirror.simpleName, mirror.isStatic, 866 var method = new Method(mirror.simpleName, mirror.isStatic,
868 mirror.isAbstract, mirror.isConstConstructor, _type(mirror.returnType), 867 mirror.isAbstract, mirror.isConstConstructor, _type(mirror.returnType),
869 _commentToHtml(mirror), _parameters(mirror.parameters), 868 _commentToHtml(mirror), _parameters(mirror.parameters),
870 _annotations(mirror), mirror.qualifiedName, _isHidden(mirror), 869 _annotations(mirror), mirror.qualifiedName, _isHidden(mirror),
871 mirror.owner.qualifiedName); 870 mirror.owner.qualifiedName);
872 entityMap[mirror.qualifiedName] = method; 871 entityMap[mirror.qualifiedName] = method;
873 _currentMember = mirror; 872 _currentMember = mirror;
874 if (mirror.isSetter) { 873 if (mirror.isSetter) {
875 setters[mirror.simpleName] = method; 874 setters[mirror.simpleName] = method;
876 } else if (mirror.isGetter) { 875 } else if (mirror.isGetter) {
877 getters[mirror.simpleName] = method; 876 getters[mirror.simpleName] = method;
878 } else if (mirror.isConstructor) { 877 } else if (mirror.isConstructor) {
879 constructors[mirror.simpleName] = method; 878 constructors[mirror.simpleName] = method;
880 } else if (mirror.isOperator) { 879 } else if (mirror.isOperator) {
881 operators[mirror.simpleName] = method; 880 operators[mirror.simpleName] = method;
882 } else if (mirror.isRegularMethod) { 881 } else if (mirror.isRegularMethod) {
883 regularMethods[mirror.simpleName] = method; 882 regularMethods[mirror.simpleName] = method;
884 } else { 883 } else {
885 throw new ArgumentError('${mirror.simpleName} - no method type match'); 884 throw new ArgumentError('${mirror.simpleName} - no method type match');
886 } 885 }
887 } 886 }
888 887
889 void addInherited(Class parent) { 888 void addInherited(Class parent) {
890 setters.addAll(parent.inheritedMethods.setters); 889 setters.addAll(parent.inheritedMethods.setters);
891 getters.addAll(parent.inheritedMethods.getters); 890 getters.addAll(parent.inheritedMethods.getters);
892 operators.addAll(parent.inheritedMethods.operators); 891 operators.addAll(parent.inheritedMethods.operators);
893 regularMethods.addAll(parent.inheritedMethods.regularMethods); 892 regularMethods.addAll(parent.inheritedMethods.regularMethods);
894 if (_isVisible(parent)) { 893 if (_isVisible(parent)) {
895 setters.addAll(parent.methods.setters); 894 setters.addAll(parent.methods.setters);
896 getters.addAll(parent.methods.getters); 895 getters.addAll(parent.methods.getters);
897 operators.addAll(parent.methods.operators); 896 operators.addAll(parent.methods.operators);
898 regularMethods.addAll(parent.methods.regularMethods); 897 regularMethods.addAll(parent.methods.regularMethods);
899 } 898 }
900 } 899 }
901 900
902 Map toMap() => { 901 Map toMap() => {
903 'setters': recurseMap(setters), 902 'setters': recurseMap(setters),
904 'getters': recurseMap(getters), 903 'getters': recurseMap(getters),
905 'constructors': recurseMap(constructors), 904 'constructors': recurseMap(constructors),
906 'operators': recurseMap(operators), 905 'operators': recurseMap(operators),
907 'methods': recurseMap(regularMethods) 906 'methods': recurseMap(regularMethods)
908 }; 907 };
909 908
910 Method operator [](String qualifiedName) { 909 Method operator [](String qualifiedName) {
911 if (setters.containsKey(qualifiedName)) return setters[qualifiedName]; 910 if (setters.containsKey(qualifiedName)) return setters[qualifiedName];
912 if (getters.containsKey(qualifiedName)) return getters[qualifiedName]; 911 if (getters.containsKey(qualifiedName)) return getters[qualifiedName];
913 if (operators.containsKey(qualifiedName)) return operators[qualifiedName]; 912 if (operators.containsKey(qualifiedName)) return operators[qualifiedName];
914 if (regularMethods.containsKey(qualifiedName)) { 913 if (regularMethods.containsKey(qualifiedName)) {
915 return regularMethods[qualifiedName]; 914 return regularMethods[qualifiedName];
916 } 915 }
917 return null; 916 return null;
918 } 917 }
919 918
920 void forEach(void f(String key, Method value)) { 919 void forEach(void f(String key, Method value)) {
921 setters.forEach(f); 920 setters.forEach(f);
922 getters.forEach(f); 921 getters.forEach(f);
923 operators.forEach(f); 922 operators.forEach(f);
924 regularMethods.forEach(f); 923 regularMethods.forEach(f);
925 } 924 }
926 } 925 }
927 926
928 /** 927 /**
929 * A class containing properties of a Dart method/function parameter. 928 * A class containing properties of a Dart method/function parameter.
930 */ 929 */
931 class Parameter { 930 class Parameter {
932 931
933 String name; 932 String name;
934 bool isOptional; 933 bool isOptional;
935 bool isNamed; 934 bool isNamed;
936 bool hasDefaultValue; 935 bool hasDefaultValue;
937 Type type; 936 Type type;
938 String defaultValue; 937 String defaultValue;
939 938
940 /// List of the meta annotations on the parameter. 939 /// List of the meta annotations on the parameter.
941 List<String> annotations; 940 List<String> annotations;
942 941
943 Parameter(this.name, this.isOptional, this.isNamed, this.hasDefaultValue, 942 Parameter(this.name, this.isOptional, this.isNamed, this.hasDefaultValue,
944 this.type, this.defaultValue, this.annotations); 943 this.type, this.defaultValue, this.annotations);
945 944
946 /// Generates a map describing the [Parameter] object. 945 /// Generates a map describing the [Parameter] object.
947 Map toMap() => { 946 Map toMap() => {
948 'name': name, 947 'name': name,
949 'optional': isOptional.toString(), 948 'optional': isOptional.toString(),
950 'named': isNamed.toString(), 949 'named': isNamed.toString(),
951 'default': hasDefaultValue.toString(), 950 'default': hasDefaultValue.toString(),
952 'type': new List.filled(1, type.toMap()), 951 'type': new List.filled(1, type.toMap()),
953 'value': defaultValue, 952 'value': defaultValue,
954 'annotations': annotations.map((a) => a.toMap()).toList() 953 'annotations': annotations.map((a) => a.toMap()).toList()
955 }; 954 };
956 } 955 }
957 956
958 /** 957 /**
959 * A class containing properties of a Generic. 958 * A class containing properties of a Generic.
960 */ 959 */
961 class Generic { 960 class Generic {
962 String name; 961 String name;
963 String type; 962 String type;
964 963
965 Generic(this.name, this.type); 964 Generic(this.name, this.type);
966 965
967 Map toMap() => { 966 Map toMap() => {
968 'name': name, 967 'name': name,
969 'type': type 968 'type': type
970 }; 969 };
971 } 970 }
972 971
973 /** 972 /**
974 * Holds the name of a return type, and its generic type parameters. 973 * Holds the name of a return type, and its generic type parameters.
975 * 974 *
976 * Return types are of a form [outer]<[inner]>. 975 * Return types are of a form [outer]<[inner]>.
977 * If there is no [inner] part, [inner] will be an empty list. 976 * If there is no [inner] part, [inner] will be an empty list.
978 * 977 *
979 * For example: 978 * For example:
980 * int size() 979 * int size()
981 * "return" : 980 * "return" :
982 * - "outer" : "dart.core.int" 981 * - "outer" : "dart.core.int"
983 * "inner" : 982 * "inner" :
984 * 983 *
985 * List<String> toList() 984 * List<String> toList()
986 * "return" : 985 * "return" :
987 * - "outer" : "dart.core.List" 986 * - "outer" : "dart.core.List"
988 * "inner" : 987 * "inner" :
989 * - "outer" : "dart.core.String" 988 * - "outer" : "dart.core.String"
990 * "inner" : 989 * "inner" :
991 * 990 *
992 * Map<String, List<int>> 991 * Map<String, List<int>>
993 * "return" : 992 * "return" :
994 * - "outer" : "dart.core.Map" 993 * - "outer" : "dart.core.Map"
995 * "inner" : 994 * "inner" :
996 * - "outer" : "dart.core.String" 995 * - "outer" : "dart.core.String"
997 * "inner" : 996 * "inner" :
998 * - "outer" : "dart.core.List" 997 * - "outer" : "dart.core.List"
999 * "inner" : 998 * "inner" :
1000 * - "outer" : "dart.core.int" 999 * - "outer" : "dart.core.int"
1001 * "inner" : 1000 * "inner" :
1002 */ 1001 */
1003 class Type { 1002 class Type {
1004 String outer; 1003 String outer;
1005 List<Type> inner; 1004 List<Type> inner;
1006 1005
1007 Type(this.outer, this.inner); 1006 Type(this.outer, this.inner);
1008 1007
1009 Map toMap() => { 1008 Map toMap() => {
1010 'outer': outer, 1009 'outer': outer,
1011 'inner': inner.map((e) => e.toMap()).toList() 1010 'inner': inner.map((e) => e.toMap()).toList()
1012 }; 1011 };
1013 } 1012 }
1014 1013
1015 /** 1014 /**
1016 * Holds the name of the annotation, and its parameters. 1015 * Holds the name of the annotation, and its parameters.
1017 */ 1016 */
1018 class Annotation { 1017 class Annotation {
1019 String qualifiedName; 1018 String qualifiedName;
1020 List<String> parameters; 1019 List<String> parameters;
1021 1020
1022 Annotation(this.qualifiedName, this.parameters); 1021 Annotation(this.qualifiedName, this.parameters);
1023 1022
1024 Map toMap() => { 1023 Map toMap() => {
1025 'name': qualifiedName, 1024 'name': qualifiedName,
1026 'parameters': parameters 1025 'parameters': parameters
1027 }; 1026 };
1028 } 1027 }
OLDNEW
« no previous file with comments | « no previous file | pkg/docgen/pubspec.yaml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698