| Index: pkg/docgen/bin/docgen.dart
|
| diff --git a/pkg/docgen/bin/docgen.dart b/pkg/docgen/bin/docgen.dart
|
| index ff16b0d9ea30dce2ca429b8ff96a87ed5da801a4..308df289271e71bab2ec5e94b542b2fccffffff0 100644
|
| --- a/pkg/docgen/bin/docgen.dart
|
| +++ b/pkg/docgen/bin/docgen.dart
|
| @@ -2,20 +2,392 @@
|
| // for details. All rights reserved. Use of this source code is governed by a
|
| // BSD-style license that can be found in the LICENSE file.
|
|
|
| -import 'dart:io';
|
| -
|
| -import 'package:args/args.dart';
|
| -import 'package:logging/logging.dart';
|
| +/**
|
| + * The docgen tool takes in a library as input and produces documentation
|
| + * for the library as well as all libraries it imports and uses. The tool can
|
| + * be run by passing in the path to a .dart file like this:
|
| + *
|
| + * ./dart docgen.dart path/to/file.dart
|
| + *
|
| + * This outputs information about all classes, variables, functions, and
|
| + * methods defined in the library and its imported libraries.
|
| + */
|
| +library docgen;
|
|
|
| -import '../lib/docgen.dart';
|
| +// TODO(tmandel): Use 'package:' references for imports with relative paths.
|
| +import 'dart:io';
|
| +import 'dart:json';
|
| +import 'dart:async';
|
| +import '../lib/dart2yaml.dart';
|
| +import '../lib/src/dart2js_mirrors.dart';
|
| +import 'package:markdown/markdown.dart' as markdown;
|
| +import '../../args/lib/args.dart';
|
| import '../../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors.dart';
|
| import '../../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors_util.dart';
|
|
|
| /**
|
| - * Analyzes Dart files and generates a representation of included libraries,
|
| - * classes, and members.
|
| + * Entry function to create YAML documentation from Dart files.
|
| */
|
| void main() {
|
| - var results = initArgParser().parse(new Options().arguments);
|
| - new Docgen(results).analyze(listLibraries(results.rest));
|
| + // TODO(tmandel): Use args library once flags are clear.
|
| + Options opts = new Options();
|
| + Docgen docgen = new Docgen();
|
| +
|
| + if (opts.arguments.length > 0) {
|
| + List<Path> libraries = [new Path(opts.arguments[0])];
|
| + Path sdkDirectory = new Path("../../../sdk/");
|
| + var workingMirrors = analyze(libraries, sdkDirectory,
|
| + options: ['--preserve-comments', '--categories=Client,Server']);
|
| + workingMirrors.then( (MirrorSystem mirrorSystem) {
|
| + var mirrors = mirrorSystem.libraries.values;
|
| + if (mirrors.isEmpty) {
|
| + print("no LibraryMirrors");
|
| + } else {
|
| + docgen.libraries = mirrors;
|
| + docgen.documentLibraries();
|
| + }
|
| + });
|
| + }
|
| +}
|
| +
|
| +/**
|
| + * This class documents a list of libraries.
|
| + */
|
| +class Docgen {
|
| +
|
| + /// Libraries to be documented.
|
| + List<LibraryMirror> _libraries;
|
| +
|
| + /// Saves list of libraries for Docgen object.
|
| + void set libraries(value) => _libraries = value;
|
| +
|
| + /// Current library being documented to be used for comment links.
|
| + LibraryMirror _currentLibrary;
|
| +
|
| + /// Current class being documented to be used for comment links.
|
| + ClassMirror _currentClass;
|
| +
|
| + /// Current member being documented to be used for comment links.
|
| + MemberMirror _currentMember;
|
| +
|
| + /// Should the output file type be JSON?
|
| + // TODO(tmandel): Add flag to allow for output to JSON.
|
| + bool outputToJson = false;
|
| +
|
| + /// Resolves reference links
|
| + markdown.Resolver linkResolver;
|
| +
|
| + /**
|
| + * Docgen constructor initializes the link resolver for markdown parsing.
|
| + */
|
| + Docgen() {
|
| + this.linkResolver = (name) =>
|
| + fixReference(name, _currentLibrary, _currentClass, _currentMember);
|
| + }
|
| +
|
| + /**
|
| + * Creates documentation for filtered libraries.
|
| + */
|
| + void documentLibraries() {
|
| + //TODO(tmandel): Filter libraries and determine output type using flags.
|
| + _libraries.forEach((library) {
|
| + _currentLibrary = library;
|
| + var result = new Library(library.qualifiedName, _getComment(library),
|
| + _getVariables(library.variables), _getMethods(library.functions),
|
| + _getClasses(library.classes));
|
| + if (outputToJson) {
|
| + _writeToFile(stringify(result.toMap()), "${result.name}.json");
|
| + } else {
|
| + _writeToFile(getYamlString(result.toMap()), "${result.name}.yaml");
|
| + }
|
| + });
|
| + }
|
| +
|
| + /**
|
| + * Returns any documentation comments associated with a mirror with
|
| + * simple markdown converted to html.
|
| + */
|
| + String _getComment(DeclarationMirror mirror) {
|
| + String commentText;
|
| + mirror.metadata.forEach((metadata) {
|
| + if (metadata is CommentInstanceMirror) {
|
| + CommentInstanceMirror comment = metadata;
|
| + if (comment.isDocComment) {
|
| + if (commentText == null) {
|
| + commentText = comment.trimmedText;
|
| + } else {
|
| + commentText = "$commentText ${comment.trimmedText}";
|
| + }
|
| + }
|
| + }
|
| + });
|
| + return commentText == null ? "" :
|
| + markdown.markdownToHtml(commentText.trim(), linkResolver: linkResolver);
|
| + }
|
| +
|
| + /**
|
| + * Converts all [_] references in comments to <code>_</code>.
|
| + */
|
| + // TODO(tmandel): Create proper links for [_] style markdown based
|
| + // on scope once layout of viewer is finished.
|
| + markdown.Node fixReference(String name, LibraryMirror currentLibrary,
|
| + ClassMirror currentClass, MemberMirror currentMember) {
|
| + return new markdown.Element.text('code', name);
|
| + }
|
| +
|
| + /**
|
| + * Returns a map of [Variable] objects constructed from inputted mirrors.
|
| + */
|
| + Map<String, Variable> _getVariables(Map<String, VariableMirror> mirrorMap) {
|
| + var data = {};
|
| + mirrorMap.forEach((String mirrorName, VariableMirror mirror) {
|
| + _currentMember = mirror;
|
| + data[mirrorName] = new Variable(mirrorName, mirror.isFinal,
|
| + mirror.isStatic, mirror.type.toString(), _getComment(mirror));
|
| + });
|
| + return data;
|
| + }
|
| +
|
| + /**
|
| + * Returns a map of [Method] objects constructed from inputted mirrors.
|
| + */
|
| + Map<String, Method> _getMethods(Map<String, MethodMirror> mirrorMap) {
|
| + var data = {};
|
| + mirrorMap.forEach((String mirrorName, MethodMirror mirror) {
|
| + _currentMember = mirror;
|
| + data[mirrorName] = new Method(mirrorName, mirror.isSetter,
|
| + mirror.isGetter, mirror.isConstructor, mirror.isOperator,
|
| + mirror.isStatic, mirror.returnType.toString(), _getComment(mirror),
|
| + _getParameters(mirror.parameters));
|
| + });
|
| + return data;
|
| + }
|
| +
|
| + /**
|
| + * Returns a map of [Class] objects constructed from inputted mirrors.
|
| + */
|
| + Map<String, Class> _getClasses(Map<String, ClassMirror> mirrorMap) {
|
| + var data = {};
|
| + mirrorMap.forEach((String mirrorName, ClassMirror mirror) {
|
| + _currentClass = mirror;
|
| + var superclass;
|
| + if (mirror.superclass != null) {
|
| + superclass = mirror.superclass.qualifiedName;
|
| + }
|
| + var interfaces =
|
| + mirror.superinterfaces.map((interface) => interface.qualifiedName);
|
| + data[mirrorName] = new Class(mirrorName, superclass, mirror.isAbstract,
|
| + mirror.isTypedef, _getComment(mirror), interfaces,
|
| + _getVariables(mirror.variables), _getMethods(mirror.methods));
|
| + });
|
| + return data;
|
| + }
|
| +
|
| + /**
|
| + * Returns a map of [Parameter] objects constructed from inputted mirrors.
|
| + */
|
| + Map<String, Parameter> _getParameters(List<ParameterMirror> mirrorList) {
|
| + var data = {};
|
| + mirrorList.forEach((ParameterMirror mirror) {
|
| + _currentMember = mirror;
|
| + data[mirror.simpleName] = new Parameter(mirror.simpleName,
|
| + mirror.isOptional, mirror.isNamed, mirror.hasDefaultValue,
|
| + mirror.type.toString(), mirror.defaultValue);
|
| + });
|
| + return data;
|
| + }
|
| +}
|
| +
|
| +/**
|
| + * Transforms the map by calling toMap on each value in it.
|
| + */
|
| +Map recurseMap(Map inputMap) {
|
| + var outputMap = {};
|
| + inputMap.forEach((key, value) {
|
| + outputMap[key] = value.toMap();
|
| + });
|
| + return outputMap;
|
| +}
|
| +
|
| +/**
|
| + * A class containing contents of a Dart library.
|
| + */
|
| +class Library {
|
| +
|
| + /// Documentation comment with converted markdown.
|
| + String comment;
|
| +
|
| + /// Top-level variables in the library.
|
| + Map<String, Variable> variables;
|
| +
|
| + /// Top-level functions in the library.
|
| + Map<String, Method> functions;
|
| +
|
| + /// Classes defined within the library
|
| + Map<String, Class> classes;
|
| +
|
| + String name;
|
| +
|
| + Library(this.name, this.comment, this.variables,
|
| + this.functions, this.classes);
|
| +
|
| + /// Generates a map describing the [Library] object.
|
| + Map toMap() {
|
| + var libraryMap = {};
|
| + libraryMap["name"] = name;
|
| + libraryMap["comment"] = comment;
|
| + libraryMap["variables"] = recurseMap(variables);
|
| + libraryMap["functions"] = recurseMap(functions);
|
| + libraryMap["classes"] = recurseMap(classes);
|
| + return libraryMap;
|
| + }
|
| +}
|
| +
|
| +/**
|
| + * A class containing contents of a Dart class.
|
| + */
|
| +// TODO(tmandel): Figure out how to do typedefs (what is needed)
|
| +class Class {
|
| +
|
| + /// Documentation comment with converted markdown.
|
| + String comment;
|
| +
|
| + /// List of the names of interfaces that this class implements.
|
| + List<String> interfaces;
|
| +
|
| + /// Top-level variables in the class.
|
| + Map<String, Variable> variables;
|
| +
|
| + /// Methods in the class.
|
| + Map<String, Method> methods;
|
| +
|
| + String name;
|
| + String superclass;
|
| + bool isAbstract;
|
| + bool isTypedef;
|
| +
|
| + Class(this.name, this.superclass, this.isAbstract, this.isTypedef,
|
| + this.comment, this.interfaces, this.variables, this.methods);
|
| +
|
| + /// Generates a map describing the [Class] object.
|
| + Map toMap() {
|
| + var classMap = {};
|
| + classMap["name"] = name;
|
| + classMap["comment"] = comment;
|
| + classMap["superclass"] = superclass;
|
| + classMap["abstract"] = isAbstract.toString();
|
| + classMap["typedef"] = isTypedef.toString();
|
| + classMap["implements"] = new List.from(interfaces);
|
| + classMap["variables"] = recurseMap(variables);
|
| + classMap["methods"] = recurseMap(methods);
|
| + return classMap;
|
| + }
|
| +}
|
| +
|
| +/**
|
| + * A class containing properties of a Dart variable.
|
| + */
|
| +class Variable {
|
| +
|
| + /// Documentation comment with converted markdown.
|
| + String comment;
|
| +
|
| + String name;
|
| + bool isFinal;
|
| + bool isStatic;
|
| + String type;
|
| +
|
| + Variable(this.name, this.isFinal, this.isStatic, this.type, this.comment);
|
| +
|
| + /// Generates a map describing the [Variable] object.
|
| + Map toMap() {
|
| + var variableMap = {};
|
| + variableMap["name"] = name;
|
| + variableMap["comment"] = comment;
|
| + variableMap["final"] = isFinal.toString();
|
| + variableMap["static"] = isStatic.toString();
|
| + variableMap["type"] = type;
|
| + return variableMap;
|
| + }
|
| +}
|
| +
|
| +/**
|
| + * A class containing properties of a Dart method.
|
| + */
|
| +class Method {
|
| +
|
| + /// Documentation comment with converted markdown.
|
| + String comment;
|
| +
|
| + /// Parameters for this method.
|
| + Map<String, Parameter> parameters;
|
| +
|
| + String name;
|
| + bool isSetter;
|
| + bool isGetter;
|
| + bool isConstructor;
|
| + bool isOperator;
|
| + bool isStatic;
|
| + String returnType;
|
| +
|
| + Method(this.name, this.isSetter, this.isGetter, this.isConstructor,
|
| + this.isOperator, this.isStatic, this.returnType, this.comment,
|
| + this.parameters);
|
| +
|
| + /// Generates a map describing the [Method] object.
|
| + Map toMap() {
|
| + var methodMap = {};
|
| + methodMap["name"] = name;
|
| + methodMap["comment"] = comment;
|
| + methodMap["type"] = isSetter ? "setter" : isGetter ? "getter" :
|
| + isOperator ? "operator" : isConstructor ? "constructor" : "method";
|
| + methodMap["static"] = isStatic.toString();
|
| + methodMap["return"] = returnType;
|
| + methodMap["parameters"] = recurseMap(parameters);
|
| + return methodMap;
|
| + }
|
| +}
|
| +
|
| +/**
|
| + * A class containing properties of a Dart method/function parameter.
|
| + */
|
| +class Parameter {
|
| +
|
| + String name;
|
| + bool isOptional;
|
| + bool isNamed;
|
| + bool hasDefaultValue;
|
| + String type;
|
| + String defaultValue;
|
| +
|
| + Parameter(this.name, this.isOptional, this.isNamed, this.hasDefaultValue,
|
| + this.type, this.defaultValue);
|
| +
|
| + /// Generates a map describing the [Parameter] object.
|
| + Map toMap() {
|
| + var parameterMap = {};
|
| + parameterMap["name"] = name;
|
| + parameterMap["optional"] = isOptional.toString();
|
| + parameterMap["named"] = isNamed.toString();
|
| + parameterMap["default"] = hasDefaultValue.toString();
|
| + parameterMap["type"] = type;
|
| + parameterMap["value"] = defaultValue;
|
| + return parameterMap;
|
| + }
|
| +}
|
| +
|
| +/**
|
| + * Writes text to a file in the 'docs' directory.
|
| + */
|
| +void _writeToFile(String text, String filename) {
|
| + Directory dir = new Directory('docs');
|
| + if (!dir.existsSync()) {
|
| + dir.createSync();
|
| + }
|
| + File file = new File('docs/$filename');
|
| + if (!file.exists()) {
|
| + file.createSync();
|
| + }
|
| + file.openSync();
|
| + file.writeAsString(text);
|
| }
|
|
|