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 * A library for extracting the documentation from the various HTML libraries | 6 * A library for extracting the documentation from the various HTML libraries |
7 * ([dart:html], [dart:svg], [dart:web_audio], [dart:indexed_db]) and saving | 7 * ([dart:html], [dart:svg], [dart:web_audio], [dart:indexed_db]) and saving |
8 * those documentation comments to a JSON file. | 8 * those documentation comments to a JSON file. |
9 */ | 9 */ |
10 | 10 |
11 library docs; | 11 library docs; |
12 | 12 |
13 import '../../../../sdk/lib/_internal/dartdoc/lib/src/dart2js_mirrors.dart'; | 13 import '../../../../sdk/lib/_internal/dartdoc/lib/src/dart2js_mirrors.dart'; |
14 import '../../../../pkg/compiler/lib/src/mirrors/source_mirrors.dart'; | 14 import '../../../../pkg/compiler/lib/src/mirrors/source_mirrors.dart'; |
15 import '../../../../pkg/compiler/lib/src/mirrors/mirrors_util.dart'; | 15 import '../../../../pkg/compiler/lib/src/mirrors/mirrors_util.dart'; |
16 import '../../../../sdk/lib/_internal/dartdoc/lib/dartdoc.dart'; | 16 import '../../../../sdk/lib/_internal/dartdoc/lib/dartdoc.dart'; |
17 import '../../../../sdk/lib/_internal/dartdoc/lib/src/json_serializer.dart'; | 17 import '../../../../sdk/lib/_internal/dartdoc/lib/src/json_serializer.dart'; |
18 import '../../../../utils/apidoc/lib/metadata.dart'; | 18 import '../../../../utils/apidoc/lib/metadata.dart'; |
19 import 'dart:async'; | 19 import 'dart:async'; |
20 import 'dart:io'; | 20 import 'dart:io'; |
21 | 21 |
22 /// The various HTML libraries. | 22 /// The various HTML libraries. |
23 const List<String> HTML_LIBRARY_NAMES = const ['dart:html', | 23 const List<String> HTML_LIBRARY_NAMES = const [ |
24 'dart:indexed_db', | 24 'dart:html', |
25 'dart:svg', | 25 'dart:indexed_db', |
26 'dart:web_audio', | 26 'dart:svg', |
27 'dart:web_gl', | 27 'dart:web_audio', |
28 'dart:web_sql']; | 28 'dart:web_gl', |
| 29 'dart:web_sql' |
| 30 ]; |
29 /** | 31 /** |
30 * Converts the libraries in [HTML_LIBRARY_NAMES] to a json file at [jsonPath] | 32 * Converts the libraries in [HTML_LIBRARY_NAMES] to a json file at [jsonPath] |
31 * given the library path at [libUri]. | 33 * given the library path at [libUri]. |
32 * | 34 * |
33 * The json output looks like: | 35 * The json output looks like: |
34 * { | 36 * { |
35 * $library_name: { | 37 * $library_name: { |
36 * $interface_name: { | 38 * $interface_name: { |
37 * comment: "$comment" | 39 * comment: "$comment" |
38 * members: { | 40 * members: { |
(...skipping 13 matching lines...) Expand all Loading... |
52 * | 54 * |
53 * Completes to true if any errors were encountered, false otherwise. | 55 * Completes to true if any errors were encountered, false otherwise. |
54 */ | 56 */ |
55 Future<bool> convert(String libUri, String jsonPath) { | 57 Future<bool> convert(String libUri, String jsonPath) { |
56 var paths = <String>[]; | 58 var paths = <String>[]; |
57 for (var libraryName in HTML_LIBRARY_NAMES) { | 59 for (var libraryName in HTML_LIBRARY_NAMES) { |
58 paths.add(libraryName); | 60 paths.add(libraryName); |
59 } | 61 } |
60 | 62 |
61 return analyze(paths, libUri, options: ['--preserve-comments']) | 63 return analyze(paths, libUri, options: ['--preserve-comments']) |
62 .then((MirrorSystem mirrors) { | 64 .then((MirrorSystem mirrors) { |
63 var convertedJson = _generateJsonFromLibraries(mirrors); | 65 var convertedJson = _generateJsonFromLibraries(mirrors); |
64 return _exportJsonToFile(convertedJson, jsonPath); | 66 return _exportJsonToFile(convertedJson, jsonPath); |
65 }); | 67 }); |
66 } | 68 } |
67 | 69 |
68 Future<bool> _exportJsonToFile(Map convertedJson, String jsonPath) { | 70 Future<bool> _exportJsonToFile(Map convertedJson, String jsonPath) { |
69 return new Future.sync(() { | 71 return new Future.sync(() { |
70 final jsonFile = new File(jsonPath); | 72 final jsonFile = new File(jsonPath); |
71 var writeJson = prettySerialize(convertedJson); | 73 var writeJson = prettySerialize(convertedJson); |
72 | 74 |
73 var outputStream = jsonFile.openWrite(); | 75 var outputStream = jsonFile.openWrite(); |
74 outputStream.writeln(writeJson); | 76 outputStream.writeln(writeJson); |
75 outputStream.close(); | 77 outputStream.close(); |
76 return outputStream.done.then((_) => false); | 78 return outputStream.done.then((_) => false); |
77 }); | 79 }); |
78 } | 80 } |
79 | 81 |
80 Map _generateJsonFromLibraries(MirrorSystem mirrors) { | 82 Map _generateJsonFromLibraries(MirrorSystem mirrors) { |
81 var convertedJson = {}; | 83 var convertedJson = {}; |
82 | 84 |
83 // Sort the libraries by name (not key). | 85 // Sort the libraries by name (not key). |
84 var sortedLibraries = new List<LibraryMirror>.from( | 86 var sortedLibraries = new List<LibraryMirror>.from(mirrors.libraries.values |
85 mirrors.libraries.values.where( | 87 .where((e) => HTML_LIBRARY_NAMES.indexOf(e.uri.toString()) >= 0)) |
86 (e) => HTML_LIBRARY_NAMES.indexOf(e.uri.toString()) >= 0)) | 88 ..sort((x, y) => x.uri |
87 ..sort((x, y) => | 89 .toString() |
88 x.uri.toString().toUpperCase().compareTo( | 90 .toUpperCase() |
89 y.uri.toString().toUpperCase())); | 91 .compareTo(y.uri.toString().toUpperCase())); |
90 | 92 |
91 for (LibraryMirror libMirror in sortedLibraries) { | 93 for (LibraryMirror libMirror in sortedLibraries) { |
92 print('Extracting documentation from ${libMirror.simpleName}.'); | 94 print('Extracting documentation from ${libMirror.simpleName}.'); |
93 | 95 |
94 var libraryJson = {}; | 96 var libraryJson = {}; |
95 var sortedClasses = _sortAndFilterMirrors( | 97 var sortedClasses = _sortAndFilterMirrors( |
96 classesOf(libMirror.declarations).toList(), ignoreDocsEditable: true); | 98 classesOf(libMirror.declarations).toList(), |
| 99 ignoreDocsEditable: true); |
97 | 100 |
98 for (ClassMirror classMirror in sortedClasses) { | 101 for (ClassMirror classMirror in sortedClasses) { |
99 print(' class: $classMirror'); | 102 print(' class: $classMirror'); |
100 var classJson = {}; | 103 var classJson = {}; |
101 var sortedMembers = _sortAndFilterMirrors( | 104 var sortedMembers = |
102 membersOf(classMirror.declarations).toList()); | 105 _sortAndFilterMirrors(membersOf(classMirror.declarations).toList()); |
103 | 106 |
104 var membersJson = {}; | 107 var membersJson = {}; |
105 for (var memberMirror in sortedMembers) { | 108 for (var memberMirror in sortedMembers) { |
106 print(' member: $memberMirror'); | 109 print(' member: $memberMirror'); |
107 var memberDomName = domNames(memberMirror)[0]; | 110 var memberDomName = domNames(memberMirror)[0]; |
108 var memberComment = _splitCommentsByNewline( | 111 var memberComment = _splitCommentsByNewline( |
109 computeUntrimmedCommentAsList(memberMirror)); | 112 computeUntrimmedCommentAsList(memberMirror)); |
110 | 113 |
111 // Remove interface name from Dom Name. | 114 // Remove interface name from Dom Name. |
112 if (memberDomName.indexOf('.') >= 0) { | 115 if (memberDomName.indexOf('.') >= 0) { |
113 memberDomName = | 116 memberDomName = |
114 memberDomName.substring(memberDomName.indexOf('.') + 1); | 117 memberDomName.substring(memberDomName.indexOf('.') + 1); |
115 } | 118 } |
116 | 119 |
117 if (!memberComment.isEmpty) { | 120 if (!memberComment.isEmpty) { |
118 membersJson.putIfAbsent(memberDomName, () => memberComment); | 121 membersJson.putIfAbsent(memberDomName, () => memberComment); |
119 } | 122 } |
120 } | 123 } |
121 | 124 |
122 // Only include the comment if DocsEditable is set. | 125 // Only include the comment if DocsEditable is set. |
123 var classComment = _splitCommentsByNewline( | 126 var classComment = |
124 computeUntrimmedCommentAsList(classMirror)); | 127 _splitCommentsByNewline(computeUntrimmedCommentAsList(classMirror)); |
125 if (!classComment.isEmpty && | 128 if (!classComment.isEmpty && |
126 findMetadata(classMirror.metadata, 'DocsEditable') != null) { | 129 findMetadata(classMirror.metadata, 'DocsEditable') != null) { |
127 classJson.putIfAbsent('comment', () => classComment); | 130 classJson.putIfAbsent('comment', () => classComment); |
128 } | 131 } |
129 if (!membersJson.isEmpty) { | 132 if (!membersJson.isEmpty) { |
130 classJson.putIfAbsent('members', () => | 133 classJson.putIfAbsent('members', () => membersJson); |
131 membersJson); | |
132 } | 134 } |
133 | 135 |
134 if (!classJson.isEmpty) { | 136 if (!classJson.isEmpty) { |
135 libraryJson.putIfAbsent(domNames(classMirror)[0], () => | 137 libraryJson.putIfAbsent(domNames(classMirror)[0], () => classJson); |
136 classJson); | |
137 } | 138 } |
138 } | 139 } |
139 | 140 |
140 if (!libraryJson.isEmpty) { | 141 if (!libraryJson.isEmpty) { |
141 convertedJson.putIfAbsent(nameOf(libMirror), () => | 142 convertedJson.putIfAbsent(nameOf(libMirror), () => libraryJson); |
142 libraryJson); | |
143 } | 143 } |
144 } | 144 } |
145 | 145 |
146 return convertedJson; | 146 return convertedJson; |
147 } | 147 } |
148 | 148 |
149 /// Filter out mirrors that are private, or which are not part of this docs | 149 /// Filter out mirrors that are private, or which are not part of this docs |
150 /// process. That is, ones without the DocsEditable annotation. | 150 /// process. That is, ones without the DocsEditable annotation. |
151 /// If [ignoreDocsEditable] is true, relax the restriction on @DocsEditable(). | 151 /// If [ignoreDocsEditable] is true, relax the restriction on @DocsEditable(). |
152 /// This is to account for classes that are defined in a template, but whose | 152 /// This is to account for classes that are defined in a template, but whose |
153 /// members are generated. | 153 /// members are generated. |
154 List<DeclarationMirror> _sortAndFilterMirrors(List<DeclarationMirror> mirrors, | 154 List<DeclarationMirror> _sortAndFilterMirrors(List<DeclarationMirror> mirrors, |
155 {ignoreDocsEditable: false}) { | 155 {ignoreDocsEditable: false}) { |
156 | 156 var filteredMirrors = mirrors |
157 var filteredMirrors = mirrors.where((DeclarationMirror c) => | 157 .where((DeclarationMirror c) => |
158 !domNames(c).isEmpty && | 158 !domNames(c).isEmpty && |
159 !displayName(c).startsWith('_') && | 159 !displayName(c).startsWith('_') && |
160 (!ignoreDocsEditable ? (findMetadata(c.metadata, 'DocsEditable') != null) | 160 (!ignoreDocsEditable |
161 : true)) | 161 ? (findMetadata(c.metadata, 'DocsEditable') != null) |
| 162 : true)) |
162 .toList(); | 163 .toList(); |
163 | 164 |
164 filteredMirrors.sort((x, y) => | 165 filteredMirrors.sort((x, y) => |
165 domNames(x)[0].toUpperCase().compareTo( | 166 domNames(x)[0].toUpperCase().compareTo(domNames(y)[0].toUpperCase())); |
166 domNames(y)[0].toUpperCase())); | |
167 | 167 |
168 return filteredMirrors; | 168 return filteredMirrors; |
169 } | 169 } |
170 | 170 |
171 List<String> _splitCommentsByNewline(List<String> comments) { | 171 List<String> _splitCommentsByNewline(List<String> comments) { |
172 var out = []; | 172 var out = []; |
173 | 173 |
174 comments.forEach((c) { | 174 comments.forEach((c) { |
175 out.addAll(c.split(new RegExp('\n'))); | 175 out.addAll(c.split(new RegExp('\n'))); |
176 }); | 176 }); |
(...skipping 11 matching lines...) Expand all Loading... |
188 for (var s in tags.reflectee.split(',')) { | 188 for (var s in tags.reflectee.split(',')) { |
189 domNames.add(s.trim()); | 189 domNames.add(s.trim()); |
190 } | 190 } |
191 | 191 |
192 if (domNames.length == 1 && domNames[0] == 'none') return <String>[]; | 192 if (domNames.length == 1 && domNames[0] == 'none') return <String>[]; |
193 return domNames; | 193 return domNames; |
194 } else { | 194 } else { |
195 return <String>[]; | 195 return <String>[]; |
196 } | 196 } |
197 } | 197 } |
OLD | NEW |