OLD | NEW |
(Empty) | |
| 1 /** |
| 2 * A library for extracting the documentation from the various HTML libraries |
| 3 * ([dart:html], [dart:svg], [dart:web_audio], [dart:indexed_db]) and saving |
| 4 * those documentation comments to a JSON file. |
| 5 */ |
| 6 |
| 7 library docs; |
| 8 |
| 9 import '../../../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors.da
rt'; |
| 10 import '../../../../sdk/lib/_internal/dartdoc/lib/src/json_serializer.dart'; |
| 11 import '../../../../sdk/lib/_internal/dartdoc/lib/dartdoc.dart'; |
| 12 import '../../../../utils/apidoc/lib/metadata.dart'; |
| 13 import 'dart:async'; |
| 14 import 'dart:io'; |
| 15 |
| 16 /// The various HTML libraries. |
| 17 const List<String> HTML_LIBRARY_NAMES = const ['dart:html', |
| 18 'dart:svg', |
| 19 'dart:web_audio', |
| 20 'dart:indexed_db']; |
| 21 /** |
| 22 * Converts the libraries in [HTML_LIBRARY_NAMES] to a json file at [jsonPath] |
| 23 * given the library path at [libPath]. |
| 24 * |
| 25 * The json output looks like: |
| 26 * { |
| 27 * $library_name: { |
| 28 * $interface_name: { |
| 29 * comment: "$comment" |
| 30 * members: { |
| 31 * $member: "$comment", |
| 32 * ... |
| 33 * } |
| 34 * }, |
| 35 * ... |
| 36 * }, |
| 37 * ... |
| 38 * } |
| 39 * |
| 40 * Returns `true` if any errors were encountered, `false` otherwise. |
| 41 */ |
| 42 bool convert(Path libPath, Path jsonPath) { |
| 43 var paths = <Path>[]; |
| 44 for (var libraryName in HTML_LIBRARY_NAMES) { |
| 45 paths.add(new Path(libraryName)); |
| 46 } |
| 47 |
| 48 // TODO(amouravski): Account for errors in compilation. |
| 49 final compilation = new Compilation.library(paths, libPath, null, |
| 50 ['--preserve-comments']); |
| 51 |
| 52 var convertedJson = _generateJsonFromLibraries(compilation); |
| 53 |
| 54 var anyErrors = _exportJsonToFile(convertedJson, jsonPath); |
| 55 |
| 56 return anyErrors; |
| 57 } |
| 58 |
| 59 bool _exportJsonToFile(Map convertedJson, Path jsonPath) { |
| 60 final jsonFile = new File.fromPath(jsonPath); |
| 61 var writeJson = prettySerialize(convertedJson); |
| 62 |
| 63 var outputStream = jsonFile.openOutputStream(); |
| 64 outputStream.writeString(writeJson); |
| 65 |
| 66 return false; |
| 67 } |
| 68 |
| 69 Map _generateJsonFromLibraries(Compilation compilation) { |
| 70 var convertedJson = {}; |
| 71 |
| 72 // Sort the libraries by name (not key). |
| 73 var sortedLibraries = new List<LibraryMirror>.from( |
| 74 compilation.mirrors.libraries.values.where( |
| 75 (e) => HTML_LIBRARY_NAMES.indexOf(e.uri.toString()) >= 0)) |
| 76 ..sort((x, y) => |
| 77 x.uri.toString().toUpperCase().compareTo( |
| 78 y.uri.toString().toUpperCase())); |
| 79 |
| 80 for (LibraryMirror libMirror in sortedLibraries) { |
| 81 print('Extracting documentation from ${libMirror.displayName}.'); |
| 82 |
| 83 var libraryJson = {}; |
| 84 var sortedClasses = _sortAndFilterMirrors( |
| 85 libMirror.classes.values.toList()); |
| 86 |
| 87 for (ClassMirror classMirror in sortedClasses) { |
| 88 var classJson = {}; |
| 89 var sortedMembers = _sortAndFilterMirrors( |
| 90 classMirror.members.values.toList()); |
| 91 |
| 92 var membersJson = {}; |
| 93 for (var memberMirror in sortedMembers) { |
| 94 var memberDomName = domNames(memberMirror)[0]; |
| 95 var memberComment = computeComment(memberMirror); |
| 96 if (memberComment != null) { |
| 97 membersJson.putIfAbsent(memberDomName, () => memberComment); |
| 98 } |
| 99 } |
| 100 |
| 101 var classComment = computeComment(classMirror); |
| 102 if (classComment != null) { |
| 103 classJson.putIfAbsent('comment', () => classComment); |
| 104 } |
| 105 if (!membersJson.isEmpty) { |
| 106 classJson.putIfAbsent('members', () => |
| 107 membersJson); |
| 108 } |
| 109 |
| 110 if (!classJson.isEmpty) { |
| 111 libraryJson.putIfAbsent(domNames(classMirror)[0], () => |
| 112 classJson); |
| 113 } |
| 114 } |
| 115 |
| 116 if (!libraryJson.isEmpty) { |
| 117 convertedJson.putIfAbsent(libMirror.displayName, () => |
| 118 libraryJson); |
| 119 } |
| 120 } |
| 121 |
| 122 return convertedJson; |
| 123 } |
| 124 |
| 125 List<DeclarationMirror> _sortAndFilterMirrors(List<DeclarationMirror> mirrors) { |
| 126 // Filter out mirrors that are private, or which are not part of this docs |
| 127 // process. That is, ones without the DocsEditable annotation. |
| 128 var filteredMirrors = mirrors.where((DeclarationMirror c) => |
| 129 !domNames(c).isEmpty && |
| 130 !c.displayName.startsWith('_') && |
| 131 (findMetadata(c.metadata, 'DocsEditable') != null)) |
| 132 .toList(); |
| 133 |
| 134 filteredMirrors.sort((x, y) => |
| 135 domNames(x)[0].toUpperCase().compareTo( |
| 136 domNames(y)[0].toUpperCase())); |
| 137 |
| 138 return filteredMirrors; |
| 139 } |
| 140 |
| 141 /// Given the class mirror, returns the names found or an empty list. |
| 142 List<String> domNames(DeclarationMirror mirror) { |
| 143 var domNameMetadata = findMetadata(mirror.metadata, 'DomName'); |
| 144 |
| 145 if (domNameMetadata != null) { |
| 146 var domNames = <String>[]; |
| 147 var tags = deprecatedFutureValue(domNameMetadata.getField('name')); |
| 148 for (var s in tags.reflectee.split(',')) { |
| 149 domNames.add(s.trim()); |
| 150 } |
| 151 |
| 152 if (domNames.length == 1 && domNames[0] == 'none') return <String>[]; |
| 153 return domNames; |
| 154 } else { |
| 155 return <String>[]; |
| 156 } |
| 157 } |
OLD | NEW |