| OLD | NEW |
| (Empty) |
| 1 /** | |
| 2 * The docgen tool takes in a library as input and produces documentation | |
| 3 * for the library as well as all libraries it imports and uses. The tool can | |
| 4 * be run by passing in the path to a .dart file like this: | |
| 5 * | |
| 6 * ./dart docgen.dart path/to/file.dart | |
| 7 * | |
| 8 * This outputs information about all classes, variables, functions, and | |
| 9 * methods defined in the library and its imported libraries. | |
| 10 */ | |
| 11 library docgen; | |
| 12 | |
| 13 import 'dart:io'; | |
| 14 import 'dart:async'; | |
| 15 import 'lib/dart2yaml.dart'; | |
| 16 import 'lib/src/dart2js_mirrors.dart'; | |
| 17 import 'package:markdown/markdown.dart' as markdown; | |
| 18 import '../../../../pkg/args/lib/args.dart'; | |
| 19 import '../compiler/implementation/mirrors/mirrors.dart'; | |
| 20 import '../compiler/implementation/mirrors/mirrors_util.dart'; | |
| 21 | |
| 22 /** | |
| 23 * Entry function to create YAML documentation from Dart files. | |
| 24 */ | |
| 25 void main() { | |
| 26 // TODO(tmandel): Use args library once flags are clear. | |
| 27 Options opts = new Options(); | |
| 28 Docgen docgen = new Docgen(); | |
| 29 | |
| 30 if (opts.arguments.length > 0) { | |
| 31 List<Path> libraries = [new Path(opts.arguments[0])]; | |
| 32 Path sdkDirectory = new Path("../../../"); | |
| 33 var workingMirrors = analyze(libraries, sdkDirectory, | |
| 34 options: ['--preserve-comments', '--categories=Client,Server']); | |
| 35 workingMirrors.then( (MirrorSystem mirrorSystem) { | |
| 36 var mirrors = mirrorSystem.libraries.values; | |
| 37 if (mirrors.isEmpty) { | |
| 38 print("no LibraryMirrors"); | |
| 39 } else { | |
| 40 docgen.libraries = mirrors; | |
| 41 docgen.documentLibraries(); | |
| 42 } | |
| 43 }); | |
| 44 } | |
| 45 } | |
| 46 | |
| 47 /** | |
| 48 * This class documents a list of libraries. | |
| 49 */ | |
| 50 class Docgen { | |
| 51 | |
| 52 /// Libraries to be documented. | |
| 53 List<LibraryMirror> _libraries; | |
| 54 | |
| 55 /// Saves list of libraries for Docgen object. | |
| 56 void set libraries(value) => _libraries = value; | |
| 57 | |
| 58 /// Current library being documented to be used for comment links. | |
| 59 LibraryMirror _currentLibrary; | |
| 60 | |
| 61 /// Current class being documented to be used for comment links. | |
| 62 ClassMirror _currentClass; | |
| 63 | |
| 64 /// Current member being documented to be used for comment links. | |
| 65 MemberMirror _currentMember; | |
| 66 | |
| 67 /** | |
| 68 * Creates documentation for filtered libraries. | |
| 69 */ | |
| 70 void documentLibraries() { | |
| 71 //TODO(tmandel): Filter libraries and determine output type using flags. | |
| 72 _libraries.forEach((library) { | |
| 73 _currentLibrary = library; | |
| 74 var result = new Library(library.qualifiedName, _getComment(library), | |
| 75 _getVariables(library.variables), _getMethods(library.functions), | |
| 76 _getClasses(library.classes)); | |
| 77 _writeToFile(getYamlString(result.toMap()), "${result.name}.yaml"); | |
| 78 }); | |
| 79 } | |
| 80 | |
| 81 /** | |
| 82 * Returns any documentation comments associated with a mirror with | |
| 83 * simple markdown converted to html. | |
| 84 */ | |
| 85 String _getComment(DeclarationMirror mirror) { | |
| 86 String commentText; | |
| 87 mirror.metadata.forEach((metadata) { | |
| 88 if (metadata is CommentInstanceMirror) { | |
| 89 CommentInstanceMirror comment = metadata; | |
| 90 if (comment.isDocComment) { | |
| 91 if (commentText == null) { | |
| 92 commentText = comment.trimmedText; | |
| 93 } else { | |
| 94 commentText = "$commentText ${comment.trimmedText}"; | |
| 95 } | |
| 96 } | |
| 97 } | |
| 98 }); | |
| 99 // TODO(tmandel): Resolve links to members in markdown using _currentClass, | |
| 100 // _currentMember, and _currentLibrary. | |
| 101 return commentText == null ? "" : | |
| 102 markdown.markdownToHtml(commentText.trim()); | |
| 103 } | |
| 104 | |
| 105 /** | |
| 106 * Returns a map of [Variable] objects constructed from inputted mirrors. | |
| 107 */ | |
| 108 Map<String, Variable> _getVariables(Map<String, VariableMirror> mirrorMap) { | |
| 109 var data = {}; | |
| 110 mirrorMap.forEach((String mirrorName, VariableMirror mirror) { | |
| 111 _currentMember = mirror; | |
| 112 data[mirrorName] = new Variable(mirrorName, mirror.isFinal, | |
| 113 mirror.isStatic, mirror.type.toString(), _getComment(mirror)); | |
| 114 }); | |
| 115 return data; | |
| 116 } | |
| 117 | |
| 118 /** | |
| 119 * Returns a map of [Method] objects constructed from inputted mirrors. | |
| 120 */ | |
| 121 Map<String, Method> _getMethods(Map<String, MethodMirror> mirrorMap) { | |
| 122 var data = {}; | |
| 123 mirrorMap.forEach((String mirrorName, MethodMirror mirror) { | |
| 124 _currentMember = mirror; | |
| 125 data[mirrorName] = new Method(mirrorName, mirror.isSetter, | |
| 126 mirror.isGetter, mirror.isConstructor, mirror.isOperator, | |
| 127 mirror.isStatic, mirror.returnType.toString(), _getComment(mirror), | |
| 128 _getParameters(mirror.parameters)); | |
| 129 }); | |
| 130 return data; | |
| 131 } | |
| 132 | |
| 133 /** | |
| 134 * Returns a map of [Class] objects constructed from inputted mirrors. | |
| 135 */ | |
| 136 Map<String, Class> _getClasses(Map<String, ClassMirror> mirrorMap) { | |
| 137 var data = {}; | |
| 138 mirrorMap.forEach((String mirrorName, ClassMirror mirror) { | |
| 139 _currentClass = mirror; | |
| 140 var superclass; | |
| 141 if (mirror.superclass != null) { | |
| 142 superclass = mirror.superclass.qualifiedName; | |
| 143 } | |
| 144 var interfaces = | |
| 145 mirror.superinterfaces.map((interface) => interface.qualifiedName); | |
| 146 data[mirrorName] = new Class(mirrorName, superclass, mirror.isAbstract, | |
| 147 mirror.isTypedef, _getComment(mirror), interfaces, | |
| 148 _getVariables(mirror.variables), _getMethods(mirror.methods)); | |
| 149 }); | |
| 150 return data; | |
| 151 } | |
| 152 | |
| 153 /** | |
| 154 * Returns a map of [Parameter] objects constructed from inputted mirrors. | |
| 155 */ | |
| 156 Map<String, Parameter> _getParameters(List<ParameterMirror> mirrorList) { | |
| 157 var data = {}; | |
| 158 mirrorList.forEach((ParameterMirror mirror) { | |
| 159 _currentMember = mirror; | |
| 160 data[mirror.simpleName] = new Parameter(mirror.simpleName, | |
| 161 mirror.isOptional, mirror.isNamed, mirror.hasDefaultValue, | |
| 162 mirror.type.toString(), mirror.defaultValue); | |
| 163 }); | |
| 164 return data; | |
| 165 } | |
| 166 } | |
| 167 | |
| 168 /** | |
| 169 * Transforms the map by calling toMap on each value in it. | |
| 170 */ | |
| 171 Map recurseMap(Map inputMap) { | |
| 172 var outputMap = {}; | |
| 173 inputMap.forEach((key, value) { | |
| 174 outputMap[key] = value.toMap(); | |
| 175 }); | |
| 176 return outputMap; | |
| 177 } | |
| 178 | |
| 179 /** | |
| 180 * A class containing contents of a Dart library. | |
| 181 */ | |
| 182 class Library { | |
| 183 | |
| 184 /// Documentation comment with converted markdown. | |
| 185 String comment; | |
| 186 | |
| 187 /// Top-level variables in the library. | |
| 188 Map<String, Variable> variables; | |
| 189 | |
| 190 /// Top-level functions in the library. | |
| 191 Map<String, Method> functions; | |
| 192 | |
| 193 /// Classes defined within the library | |
| 194 Map<String, Class> classes; | |
| 195 | |
| 196 String name; | |
| 197 | |
| 198 Library(this.name, this.comment, this.variables, | |
| 199 this.functions, this.classes); | |
| 200 | |
| 201 /// Generates a map describing the [Library] object. | |
| 202 Map toMap() { | |
| 203 var libraryMap = {}; | |
| 204 libraryMap["name"] = name; | |
| 205 libraryMap["comment"] = comment; | |
| 206 libraryMap["variables"] = recurseMap(variables); | |
| 207 libraryMap["functions"] = recurseMap(functions); | |
| 208 libraryMap["classes"] = recurseMap(classes); | |
| 209 return libraryMap; | |
| 210 } | |
| 211 } | |
| 212 | |
| 213 /** | |
| 214 * A class containing contents of a Dart class. | |
| 215 */ | |
| 216 // TODO(tmandel): Figure out how to do typedefs (what is needed) | |
| 217 class Class { | |
| 218 | |
| 219 /// Documentation comment with converted markdown. | |
| 220 String comment; | |
| 221 | |
| 222 /// List of the names of interfaces that this class implements. | |
| 223 List<String> interfaces; | |
| 224 | |
| 225 /// Top-level variables in the class. | |
| 226 Map<String, Variable> variables; | |
| 227 | |
| 228 /// Methods in the class. | |
| 229 Map<String, Method> methods; | |
| 230 | |
| 231 String name; | |
| 232 String superclass; | |
| 233 bool isAbstract; | |
| 234 bool isTypedef; | |
| 235 | |
| 236 Class(this.name, this.superclass, this.isAbstract, this.isTypedef, | |
| 237 this.comment, this.interfaces, this.variables, this.methods); | |
| 238 | |
| 239 /// Generates a map describing the [Class] object. | |
| 240 Map toMap() { | |
| 241 var classMap = {}; | |
| 242 classMap["name"] = name; | |
| 243 classMap["comment"] = comment; | |
| 244 classMap["superclass"] = superclass; | |
| 245 classMap["abstract"] = isAbstract; | |
| 246 classMap["typedef"] = isTypedef; | |
| 247 classMap["implements"] = interfaces; | |
| 248 classMap["variables"] = recurseMap(variables); | |
| 249 classMap["methods"] = recurseMap(methods); | |
| 250 return classMap; | |
| 251 } | |
| 252 } | |
| 253 | |
| 254 /** | |
| 255 * A class containing properties of a Dart variable. | |
| 256 */ | |
| 257 class Variable { | |
| 258 | |
| 259 /// Documentation comment with converted markdown. | |
| 260 String comment; | |
| 261 | |
| 262 String name; | |
| 263 bool isFinal; | |
| 264 bool isStatic; | |
| 265 String type; | |
| 266 | |
| 267 Variable(this.name, this.isFinal, this.isStatic, this.type, this.comment); | |
| 268 | |
| 269 /// Generates a map describing the [Variable] object. | |
| 270 Map toMap() { | |
| 271 var variableMap = {}; | |
| 272 variableMap["name"] = name; | |
| 273 variableMap["comment"] = comment; | |
| 274 variableMap["final"] = isFinal; | |
| 275 variableMap["static"] = isStatic; | |
| 276 variableMap["type"] = type; | |
| 277 return variableMap; | |
| 278 } | |
| 279 } | |
| 280 | |
| 281 /** | |
| 282 * A class containing properties of a Dart method. | |
| 283 */ | |
| 284 class Method { | |
| 285 | |
| 286 /// Documentation comment with converted markdown. | |
| 287 String comment; | |
| 288 | |
| 289 /// Parameters for this method. | |
| 290 Map<String, Parameter> parameters; | |
| 291 | |
| 292 String name; | |
| 293 bool isSetter; | |
| 294 bool isGetter; | |
| 295 bool isConstructor; | |
| 296 bool isOperator; | |
| 297 bool isStatic; | |
| 298 String returnType; | |
| 299 | |
| 300 Method(this.name, this.isSetter, this.isGetter, this.isConstructor, | |
| 301 this.isOperator, this.isStatic, this.returnType, this.comment, | |
| 302 this.parameters); | |
| 303 | |
| 304 /// Generates a map describing the [Method] object. | |
| 305 Map toMap() { | |
| 306 var methodMap = {}; | |
| 307 methodMap["name"] = name; | |
| 308 methodMap["comment"] = comment; | |
| 309 methodMap["type"] = isSetter ? "Setter" : isGetter ? "Getter" : | |
| 310 isOperator ? "Operator" : isConstructor ? "Constructor" : "Method"; | |
| 311 methodMap["static"] = isStatic; | |
| 312 methodMap["return"] = returnType; | |
| 313 methodMap["parameters"] = recurseMap(parameters); | |
| 314 return methodMap; | |
| 315 } | |
| 316 } | |
| 317 | |
| 318 /** | |
| 319 * A class containing properties of a Dart method/function parameter. | |
| 320 */ | |
| 321 class Parameter { | |
| 322 | |
| 323 String name; | |
| 324 bool isOptional; | |
| 325 bool isNamed; | |
| 326 bool hasDefaultValue; | |
| 327 String type; | |
| 328 String defaultValue; | |
| 329 | |
| 330 Parameter(this.name, this.isOptional, this.isNamed, this.hasDefaultValue, | |
| 331 this.type, this.defaultValue); | |
| 332 | |
| 333 /// Generates a map describing the [Parameter] object. | |
| 334 Map toMap() { | |
| 335 var parameterMap = {}; | |
| 336 parameterMap["name"] = name; | |
| 337 parameterMap["optional"] = isOptional; | |
| 338 parameterMap["default"] = hasDefaultValue; | |
| 339 parameterMap["type"] = type; | |
| 340 parameterMap["value"] = defaultValue; | |
| 341 return parameterMap; | |
| 342 } | |
| 343 } | |
| 344 | |
| 345 /** | |
| 346 * Writes text to a file in the 'docs' directory. | |
| 347 */ | |
| 348 void _writeToFile(String text, String filename) { | |
| 349 Directory dir = new Directory('docs'); | |
| 350 if (!dir.existsSync()) { | |
| 351 dir.createSync(); | |
| 352 } | |
| 353 File file = new File('docs/$filename'); | |
| 354 if (!file.exists()) { | |
| 355 file.createSync(); | |
| 356 } | |
| 357 file.openSync(); | |
| 358 file.writeAsString(text); | |
| 359 } | |
| OLD | NEW |