Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 43 | 43 |
| 44 /// Current class being documented to be used for comment links. | 44 /// Current class being documented to be used for comment links. |
| 45 ClassMirror _currentClass; | 45 ClassMirror _currentClass; |
| 46 | 46 |
| 47 /// Current member being documented to be used for comment links. | 47 /// Current member being documented to be used for comment links. |
| 48 MemberMirror _currentMember; | 48 MemberMirror _currentMember; |
| 49 | 49 |
| 50 /// Resolves reference links in doc comments. | 50 /// Resolves reference links in doc comments. |
| 51 markdown.Resolver linkResolver; | 51 markdown.Resolver linkResolver; |
| 52 | 52 |
| 53 /// Index of all the qualified names documented. | 53 /// Index of all indexable items. This also ensures that no class is |
| 54 Set<String> qualifiedNameIndex = new Set<String>(); | 54 /// created more than once. |
| 55 Map<String, Indexable> entityMap = new Map<String, Indexable>(); | |
| 56 | |
| 57 /// This is set from the command line arguments flag --include-private | |
| 58 bool _includePrivate = false; | |
| 55 | 59 |
| 56 /** | 60 /** |
| 57 * Docgen constructor initializes the link resolver for markdown parsing. | 61 * Docgen constructor initializes the link resolver for markdown parsing. |
| 58 * Also initializes the command line arguments. | 62 * Also initializes the command line arguments. |
| 59 * | 63 * |
| 60 * [packageRoot] is the packages directory of the directory being analyzed. | 64 * [packageRoot] is the packages directory of the directory being analyzed. |
| 61 * If [includeSdk] is `true`, then any SDK libraries explicitly imported will | 65 * If [includeSdk] is `true`, then any SDK libraries explicitly imported will |
| 62 * also be documented. | 66 * also be documented. |
| 63 * If [parseSdk] is `true`, then all Dart SDK libraries will be documented. | 67 * If [parseSdk] is `true`, then all Dart SDK libraries will be documented. |
| 64 * This option is useful when only the SDK libraries are needed. | 68 * This option is useful when only the SDK libraries are needed. |
| 65 * | 69 * |
| 66 * Returns `true` if docgen sucessfuly completes. | 70 * Returns `true` if docgen sucessfuly completes. |
| 67 */ | 71 */ |
| 68 Future<bool> docgen(List<String> files, {String packageRoot, | 72 Future<bool> docgen(List<String> files, {String packageRoot, |
| 69 bool outputToYaml: true, bool includePrivate: false, bool includeSdk: false, | 73 bool outputToYaml: true, bool includePrivate: false, bool includeSdk: false, |
| 70 bool parseSdk: false, bool append: false}) { | 74 bool parseSdk: false, bool append: false}) { |
| 75 _includePrivate = includePrivate; | |
|
Alan Knight
2013/08/01 18:27:19
It's hard to follow this in the web view, but the
| |
| 71 if (!append) { | 76 if (!append) { |
| 72 var dir = new Directory('docs'); | 77 var dir = new Directory('docs'); |
| 73 if (dir.existsSync()) dir.deleteSync(recursive: true); | 78 if (dir.existsSync()) dir.deleteSync(recursive: true); |
| 74 } | 79 } |
| 75 | 80 |
| 76 if (packageRoot == null && !parseSdk) { | 81 if (packageRoot == null && !parseSdk) { |
| 77 var type = FileSystemEntity.typeSync(files.first); | 82 var type = FileSystemEntity.typeSync(files.first); |
| 78 if (type == FileSystemEntityType.DIRECTORY) { | 83 if (type == FileSystemEntityType.DIRECTORY) { |
| 79 packageRoot = _findPackageRoot(files.first); | 84 packageRoot = _findPackageRoot(files.first); |
| 80 } else if (type == FileSystemEntityType.FILE) { | 85 } else if (type == FileSystemEntityType.FILE) { |
| 81 logger.warning('WARNING: No package root defined. If Docgen fails, try ' | 86 logger.warning('WARNING: No package root defined. If Docgen fails, try ' |
| 82 'again by setting the --package-root option.'); | 87 'again by setting the --package-root option.'); |
| 83 } | 88 } |
| 84 } | 89 } |
| 85 logger.info('Package Root: ${packageRoot}'); | 90 logger.info('Package Root: ${packageRoot}'); |
| 86 | 91 |
| 87 linkResolver = (name) => | 92 linkResolver = (name) => |
| 88 fixReference(name, _currentLibrary, _currentClass, _currentMember); | 93 fixReference(name, _currentLibrary, _currentClass, _currentMember); |
| 89 | 94 |
| 90 return getMirrorSystem(files, packageRoot: packageRoot, parseSdk: parseSdk) | 95 return getMirrorSystem(files, packageRoot: packageRoot, parseSdk: parseSdk) |
| 91 .then((MirrorSystem mirrorSystem) { | 96 .then((MirrorSystem mirrorSystem) { |
| 92 if (mirrorSystem.libraries.isEmpty) { | 97 if (mirrorSystem.libraries.isEmpty) { |
| 93 throw new StateError('No library mirrors were created.'); | 98 throw new StateError('No library mirrors were created.'); |
| 94 } | 99 } |
| 95 _documentLibraries(mirrorSystem.libraries.values, | 100 _documentLibraries(mirrorSystem.libraries.values, |
| 96 includeSdk: includeSdk, includePrivate: includePrivate, | 101 includeSdk: includeSdk, outputToYaml: outputToYaml, append: append); |
| 97 outputToYaml: outputToYaml, append: append); | |
| 98 | 102 |
| 99 return true; | 103 return true; |
| 100 }); | 104 }); |
| 101 } | 105 } |
| 102 | 106 |
| 103 List<String> _listLibraries(List<String> args) { | 107 List<String> _listLibraries(List<String> args) { |
| 104 if (args.length != 1) throw new UnsupportedError(USAGE); | 108 if (args.length != 1) throw new UnsupportedError(USAGE); |
| 105 var libraries = new List<String>(); | 109 var libraries = new List<String>(); |
| 106 var type = FileSystemEntity.typeSync(args[0]); | 110 var type = FileSystemEntity.typeSync(args[0]); |
| 107 | 111 |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 189 // Currently, a string is thrown when it fails to create a mirror | 193 // Currently, a string is thrown when it fails to create a mirror |
| 190 // system, and it is not possible to use the stack trace. BUG(#11622) | 194 // system, and it is not possible to use the stack trace. BUG(#11622) |
| 191 // To avoid printing the stack trace. | 195 // To avoid printing the stack trace. |
| 192 exit(1); | 196 exit(1); |
| 193 }); | 197 }); |
| 194 } | 198 } |
| 195 | 199 |
| 196 /** | 200 /** |
| 197 * Creates documentation for filtered libraries. | 201 * Creates documentation for filtered libraries. |
| 198 */ | 202 */ |
| 199 void _documentLibraries(List<LibraryMirror> libraries, | 203 void _documentLibraries(List<LibraryMirror> libs, |
| 200 {bool includeSdk: false, bool includePrivate: false, | 204 {bool includeSdk: false, bool outputToYaml: true, bool append: false}) { |
| 201 bool outputToYaml: true, bool append: false}) { | 205 libs.forEach((lib) { |
| 202 libraries.forEach((lib) { | |
| 203 // Files belonging to the SDK have a uri that begins with 'dart:'. | 206 // Files belonging to the SDK have a uri that begins with 'dart:'. |
| 204 if (includeSdk || !lib.uri.toString().startsWith('dart:')) { | 207 if (includeSdk || !lib.uri.toString().startsWith('dart:')) { |
| 205 var library = generateLibrary(lib, includePrivate: includePrivate); | 208 var library = generateLibrary(lib); |
| 206 _writeLibraryToFile(library, outputToYaml); | 209 entityMap[library.qualifiedName] = library; |
| 207 } | 210 } |
| 208 }); | 211 }); |
| 209 // Outputs a text file with a list of files available after creating all | 212 // After everything is created, do a pass through all classes to make sure no |
| 210 // the libraries. This will help the viewer know what files are available | 213 // classes created from mixins are included. |
|
Alan Knight
2013/08/01 18:27:19
I assume this means we're skipping intermediate en
janicejl
2013/08/01 20:15:40
Done.
| |
| 214 entityMap.values.where((e) => e is Class).forEach((c) => c.makeValid()); | |
| 215 // Everything is a subclass of Object, therefore empty the list to avoid a | |
| 216 // giant list of subclasses to be printed out. | |
| 217 entityMap['dart.core.Object'].subclasses.clear(); | |
| 218 // Output libraries and classes to file after all information is generated. | |
| 219 entityMap.values.where((e) => (e is Class || e is Library)) | |
| 220 .where((e) => _includePrivate || !e.isPrivate).forEach((output) { | |
| 221 _writeIndexableToFile(output, outputToYaml); | |
|
Alan Knight
2013/08/01 18:27:19
Nit. I think you could re-arrange the filtering c
janicejl
2013/08/01 20:15:40
Done.
| |
| 222 }); | |
| 223 // Outputs a text file with a list of libraries available after creating all | |
| 224 // the libraries. This will help the viewer know what libraries are available | |
| 211 // to read in. | 225 // to read in. |
| 212 _writeToFile(listDir('docs').join('\n').replaceAll('docs/', ''), | 226 _writeToFile(entityMap.values.where((e) => e is Library) |
| 213 'library_list.txt', append: append); | 227 .where((e) => (_includePrivate || !e.isPrivate)) |
| 228 .map((e) => e.qualifiedName).join('\n'), 'library_list.txt', | |
| 229 append: append); | |
| 214 // Outputs all the qualified names documented. This will help generate search | 230 // Outputs all the qualified names documented. This will help generate search |
| 215 // results. | 231 // results. |
| 216 _writeToFile(qualifiedNameIndex.join('\n'), 'index.txt', append: append); | 232 _writeToFile(entityMap.values.where((e) => (_includePrivate || !e.isPrivate)) |
| 233 .map((e) => e.qualifiedName).join('\n'), 'index.txt', append: append); | |
| 217 } | 234 } |
| 218 | 235 |
| 219 Library generateLibrary(dart2js.Dart2JsLibraryMirror library, | 236 Library generateLibrary(dart2js.Dart2JsLibraryMirror library) { |
| 220 {bool includePrivate: false}) { | |
| 221 _currentLibrary = library; | 237 _currentLibrary = library; |
| 222 var result = new Library(library.qualifiedName, _getComment(library), | 238 var result = new Library(library.qualifiedName, _commentToHtml(library), |
| 223 _getVariables(library.variables, includePrivate), | 239 _variables(library.variables), |
| 224 _getMethods(library.functions, includePrivate), | 240 _methods(library.functions), |
| 225 _getClasses(library.classes, includePrivate)); | 241 _classes(library.classes), _isPrivate(library)); |
| 226 logger.fine('Generated library for ${result.name}'); | 242 logger.fine('Generated library for ${result.name}'); |
| 227 return result; | 243 return result; |
| 228 } | 244 } |
| 229 | 245 |
| 230 void _writeLibraryToFile(Library result, bool outputToYaml) { | 246 void _writeIndexableToFile(Indexable result, bool outputToYaml) { |
| 231 if (outputToYaml) { | 247 if (outputToYaml) { |
| 232 _writeToFile(getYamlString(result.toMap()), '${result.name}.yaml'); | 248 _writeToFile(getYamlString(result.toMap()), '${result.qualifiedName}.yaml'); |
| 233 } else { | 249 } else { |
| 234 _writeToFile(stringify(result.toMap()), '${result.name}.json'); | 250 _writeToFile(stringify(result.toMap()), '${result.qualifiedName}.json'); |
| 235 } | 251 } |
| 252 } | |
| 236 | 253 |
| 254 /** | |
| 255 * Returns true if a library name starts with an underscore, and false | |
| 256 * otherwise. | |
|
Alan Knight
2013/08/01 18:27:19
How does the "._" case arise? Should probably be d
janicejl
2013/08/01 20:15:40
Done.
| |
| 257 */ | |
| 258 // This is because LibraryMirror.isPrivate returns `false` all the time. | |
| 259 bool _isLibraryPrivate(LibraryMirror mirror) { | |
| 260 if (mirror.simpleName.startsWith('_') || mirror.simpleName.contains('._')) { | |
| 261 return true; | |
| 262 } | |
| 263 return false; | |
| 264 } | |
| 265 | |
| 266 /** | |
| 267 * A declaration is private if itself is private, or the owner is private. | |
| 268 */ | |
| 269 bool _isPrivate(DeclarationMirror mirror) { | |
| 270 if (mirror is LibraryMirror) { | |
| 271 return _isLibraryPrivate(mirror); | |
| 272 } else if (mirror.owner is LibraryMirror) { | |
| 273 return (mirror.isPrivate || _isLibraryPrivate(mirror.owner)); | |
| 274 } else { | |
| 275 return (mirror.isPrivate || _isPrivate(mirror.owner)); | |
| 276 } | |
| 237 } | 277 } |
| 238 | 278 |
| 239 /** | 279 /** |
| 240 * Returns a list of meta annotations assocated with a mirror. | 280 * Returns a list of meta annotations assocated with a mirror. |
| 241 */ | 281 */ |
| 242 List<String> _getAnnotations(DeclarationMirror mirror) { | 282 List<String> _annotations(DeclarationMirror mirror) { |
| 243 var annotations = mirror.metadata.where((e) => | 283 var annotations = mirror.metadata.where((e) => |
| 244 e is dart2js.Dart2JsConstructedConstantMirror); | 284 e is dart2js.Dart2JsConstructedConstantMirror); |
| 245 return annotations.map((e) => e.type.qualifiedName).toList(); | 285 return annotations.map((e) => e.type.qualifiedName).toList(); |
| 246 } | 286 } |
| 247 | 287 |
| 248 /** | 288 /** |
| 249 * Returns any documentation comments associated with a mirror with | 289 * Returns any documentation comments associated with a mirror with |
| 250 * simple markdown converted to html. | 290 * simple markdown converted to html. |
| 251 */ | 291 */ |
| 252 String _getComment(DeclarationMirror mirror) { | 292 String _commentToHtml(DeclarationMirror mirror) { |
| 253 String commentText; | 293 String commentText; |
| 254 mirror.metadata.forEach((metadata) { | 294 mirror.metadata.forEach((metadata) { |
| 255 if (metadata is CommentInstanceMirror) { | 295 if (metadata is CommentInstanceMirror) { |
| 256 CommentInstanceMirror comment = metadata; | 296 CommentInstanceMirror comment = metadata; |
| 257 if (comment.isDocComment) { | 297 if (comment.isDocComment) { |
| 258 if (commentText == null) { | 298 if (commentText == null) { |
| 259 commentText = comment.trimmedText; | 299 commentText = comment.trimmedText; |
| 260 } else { | 300 } else { |
| 261 commentText = '$commentText ${comment.trimmedText}'; | 301 commentText = '$commentText ${comment.trimmedText}'; |
| 262 } | 302 } |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 282 var classScope = currentClass == null ? | 322 var classScope = currentClass == null ? |
| 283 null : currentClass.lookupInScope(name); | 323 null : currentClass.lookupInScope(name); |
| 284 reference = classScope != null ? classScope.qualifiedName : name; | 324 reference = classScope != null ? classScope.qualifiedName : name; |
| 285 } | 325 } |
| 286 return new markdown.Element.text('a', reference); | 326 return new markdown.Element.text('a', reference); |
| 287 } | 327 } |
| 288 | 328 |
| 289 /** | 329 /** |
| 290 * Returns a map of [Variable] objects constructed from [mirrorMap]. | 330 * Returns a map of [Variable] objects constructed from [mirrorMap]. |
| 291 */ | 331 */ |
| 292 Map<String, Variable> _getVariables(Map<String, VariableMirror> mirrorMap, | 332 Map<String, Variable> _variables(Map<String, VariableMirror> mirrorMap) { |
| 293 bool includePrivate) { | |
| 294 var data = {}; | 333 var data = {}; |
| 295 // TODO(janicejl): When map to map feature is created, replace the below with | 334 // TODO(janicejl): When map to map feature is created, replace the below with |
| 296 // a filter. Issue(#9590). | 335 // a filter. Issue(#9590). |
| 297 mirrorMap.forEach((String mirrorName, VariableMirror mirror) { | 336 mirrorMap.forEach((String mirrorName, VariableMirror mirror) { |
| 298 if (includePrivate || !mirror.isPrivate) { | 337 _currentMember = mirror; |
| 299 _currentMember = mirror; | 338 if (_includePrivate || !_isPrivate(mirror)) { |
| 300 data[mirrorName] = new Variable(mirrorName, mirror.isFinal, | 339 entityMap[mirror.qualifiedName] = new Variable(mirrorName, mirror.isFinal, |
| 301 mirror.isStatic, mirror.isConst, _type(mirror.type), | 340 mirror.isStatic, mirror.isConst, _type(mirror.type), |
| 302 _getComment(mirror), _getAnnotations(mirror), mirror.qualifiedName); | 341 _commentToHtml(mirror), _annotations(mirror), mirror.qualifiedName, |
| 342 _isPrivate(mirror), mirror.owner.qualifiedName); | |
| 343 data[mirrorName] = entityMap[mirror.qualifiedName]; | |
| 303 } | 344 } |
| 304 }); | 345 }); |
| 305 return data; | 346 return data; |
| 306 } | 347 } |
| 307 | 348 |
| 308 /** | 349 /** |
| 309 * Returns a map of [Method] objects constructed from [mirrorMap]. | 350 * Returns a map of [Method] objects constructed from [mirrorMap]. |
| 310 */ | 351 */ |
| 311 Map<String, Map<String, Method>> _getMethods | 352 MethodGroup _methods(Map<String, MethodMirror> mirrorMap) { |
| 312 (Map<String, MethodMirror> mirrorMap, bool includePrivate) { | 353 var group = new MethodGroup(); |
| 313 | |
| 314 var setters = {}; | |
| 315 var getters = {}; | |
| 316 var constructors = {}; | |
| 317 var operators = {}; | |
| 318 var methods = {}; | |
| 319 | |
| 320 mirrorMap.forEach((String mirrorName, MethodMirror mirror) { | 354 mirrorMap.forEach((String mirrorName, MethodMirror mirror) { |
| 321 if (includePrivate || !mirror.isPrivate) { | 355 if (_includePrivate || !_isPrivate(mirror)) { |
| 322 var method = new Method(mirrorName, mirror.isStatic, mirror.isAbstract, | 356 group.addMethod(mirror); |
| 323 mirror.isConstConstructor, _type(mirror.returnType), | |
| 324 _getComment(mirror), _getParameters(mirror.parameters), | |
| 325 _getAnnotations(mirror), mirror.qualifiedName); | |
| 326 _currentMember = mirror; | |
| 327 if (mirror.isSetter) { | |
| 328 setters[mirrorName] = method; | |
| 329 } else if (mirror.isGetter) { | |
| 330 getters[mirrorName] = method; | |
| 331 } else if (mirror.isConstructor) { | |
| 332 constructors[mirrorName] = method; | |
| 333 } else if (mirror.isOperator) { | |
| 334 operators[mirrorName] = method; | |
| 335 } else if (mirror.isRegularMethod) { | |
| 336 methods[mirrorName] = method; | |
| 337 } else { | |
| 338 throw new ArgumentError('$mirrorName - no method type match'); | |
| 339 } | |
| 340 } | 357 } |
| 341 }); | 358 }); |
| 342 return { | 359 return group; |
| 343 'setters': setters, | |
| 344 'getters': getters, | |
| 345 'constructors': constructors, | |
| 346 'operators': operators, | |
| 347 'methods': methods | |
| 348 }; | |
| 349 } | 360 } |
| 350 | 361 |
| 351 /** | 362 /** |
| 363 * Returns the [Class] for the given [mirror] has already been created, and if | |
| 364 * it does not exist, creates it. | |
| 365 */ | |
| 366 Class _class(ClassMirror mirror) { | |
| 367 var clazz = entityMap[mirror.qualifiedName]; | |
| 368 if (clazz == null) { | |
| 369 var superclass = mirror.superclass != null ? | |
| 370 _class(mirror.superclass) : null; | |
| 371 var interfaces = | |
| 372 mirror.superinterfaces.map((interface) => _class(interface)); | |
| 373 clazz = new Class(mirror.simpleName, superclass, _commentToHtml(mirror), | |
| 374 interfaces.toList(), _variables(mirror.variables), | |
| 375 _methods(mirror.methods), _annotations(mirror), _generics(mirror), | |
| 376 mirror.qualifiedName, _isPrivate(mirror), mirror.owner.qualifiedName); | |
| 377 entityMap[mirror.qualifiedName] = clazz; | |
| 378 } | |
| 379 return clazz; | |
| 380 } | |
| 381 | |
| 382 /** | |
| 352 * Returns a map of [Class] objects constructed from [mirrorMap]. | 383 * Returns a map of [Class] objects constructed from [mirrorMap]. |
| 353 */ | 384 */ |
| 354 Map<String, Class> _getClasses(Map<String, ClassMirror> mirrorMap, | 385 ClassGroup _classes(Map<String, ClassMirror> mirrorMap) { |
| 355 bool includePrivate) { | 386 var group = new ClassGroup(); |
| 356 | |
| 357 var abstractClasses = {}; | |
| 358 var classes = {}; | |
| 359 var typedefs = {}; | |
| 360 var errors = {}; | |
| 361 | |
| 362 mirrorMap.forEach((String mirrorName, ClassMirror mirror) { | 387 mirrorMap.forEach((String mirrorName, ClassMirror mirror) { |
| 363 if (includePrivate || !mirror.isPrivate) { | 388 group.addClass(mirror); |
| 364 var superclass = (mirror.superclass != null) ? | |
| 365 mirror.superclass.qualifiedName : ''; | |
| 366 var interfaces = | |
| 367 mirror.superinterfaces.map((interface) => interface.qualifiedName); | |
| 368 var clazz = new Class(mirrorName, superclass, _getComment(mirror), | |
| 369 interfaces.toList(), _getVariables(mirror.variables, includePrivate), | |
| 370 _getMethods(mirror.methods, includePrivate), | |
| 371 _getAnnotations(mirror), _getGenerics(mirror), mirror.qualifiedName); | |
| 372 _currentClass = mirror; | |
| 373 | |
| 374 if (isError(mirror.qualifiedName)) { | |
| 375 errors[mirrorName] = clazz; | |
| 376 } else if (mirror.isTypedef) { | |
| 377 typedefs[mirrorName] = new Typedef(mirrorName, | |
| 378 mirror.value.returnType.qualifiedName, _getComment(mirror), | |
| 379 _getGenerics(mirror), _getParameters(mirror.value.parameters), | |
| 380 _getAnnotations(mirror), mirror.qualifiedName); | |
| 381 } else if (mirror.isAbstract) { | |
| 382 abstractClasses[mirrorName] = clazz; | |
| 383 } else if (mirror.isClass) { | |
| 384 classes[mirrorName] = clazz; | |
| 385 } else { | |
| 386 throw new ArgumentError('$mirrorName - no class type match. '); | |
| 387 } | |
| 388 } | |
| 389 }); | 389 }); |
| 390 return { | 390 return group; |
| 391 'abstract': abstractClasses, | |
| 392 'class': classes, | |
| 393 'typedef': typedefs, | |
| 394 'error': errors | |
| 395 }; | |
| 396 } | 391 } |
| 397 | 392 |
| 398 /** | 393 /** |
| 399 * Returns a map of [Parameter] objects constructed from [mirrorList]. | 394 * Returns a map of [Parameter] objects constructed from [mirrorList]. |
| 400 */ | 395 */ |
| 401 Map<String, Parameter> _getParameters(List<ParameterMirror> mirrorList) { | 396 Map<String, Parameter> _parameters(List<ParameterMirror> mirrorList) { |
| 402 var data = {}; | 397 var data = {}; |
| 403 mirrorList.forEach((ParameterMirror mirror) { | 398 mirrorList.forEach((ParameterMirror mirror) { |
| 404 _currentMember = mirror; | 399 _currentMember = mirror; |
| 405 data[mirror.simpleName] = new Parameter(mirror.simpleName, | 400 data[mirror.simpleName] = new Parameter(mirror.simpleName, |
| 406 mirror.isOptional, mirror.isNamed, mirror.hasDefaultValue, | 401 mirror.isOptional, mirror.isNamed, mirror.hasDefaultValue, |
| 407 _type(mirror.type), mirror.defaultValue, | 402 _type(mirror.type), mirror.defaultValue, |
| 408 _getAnnotations(mirror)); | 403 _annotations(mirror)); |
| 409 }); | 404 }); |
| 410 return data; | 405 return data; |
| 411 } | 406 } |
| 412 | 407 |
| 413 /** | 408 /** |
| 414 * Returns a map of [Generic] objects constructed from the class mirror. | 409 * Returns a map of [Generic] objects constructed from the class mirror. |
| 415 */ | 410 */ |
| 416 Map<String, Generic> _getGenerics(ClassMirror mirror) { | 411 Map<String, Generic> _generics(ClassMirror mirror) { |
| 417 return new Map.fromIterable(mirror.typeVariables, | 412 return new Map.fromIterable(mirror.typeVariables, |
| 418 key: (e) => e.toString(), | 413 key: (e) => e.toString(), |
| 419 value: (e) => new Generic(e.toString(), e.upperBound.qualifiedName)); | 414 value: (e) => new Generic(e.toString(), e.upperBound.qualifiedName)); |
| 420 } | 415 } |
| 421 | 416 |
| 422 /** | 417 /** |
| 423 * Returns a single [Type] object constructed from the Method.returnType | 418 * Returns a single [Type] object constructed from the Method.returnType |
| 424 * Type mirror. | 419 * Type mirror. |
| 425 */ | 420 */ |
| 426 Type _type(TypeMirror mirror) { | 421 Type _type(TypeMirror mirror) { |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 475 return qualifiedName.toLowerCase().contains('error') || | 470 return qualifiedName.toLowerCase().contains('error') || |
| 476 qualifiedName.toLowerCase().contains('exception'); | 471 qualifiedName.toLowerCase().contains('exception'); |
| 477 } | 472 } |
| 478 | 473 |
| 479 /** | 474 /** |
| 480 * A class representing all programming constructs, like library or class. | 475 * A class representing all programming constructs, like library or class. |
| 481 */ | 476 */ |
| 482 class Indexable { | 477 class Indexable { |
| 483 String name; | 478 String name; |
| 484 String qualifiedName; | 479 String qualifiedName; |
| 480 bool isPrivate; | |
| 485 | 481 |
| 486 /// Documentation comment with converted markdown. | 482 /// Documentation comment with converted markdown. |
| 487 String comment; | 483 String comment; |
| 488 | 484 |
| 489 Indexable(this.name, this.comment, String qualifiedName) { | 485 /// Qualified Name of the owner of this Indexable Item. |
| 486 /// For Library, owner will be ""; | |
| 487 String owner; | |
| 488 | |
| 489 Indexable(this.name, this.comment, String qualifiedName, bool isPrivate, | |
| 490 this.owner) { | |
| 490 this.qualifiedName = qualifiedName; | 491 this.qualifiedName = qualifiedName; |
|
Alan Knight
2013/08/01 18:27:19
Why are these two in the body of the constructor i
janicejl
2013/08/01 20:15:40
Done.
| |
| 491 qualifiedNameIndex.add(qualifiedName); | 492 this.isPrivate = isPrivate; |
| 492 } | 493 } |
| 493 } | 494 } |
| 494 | 495 |
| 495 /** | 496 /** |
| 496 * A class containing contents of a Dart library. | 497 * A class containing contents of a Dart library. |
| 497 */ | 498 */ |
| 498 class Library extends Indexable { | 499 class Library extends Indexable { |
| 499 | 500 |
| 500 /// Top-level variables in the library. | 501 /// Top-level variables in the library. |
| 501 Map<String, Variable> variables; | 502 Map<String, Variable> variables; |
| 502 | 503 |
| 503 /// Top-level functions in the library. | 504 /// Top-level functions in the library. |
| 504 Map<String, Map<String, Method>> functions; | 505 MethodGroup functions; |
| 505 | 506 |
| 506 /// Classes defined within the library | 507 /// Classes defined within the library |
| 507 Map<String, Class> classes; | 508 ClassGroup classes; |
| 508 | 509 |
| 509 Library(String name, String comment, this.variables, | 510 Library(String name, String comment, this.variables, |
| 510 this.functions, this.classes) : super(name, comment, name) {} | 511 this.functions, this.classes, bool isPrivate) : super(name, comment, |
| 512 name, isPrivate, "") {} | |
| 511 | 513 |
| 512 /// Generates a map describing the [Library] object. | 514 /// Generates a map describing the [Library] object. |
| 513 Map toMap() => { | 515 Map toMap() => { |
| 514 'name': name, | 516 'name': name, |
| 515 'qualifiedname': qualifiedName, | 517 'qualifiedname': qualifiedName, |
| 516 'comment': comment, | 518 'comment': comment, |
| 517 'variables': recurseMap(variables), | 519 'variables': recurseMap(variables), |
| 518 'functions': recurseMap(functions), | 520 'functions': functions.toMap(), |
| 519 'classes': recurseMap(classes) | 521 'classes': classes.toMap() |
| 520 }; | 522 }; |
| 521 } | 523 } |
| 522 | 524 |
| 523 /** | 525 /** |
| 524 * A class containing contents of a Dart class. | 526 * A class containing contents of a Dart class. |
| 525 */ | 527 */ |
| 526 class Class extends Indexable { | 528 class Class extends Indexable { |
| 527 | 529 |
| 528 /// List of the names of interfaces that this class implements. | 530 /// List of the names of interfaces that this class implements. |
| 529 List<String> interfaces; | 531 List<Class> interfaces = []; |
| 532 | |
| 533 /// Names of classes that extends or implements this class. | |
| 534 Set<String> subclasses = new Set<String>(); | |
| 530 | 535 |
| 531 /// Top-level variables in the class. | 536 /// Top-level variables in the class. |
| 532 Map<String, Variable> variables; | 537 Map<String, Variable> variables; |
| 538 | |
| 539 /// Inherited variables in the class. | |
| 540 Map<String, Variable> inheritedVariables = {}; | |
| 533 | 541 |
| 534 /// Methods in the class. | 542 /// Methods in the class. |
| 535 Map<String, Map<String, Method>> methods; | 543 MethodGroup methods; |
| 544 | |
| 545 /// Inherited methods in the class. | |
| 546 MethodGroup inheritedMethods = new MethodGroup(); | |
| 536 | 547 |
| 537 /// Generic infomation about the class. | 548 /// Generic infomation about the class. |
| 538 Map<String, Generic> generics; | 549 Map<String, Generic> generics; |
| 539 | 550 |
| 540 String superclass; | 551 Class superclass; |
| 541 | 552 |
| 542 /// List of the meta annotations on the class. | 553 /// List of the meta annotations on the class. |
| 543 List<String> annotations; | 554 List<String> annotations; |
| 544 | 555 |
| 545 Class(String name, this.superclass, String comment, this.interfaces, | 556 Class(String name, this.superclass, String comment, this.interfaces, |
| 546 this.variables, this.methods, this.annotations, this.generics, | 557 this.variables, this.methods, this.annotations, this.generics, |
| 547 String qualifiedName) : super(name, comment, qualifiedName) {} | 558 String qualifiedName, bool isPrivate, String owner) : super(name, comment, |
| 559 qualifiedName, isPrivate, owner) {} | |
| 548 | 560 |
| 561 /** | |
| 562 * Add all inherited variables and classes from the provided superclass. | |
| 563 * | |
| 564 * If [_includePrivate] is `false`, it only adds the inherited variables and | |
| 565 * methods from the superclass. | |
| 566 * If [_includePrivate] is `true`, it adds both inherited variables and | |
| 567 * methods as well as variables and methods from the superclass. | |
|
Alan Knight
2013/08/01 18:27:19
These comments could be clearer.
janicejl
2013/08/01 20:15:40
Done.
| |
| 568 */ | |
| 569 void addInherited(Class superclass) { | |
| 570 inheritedVariables.addAll(superclass.inheritedVariables); | |
| 571 if (_includePrivate || !superclass.isPrivate) { | |
| 572 inheritedVariables.addAll(superclass.variables); | |
| 573 } | |
| 574 inheritedMethods.addInherited(superclass); | |
| 575 } | |
| 576 | |
| 577 /** | |
| 578 * Add the subclass to the class. | |
| 579 * | |
| 580 * If this class is private, it will add it to it's superclasses. | |
|
Alan Knight
2013/08/01 18:27:19
Too many different "it"s. Refer to the things by n
janicejl
2013/08/01 20:15:40
Done.
| |
| 581 */ | |
| 582 void addSubClass(Class subclass) { | |
|
Alan Knight
2013/08/01 18:27:19
Be consistent between subClass and subclass. I thi
janicejl
2013/08/01 20:15:40
Done.
| |
| 583 if (!_includePrivate && isPrivate) { | |
| 584 if (superclass != null) superclass.addSubClass(subclass); | |
| 585 interfaces.forEach((interface) { | |
| 586 interface.addSubClass(subclass); | |
| 587 }); | |
| 588 } else { | |
| 589 subclasses.add(subclass.qualifiedName); | |
| 590 } | |
| 591 } | |
| 592 | |
| 593 /** | |
| 594 * Ensures that the class is exists in the owner library. | |
|
Alan Knight
2013/08/01 18:27:19
No "is", and probably better to say "Check" than "
janicejl
2013/08/01 20:15:40
Done.
| |
| 595 * | |
| 596 * If it does not exist in the owner library, it is a mixin and should be | |
| 597 * removed. | |
| 598 */ | |
| 599 void makeValid() { | |
| 600 var library = entityMap[owner]; | |
| 601 if (!library.classes.containsKey(name)) { | |
| 602 this.isPrivate = true; | |
| 603 // Since we are now making the mixin a private class, make all elements | |
| 604 // with the mixin as an owner private too. | |
| 605 entityMap.values.where((e) => e.owner == qualifiedName) | |
| 606 .forEach((element) => element.isPrivate = true); | |
| 607 // Move the subclass up to the next public superclass | |
| 608 subclasses.forEach((subclass) => addSubClass(entityMap[subclass])); | |
| 609 } | |
| 610 } | |
| 611 | |
| 549 /// Generates a map describing the [Class] object. | 612 /// Generates a map describing the [Class] object. |
| 550 Map toMap() => { | 613 Map toMap() => { |
| 551 'name': name, | 614 'name': name, |
| 552 'qualifiedname': qualifiedName, | 615 'qualifiedname': qualifiedName, |
| 553 'comment': comment, | 616 'comment': comment, |
| 554 'superclass': superclass, | 617 'superclass': superclass == null ? "" : |
| 555 'implements': new List.from(interfaces), | 618 (_includePrivate || !superclass.isPrivate) ? |
| 556 'variables': recurseMap(variables), | 619 superclass.qualifiedName : "", |
| 557 'methods': recurseMap(methods), | 620 'implements': new List.from(interfaces.where((e) => |
| 558 'annotations': new List.from(annotations), | 621 (_includePrivate || !e.isPrivate)).map((e) => e.qualifiedName)), |
| 559 'generics': recurseMap(generics) | 622 'subclass': new List.from(subclasses), |
| 560 }; | 623 'variables': recurseMap(variables), |
| 624 'inheritedvariables': recurseMap(inheritedVariables), | |
| 625 'methods': methods.toMap(), | |
| 626 'inheritedmethods': inheritedMethods.toMap(), | |
| 627 'annotations': new List.from(annotations), | |
| 628 'generics': recurseMap(generics) | |
| 629 }; | |
| 630 } | |
| 631 | |
| 632 /** | |
| 633 * A container to categorize classes into the following groups: abstract | |
| 634 * classes, regular classes, typedefs, and errors. | |
| 635 */ | |
| 636 class ClassGroup { | |
| 637 Map<String, Class> abstractClasses = {}; | |
| 638 Map<String, Class> regularClasses = {}; | |
| 639 Map<String, Typedef> typedefs = {}; | |
| 640 Map<String, Class> errors = {}; | |
| 641 | |
| 642 void addClass(ClassMirror mirror) { | |
| 643 _currentClass = mirror; | |
| 644 var clazz = _class(mirror); | |
| 645 | |
| 646 // Adding inherited superclass variables and methods. | |
| 647 if (clazz.superclass != null) { | |
| 648 if (_includePrivate || !clazz.isPrivate) { | |
| 649 clazz.superclass.addSubClass(clazz); | |
| 650 } | |
| 651 clazz.addInherited(clazz.superclass); | |
| 652 } | |
| 653 | |
| 654 // Adding inherited interface variables and methods. | |
| 655 clazz.interfaces.forEach((interface) { | |
|
Alan Knight
2013/08/01 18:27:19
The logic for superclasses and interfaces seems to
janicejl
2013/08/01 20:15:40
Done. At this point, it does not differentiate bet
| |
| 656 if (_includePrivate || !clazz.isPrivate) { | |
| 657 interface.addSubClass(clazz); | |
| 658 } | |
| 659 clazz.addInherited(interface); | |
| 660 }); | |
| 661 | |
| 662 if (isError(mirror.qualifiedName)) { | |
| 663 errors[mirror.simpleName] = clazz; | |
| 664 } else if (mirror.isTypedef) { | |
| 665 entityMap[mirror.qualifiedName] = new Typedef(mirror.simpleName, | |
| 666 mirror.value.returnType.qualifiedName, _commentToHtml(mirror), | |
| 667 _generics(mirror), _parameters(mirror.value.parameters), | |
| 668 _annotations(mirror), mirror.qualifiedName, _isPrivate(mirror), | |
| 669 mirror.owner.qualifiedName); | |
| 670 typedefs[mirror.simpleName] = entityMap[mirror.qualifiedName]; | |
| 671 } else if (mirror.isAbstract) { | |
| 672 abstractClasses[mirror.simpleName] = clazz; | |
| 673 } else if (mirror.isClass) { | |
| 674 regularClasses[mirror.simpleName] = clazz; | |
| 675 } else { | |
| 676 throw new ArgumentError('${mirror.simpleName} - no class type match. '); | |
| 677 } | |
| 678 } | |
| 679 | |
| 680 /** | |
| 681 * Checks if the given name is a key for any of the Class Maps. | |
| 682 */ | |
| 683 bool containsKey(String name) { | |
| 684 return abstractClasses.containsKey(name) || | |
| 685 regularClasses.containsKey(name) || | |
| 686 errors.containsKey(name); | |
| 687 } | |
| 688 | |
| 689 Map toMap() => { | |
| 690 'abstract': new List.from(abstractClasses.values | |
| 691 .where((e) => (_includePrivate || !e.isPrivate)) | |
|
Alan Knight
2013/08/01 18:27:19
This privacy test occurs a lot, seems like it coul
janicejl
2013/08/01 20:15:40
Done.
| |
| 692 .map((e) => e.qualifiedName)), | |
| 693 'class': new List.from(regularClasses.values | |
| 694 .where((e) => (_includePrivate || !e.isPrivate)) | |
| 695 .map((e) => e.qualifiedName)), | |
| 696 'typedef': recurseMap(typedefs), | |
| 697 'error': new List.from(errors.values | |
| 698 .where((e) => (_includePrivate || !e.isPrivate)) | |
| 699 .map((e) => e.qualifiedName)) | |
| 700 }; | |
| 561 } | 701 } |
| 562 | 702 |
| 563 class Typedef extends Indexable { | 703 class Typedef extends Indexable { |
| 564 String returnType; | 704 String returnType; |
| 565 | 705 |
| 566 Map<String, Parameter> parameters; | 706 Map<String, Parameter> parameters; |
| 567 | 707 |
| 568 /// Generic information about the typedef. | 708 /// Generic information about the typedef. |
| 569 Map<String, Generic> generics; | 709 Map<String, Generic> generics; |
| 570 | 710 |
| 571 /// List of the meta annotations on the typedef. | 711 /// List of the meta annotations on the typedef. |
| 572 List<String> annotations; | 712 List<String> annotations; |
| 573 | 713 |
| 574 Typedef(String name, this.returnType, String comment, this.generics, | 714 Typedef(String name, this.returnType, String comment, this.generics, |
| 575 this.parameters, this.annotations, | 715 this.parameters, this.annotations, |
| 576 String qualifiedName) : super(name, comment, qualifiedName) {} | 716 String qualifiedName, bool isPrivate, String owner) : super(name, comment, |
| 717 qualifiedName, isPrivate, owner) {} | |
| 577 | 718 |
| 578 Map toMap() => { | 719 Map toMap() => { |
| 579 'name': name, | 720 'name': name, |
| 580 'qualifiedname': qualifiedName, | 721 'qualifiedname': qualifiedName, |
| 581 'comment': comment, | 722 'comment': comment, |
| 582 'return': returnType, | 723 'return': returnType, |
| 583 'parameters': recurseMap(parameters), | 724 'parameters': recurseMap(parameters), |
| 584 'annotations': new List.from(annotations), | 725 'annotations': new List.from(annotations), |
| 585 'generics': recurseMap(generics) | 726 'generics': recurseMap(generics) |
| 586 }; | 727 }; |
| 587 } | 728 } |
| 588 | 729 |
| 589 /** | 730 /** |
| 590 * A class containing properties of a Dart variable. | 731 * A class containing properties of a Dart variable. |
| 591 */ | 732 */ |
| 592 class Variable extends Indexable { | 733 class Variable extends Indexable { |
| 593 | 734 |
| 594 bool isFinal; | 735 bool isFinal; |
| 595 bool isStatic; | 736 bool isStatic; |
| 596 bool isConst; | 737 bool isConst; |
| 597 Type type; | 738 Type type; |
| 598 | 739 |
| 599 /// List of the meta annotations on the variable. | 740 /// List of the meta annotations on the variable. |
| 600 List<String> annotations; | 741 List<String> annotations; |
| 601 | 742 |
| 602 Variable(String name, this.isFinal, this.isStatic, this.isConst, this.type, | 743 Variable(String name, this.isFinal, this.isStatic, this.isConst, this.type, |
| 603 String comment, this.annotations, String qualifiedName) : super(name, | 744 String comment, this.annotations, String qualifiedName, bool isPrivate, |
| 604 comment, qualifiedName); | 745 String owner) : super(name, comment, qualifiedName, isPrivate, owner); |
| 605 | 746 |
| 606 /// Generates a map describing the [Variable] object. | 747 /// Generates a map describing the [Variable] object. |
| 607 Map toMap() => { | 748 Map toMap() => { |
| 608 'name': name, | 749 'name': name, |
| 609 'qualifiedname': qualifiedName, | 750 'qualifiedname': qualifiedName, |
| 610 'comment': comment, | 751 'comment': comment, |
| 611 'final': isFinal.toString(), | 752 'final': isFinal.toString(), |
| 612 'static': isStatic.toString(), | 753 'static': isStatic.toString(), |
| 613 'constant': isConst.toString(), | 754 'constant': isConst.toString(), |
| 614 'type': new List.filled(1, type.toMap()), | 755 'type': new List.filled(1, type.toMap()), |
| 615 'annotations': new List.from(annotations) | 756 'annotations': new List.from(annotations) |
| 616 }; | 757 }; |
| 617 } | 758 } |
| 618 | 759 |
| 619 /** | 760 /** |
| 620 * A class containing properties of a Dart method. | 761 * A class containing properties of a Dart method. |
| 621 */ | 762 */ |
| 622 class Method extends Indexable { | 763 class Method extends Indexable { |
| 623 | 764 |
| 624 /// Parameters for this method. | 765 /// Parameters for this method. |
| 625 Map<String, Parameter> parameters; | 766 Map<String, Parameter> parameters; |
| 626 | 767 |
| 627 bool isStatic; | 768 bool isStatic; |
| 628 bool isAbstract; | 769 bool isAbstract; |
| 629 bool isConst; | 770 bool isConst; |
| 630 Type returnType; | 771 Type returnType; |
| 631 | 772 |
| 632 /// List of the meta annotations on the method. | 773 /// List of the meta annotations on the method. |
| 633 List<String> annotations; | 774 List<String> annotations; |
| 634 | 775 |
| 635 Method(String name, this.isStatic, this.isAbstract, this.isConst, | 776 Method(String name, this.isStatic, this.isAbstract, this.isConst, |
| 636 this.returnType, String comment, this.parameters, this.annotations, | 777 this.returnType, String comment, this.parameters, this.annotations, |
| 637 String qualifiedName) | 778 String qualifiedName, bool isPrivate, String owner) : super(name, comment, |
| 638 : super(name, comment, qualifiedName); | 779 qualifiedName, isPrivate, owner); |
| 639 | 780 |
| 640 /// Generates a map describing the [Method] object. | 781 /// Generates a map describing the [Method] object. |
| 641 Map toMap() => { | 782 Map toMap() => { |
| 642 'name': name, | 783 'name': name, |
| 643 'qualifiedname': qualifiedName, | 784 'qualifiedname': qualifiedName, |
| 644 'comment': comment, | 785 'comment': comment, |
| 645 'static': isStatic.toString(), | 786 'static': isStatic.toString(), |
| 646 'abstract': isAbstract.toString(), | 787 'abstract': isAbstract.toString(), |
| 647 'constant': isConst.toString(), | 788 'constant': isConst.toString(), |
| 648 'return': new List.filled(1, returnType.toMap()), | 789 'return': new List.filled(1, returnType.toMap()), |
| 649 'parameters': recurseMap(parameters), | 790 'parameters': recurseMap(parameters), |
| 650 'annotations': new List.from(annotations) | 791 'annotations': new List.from(annotations) |
| 651 }; | 792 }; |
| 652 } | 793 } |
| 653 | 794 |
| 654 /** | 795 /** |
| 796 * A container to categorize methods into the following groups: setters, | |
| 797 * getters, constructors, operators, regular methods. | |
| 798 */ | |
| 799 class MethodGroup { | |
| 800 Map<String, Method> setters = {}; | |
| 801 Map<String, Method> getters = {}; | |
| 802 Map<String, Method> constructors = {}; | |
| 803 Map<String, Method> operators = {}; | |
| 804 Map<String, Method> regularMethods = {}; | |
| 805 | |
| 806 void addMethod(MethodMirror mirror) { | |
| 807 var method = new Method(mirror.simpleName, mirror.isStatic, | |
| 808 mirror.isAbstract, mirror.isConstConstructor, _type(mirror.returnType), | |
| 809 _commentToHtml(mirror), _parameters(mirror.parameters), | |
| 810 _annotations(mirror), mirror.qualifiedName, _isPrivate(mirror), | |
| 811 mirror.owner.qualifiedName); | |
| 812 entityMap[mirror.qualifiedName] = method; | |
| 813 _currentMember = mirror; | |
| 814 if (mirror.isSetter) { | |
| 815 setters[mirror.simpleName] = method; | |
| 816 } else if (mirror.isGetter) { | |
| 817 getters[mirror.simpleName] = method; | |
| 818 } else if (mirror.isConstructor) { | |
| 819 constructors[mirror.simpleName] = method; | |
| 820 } else if (mirror.isOperator) { | |
| 821 operators[mirror.simpleName] = method; | |
| 822 } else if (mirror.isRegularMethod) { | |
| 823 regularMethods[mirror.simpleName] = method; | |
| 824 } else { | |
| 825 throw new ArgumentError('${mirror.simpleName} - no method type match'); | |
| 826 } | |
| 827 } | |
| 828 | |
| 829 void addInherited(Class implemented) { | |
|
Alan Knight
2013/08/01 18:27:19
Why the name implemented here?
janicejl
2013/08/01 20:15:40
A parent class. I renamed implemented to parent.
| |
| 830 setters.addAll(implemented.inheritedMethods.setters); | |
| 831 getters.addAll(implemented.inheritedMethods.getters); | |
| 832 operators.addAll(implemented.inheritedMethods.operators); | |
| 833 regularMethods.addAll(implemented.inheritedMethods.regularMethods); | |
| 834 if (_includePrivate || !implemented.isPrivate) { | |
| 835 setters.addAll(implemented.methods.setters); | |
| 836 getters.addAll(implemented.methods.getters); | |
| 837 operators.addAll(implemented.methods.operators); | |
| 838 regularMethods.addAll(implemented.methods.regularMethods); | |
| 839 } | |
| 840 } | |
| 841 | |
| 842 Map toMap() => { | |
| 843 'setters': recurseMap(setters), | |
| 844 'getters': recurseMap(getters), | |
| 845 'constructors': recurseMap(constructors), | |
| 846 'operators': recurseMap(operators), | |
| 847 'methods': recurseMap(regularMethods) | |
| 848 }; | |
| 849 } | |
| 850 | |
| 851 /** | |
| 655 * A class containing properties of a Dart method/function parameter. | 852 * A class containing properties of a Dart method/function parameter. |
| 656 */ | 853 */ |
| 657 class Parameter { | 854 class Parameter { |
| 658 | 855 |
| 659 String name; | 856 String name; |
| 660 bool isOptional; | 857 bool isOptional; |
| 661 bool isNamed; | 858 bool isNamed; |
| 662 bool hasDefaultValue; | 859 bool hasDefaultValue; |
| 663 Type type; | 860 Type type; |
| 664 String defaultValue; | 861 String defaultValue; |
| 665 | 862 |
| 666 /// List of the meta annotations on the parameter. | 863 /// List of the meta annotations on the parameter. |
| 667 List<String> annotations; | 864 List<String> annotations; |
| 668 | 865 |
| 669 Parameter(this.name, this.isOptional, this.isNamed, this.hasDefaultValue, | 866 Parameter(this.name, this.isOptional, this.isNamed, this.hasDefaultValue, |
| 670 this.type, this.defaultValue, this.annotations); | 867 this.type, this.defaultValue, this.annotations); |
| 671 | 868 |
| 672 /// Generates a map describing the [Parameter] object. | 869 /// Generates a map describing the [Parameter] object. |
| 673 Map toMap() => { | 870 Map toMap() => { |
| 674 'name': name, | 871 'name': name, |
| 675 'optional': isOptional.toString(), | 872 'optional': isOptional.toString(), |
| 676 'named': isNamed.toString(), | 873 'named': isNamed.toString(), |
| 677 'default': hasDefaultValue.toString(), | 874 'default': hasDefaultValue.toString(), |
| 678 'type': new List.filled(1, type.toMap()), | 875 'type': new List.filled(1, type.toMap()), |
| 679 'value': defaultValue, | 876 'value': defaultValue, |
| 680 'annotations': new List.from(annotations) | 877 'annotations': new List.from(annotations) |
| 681 }; | 878 }; |
| 682 } | 879 } |
| 683 | 880 |
| 684 /** | 881 /** |
| 685 * A class containing properties of a Generic. | 882 * A class containing properties of a Generic. |
| 686 */ | 883 */ |
| 687 class Generic { | 884 class Generic { |
| 688 String name; | 885 String name; |
| 689 String type; | 886 String type; |
| 690 | 887 |
| 691 Generic(this.name, this.type); | 888 Generic(this.name, this.type); |
| 692 | 889 |
| 693 Map toMap() => { | 890 Map toMap() => { |
| 694 'name': name, | 891 'name': name, |
| 695 'type': type | 892 'type': type |
| 696 }; | 893 }; |
| 697 } | 894 } |
| 698 | 895 |
| 699 /** | 896 /** |
| 700 * Holds the name of a return type, and its generic type parameters. | 897 * Holds the name of a return type, and its generic type parameters. |
| 701 * | 898 * |
| 702 * Return types are of a form [outer]<[inner]>. | 899 * Return types are of a form [outer]<[inner]>. |
| 703 * If there is no [inner] part, [inner] will be an empty list. | 900 * If there is no [inner] part, [inner] will be an empty list. |
| 704 * | 901 * |
| 705 * For example: | 902 * For example: |
| 706 * int size() | 903 * int size() |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 726 * - "outer" : "dart.core.int" | 923 * - "outer" : "dart.core.int" |
| 727 * "inner" : | 924 * "inner" : |
| 728 */ | 925 */ |
| 729 class Type { | 926 class Type { |
| 730 String outer; | 927 String outer; |
| 731 List<Type> inner; | 928 List<Type> inner; |
| 732 | 929 |
| 733 Type(this.outer, this.inner); | 930 Type(this.outer, this.inner); |
| 734 | 931 |
| 735 Map toMap() => { | 932 Map toMap() => { |
| 736 'outer': outer, | 933 'outer': outer, |
| 737 'inner': new List.from(inner.map((e) => e.toMap())) | 934 'inner': new List.from(inner.map((e) => e.toMap())) |
| 738 }; | 935 }; |
| 739 } | 936 } |
| OLD | NEW |