Chromium Code Reviews| Index: pkg/docgen/lib/docgen.dart |
| diff --git a/pkg/docgen/lib/docgen.dart b/pkg/docgen/lib/docgen.dart |
| index 49d659bf06488434e3a0ea94ada16df71200d2c7..d444f77ba84981e77de906ad408b21597afd3908 100644 |
| --- a/pkg/docgen/lib/docgen.dart |
| +++ b/pkg/docgen/lib/docgen.dart |
| @@ -22,8 +22,10 @@ import 'dart:async'; |
| import 'package:args/args.dart'; |
| import 'package:logging/logging.dart'; |
| import 'package:markdown/markdown.dart' as markdown; |
| +import 'package:pathos/path.dart' as path; |
| import 'dart2yaml.dart'; |
| +import 'src/io.dart'; |
| import '../../../sdk/lib/_internal/compiler/compiler.dart' as api; |
| import '../../../sdk/lib/_internal/compiler/implementation/filenames.dart'; |
| import '../../../sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart' |
| @@ -32,48 +34,9 @@ import '../../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors.dart' |
| import '../../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors_util.dart'; |
| import '../../../sdk/lib/_internal/compiler/implementation/source_file_provider.dart'; |
| -var logger = new Logger("Docgen"); |
| +var logger = new Logger('Docgen'); |
| -/// Counter used to provide unique IDs for each distinct item. |
| -int _nextID = 0; |
| - |
| -int get nextID => _nextID++; |
| - |
| -const String usage = "Usage: dart docgen.dart [OPTIONS] [fooDir/barFile]"; |
| - |
| -List<Path> listLibraries(List<String> args) { |
| - if (args.length != 1) { |
| - throw new UnsupportedError(usage); |
| - } |
| - var libraries = new List<Path>(); |
| - var type = FileSystemEntity.typeSync(args[0]); |
| - |
| - if (type == FileSystemEntityType.NOT_FOUND) { |
| - throw new UnsupportedError("File does not exist. $usage"); |
| - } else if (type == FileSystemEntityType.LINK) { |
| - libraries.addAll(listLibrariesFromDir(new Link(args[0]).targetSync())); |
| - } else if (type == FileSystemEntityType.FILE) { |
| - libraries.add(new Path(args[0])); |
| - logger.info("Added to libraries: ${libraries.last.toString()}"); |
| - } else if (type == FileSystemEntityType.DIRECTORY) { |
| - libraries.addAll(listLibrariesFromDir(args[0])); |
| - } |
| - return libraries; |
| -} |
| - |
| -List<Path> listLibrariesFromDir(String path) { |
| - var libraries = new List<Path>(); |
| - new Directory(path).listSync(recursive: true, |
| - followLinks: true).forEach((file) { |
| - if (new Path(file.path).extension == "dart") { |
| - if (!file.path.contains("/packages/")) { |
| - libraries.add(new Path(file.path)); |
| - logger.info("Added to libraries: ${libraries.last.toString()}"); |
| - } |
| - } |
| - }); |
| - return libraries; |
| -} |
| +const String usage = 'Usage: dart docgen.dart [OPTIONS] [fooDir/barFile]'; |
| /** |
| * This class documents a list of libraries. |
| @@ -82,7 +45,7 @@ class Docgen { |
| /// Libraries to be documented. |
| List<LibraryMirror> _libraries; |
| - |
| + |
| /// Current library being documented to be used for comment links. |
| LibraryMirror _currentLibrary; |
| @@ -92,9 +55,12 @@ class Docgen { |
| /// Current member being documented to be used for comment links. |
| MemberMirror _currentMember; |
| - /// Resolves reference links |
| + /// Resolves reference links in doc-comments. |
|
Andrei Mouravski
2013/06/25 20:13:22
"doc comments."
janicejl
2013/06/25 20:50:15
Done.
|
| markdown.Resolver linkResolver; |
| + /// Package Directory of directory being analyzed. |
|
Andrei Mouravski
2013/06/25 20:13:22
Directory -> directory.
janicejl
2013/06/25 20:50:15
Done.
|
| + String packageDir; |
| + |
| bool outputToYaml; |
| bool outputToJson; |
| bool includePrivate; |
| @@ -106,51 +72,82 @@ class Docgen { |
| * Also initializes the command line arguments. |
| */ |
| Docgen(ArgResults argResults) { |
| - if (argResults["output-format"] == null) { |
| + if (argResults['output-format'] == null) { |
| outputToYaml = |
| - (argResults["yaml"] == false && argResults["json"] == false) ? |
| - true : argResults["yaml"]; |
| + (argResults['yaml'] == false && argResults['json'] == false) ? |
| + true : argResults['yaml']; |
| } else { |
| - if ((argResults["output-format"] == "yaml" && |
| - argResults["json"] == true) || |
| - (argResults["output-format"] == "json" && |
| - argResults["yaml"] == true)) { |
| - throw new UnsupportedError("Cannot have contradictory output flags."); |
| + if ((argResults['output-format'] == 'yaml' && |
| + argResults['json'] == true) || |
| + (argResults['output-format'] == 'json' && |
| + argResults['yaml'] == true)) { |
| + throw new UnsupportedError('Cannot have contradictory output flags.'); |
| } |
| - outputToYaml = argResults["output-format"] == "yaml" ? true : false; |
| + outputToYaml = argResults['output-format'] == 'yaml' ? true : false; |
| } |
| outputToJson = !outputToYaml; |
| - includePrivate = argResults["include-private"]; |
| - includeSdk = argResults["include-sdk"]; |
| + includePrivate = argResults['include-private']; |
| + includeSdk = argResults['include-sdk']; |
| this.linkResolver = (name) => |
| fixReference(name, _currentLibrary, _currentClass, _currentMember); |
| + |
| + analyze(argResults.rest); |
| } |
| + List<String> listLibraries(List<String> args) { |
| + if (args.length != 1) throw new UnsupportedError(usage); |
|
Andrei Mouravski
2013/06/25 20:13:22
Add a TODO here as to why it needs to be this way.
janicejl
2013/06/25 20:50:15
Done.
|
| + var libraries = new List<String>(); |
| + var type = FileSystemEntity.typeSync(args[0]); |
| + |
| + if (type == FileSystemEntityType.LINK) { |
| + libraries.addAll(listDartFromDir(resolveLink(args[0]))); |
| + } else if (type == FileSystemEntityType.FILE) { |
| + libraries.add(path.absolute(args[0])); |
| + logger.info('Added to libraries: ${libraries.last}'); |
| + packageDir = ''; |
| + } else if (type == FileSystemEntityType.DIRECTORY) { |
| + libraries.addAll(listDartFromDir(args[0])); |
| + } else { |
| + throw new UnsupportedError('File does not exist. $usage'); |
| + } |
| + logger.info('Package Directory: $packageDir'); |
| + return libraries; |
| + } |
| + |
| + List<String> listDartFromDir(String args) { |
| + var files = listDir(args, recursive: true); |
| + var libraries = files.where((f) => |
| + f.endsWith('.dart') && !f.contains('/packages')).toList(); |
| + libraries.forEach((lib) => logger.info('Added to libraries: $lib')); |
| + packageDir = files.firstWhere((f) => |
| + f.endsWith('/pubspec.yaml'), orElse: () => ''); |
| + if (packageDir != '') packageDir = path.dirname(packageDir) + '/packages'; |
| + return libraries; |
| + } |
| + |
| /** |
| * Analyzes set of libraries by getting a mirror system and triggers the |
| * documentation of the libraries. |
| */ |
| - void analyze(List<Path> libraries) { |
| + void analyze(List<String> args) { |
| + var libraries = listLibraries(args); |
| + if (libraries.isEmpty) throw new UnsupportedError('No Libraries.'); |
|
Andrei Mouravski
2013/06/25 20:13:22
Because you check isEmpty here, you don't need to
Andrei Mouravski
2013/06/25 20:13:22
Make a more descriptive error.
Also, it's possibly
janicejl
2013/06/25 20:50:15
Done.
|
| // DART_SDK should be set to the root of the SDK library. |
| - var sdkRoot = Platform.environment["DART_SDK"]; |
| + var sdkRoot = Platform.environment['DART_SDK']; |
| if (sdkRoot != null) { |
| - logger.info("Using DART_SDK to find SDK at $sdkRoot"); |
| - sdkRoot = new Path(sdkRoot); |
| + logger.info('Using DART_SDK to find SDK at $sdkRoot'); |
| } else { |
| // If DART_SDK is not defined in the environment, |
| // assuming the dart executable is from the Dart SDK folder inside bin. |
| - sdkRoot = new Path(new Options().executable).directoryPath |
| - .directoryPath; |
| - logger.info("SDK Root: ${sdkRoot.toString()}"); |
| + sdkRoot = path.dirname(path.dirname(new Options().executable)); |
| + logger.info('SDK Root: ${sdkRoot}'); |
| } |
| - Path packageDir = libraries.last.directoryPath.append("packages"); |
| - logger.info("Package Root: ${packageDir.toString()}"); |
| - getMirrorSystem(libraries, sdkRoot, |
| - packageRoot: packageDir).then((MirrorSystem mirrorSystem) { |
| + getMirrorSystem(libraries, sdkRoot, packageRoot: packageDir) |
| + .then((MirrorSystem mirrorSystem) { |
| if (mirrorSystem.libraries.values.isEmpty) { |
| - throw new UnsupportedError("No Library Mirrors."); |
| + throw new UnsupportedError('No Library Mirrors.'); |
| } |
| this.libraries = mirrorSystem.libraries.values; |
| documentLibraries(); |
| @@ -161,8 +158,8 @@ class Docgen { |
| * Analyzes set of libraries and provides a mirror system which can be used |
| * for static inspection of the source code. |
| */ |
| - Future<MirrorSystem> getMirrorSystem(List<Path> libraries, |
| - Path libraryRoot, {Path packageRoot}) { |
| + Future<MirrorSystem> getMirrorSystem(List<String> libraries, |
| + String libraryRoot, {String packageRoot}) { |
|
Andrei Mouravski
2013/06/25 20:13:22
Don't forget to actually update libraryRoot to Pat
janicejl
2013/06/25 20:50:15
Should I still make it a Path if it works without
|
| SourceFileProvider provider = new SourceFileProvider(); |
| api.DiagnosticHandler diagnosticHandler = |
| new FormattingDiagnosticHandler(provider).diagnosticHandler; |
| @@ -173,7 +170,7 @@ class Docgen { |
| } |
| List<Uri> librariesUri = <Uri>[]; |
| libraries.forEach((library) { |
| - librariesUri.add(currentDirectory.resolve(library.toString())); |
| + librariesUri.add(currentDirectory.resolve(library)); |
| }); |
| return dart2js.analyze(librariesUri, libraryUri, packageUri, |
| provider.readStringFromUri, diagnosticHandler, |
| @@ -185,27 +182,27 @@ class Docgen { |
| */ |
| void documentLibraries() { |
| _libraries.forEach((library) { |
| - // Files belonging to the SDK have a uri that begins with "dart:". |
| - if (includeSdk || !library.uri.toString().startsWith("dart:")) { |
| + // Files belonging to the SDK have a uri that begins with 'dart:'. |
| + if (includeSdk || !library.uri.toString().startsWith('dart:')) { |
| _currentLibrary = library; |
| var result = new Library(library.qualifiedName, _getComment(library), |
| _getVariables(library.variables), _getMethods(library.functions), |
| - _getClasses(library.classes), nextID); |
| + _getClasses(library.classes)); |
| if (outputToJson) { |
| - _writeToFile(stringify(result.toMap()), "${result.name}.json"); |
| + _writeToFile(stringify(result.toMap()), '${result.name}.json'); |
| } |
| if (outputToYaml) { |
| - _writeToFile(getYamlString(result.toMap()), "${result.name}.yaml"); |
| + _writeToFile(getYamlString(result.toMap()), '${result.name}.yaml'); |
| } |
| } |
| }); |
| } |
| - |
| + |
| /// Saves list of libraries for Docgen object. |
| void set libraries(value){ |
| _libraries = value; |
| } |
| - |
| + |
| /** |
| * Returns any documentation comments associated with a mirror with |
| * simple markdown converted to html. |
| @@ -219,14 +216,14 @@ class Docgen { |
| if (commentText == null) { |
| commentText = comment.trimmedText; |
| } else { |
| - commentText = "$commentText ${comment.trimmedText}"; |
| + commentText = '$commentText ${comment.trimmedText}'; |
| } |
| } |
| } |
| }); |
| - commentText = commentText == null ? "" : |
| + commentText = commentText == null ? '' : |
| markdown.markdownToHtml(commentText.trim(), linkResolver: linkResolver) |
| - .replaceAll("\n", ""); |
| + .replaceAll('\n', ''); |
| return commentText; |
| } |
| @@ -248,9 +245,9 @@ class Docgen { |
| mirrorMap.forEach((String mirrorName, VariableMirror mirror) { |
| if (includePrivate || !mirror.isPrivate) { |
| _currentMember = mirror; |
| - data[mirrorName] = new Variable(mirrorName, mirror.isFinal, |
| - mirror.isStatic, mirror.type.toString(), _getComment(mirror), |
| - nextID); |
| + data[mirrorName] = new Variable(mirrorName, mirror.qualifiedName, |
| + mirror.isFinal, mirror.isStatic, mirror.type.qualifiedName, |
| + _getComment(mirror)); |
| } |
| }); |
| return data; |
| @@ -264,10 +261,10 @@ class Docgen { |
| mirrorMap.forEach((String mirrorName, MethodMirror mirror) { |
| if (includePrivate || !mirror.isPrivate) { |
| _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), nextID); |
| + data[mirrorName] = new Method(mirrorName, mirror.qualifiedName, |
| + mirror.isSetter, mirror.isGetter, mirror.isConstructor, |
| + mirror.isOperator, mirror.isStatic, mirror.returnType.qualifiedName, |
| + _getComment(mirror), _getParameters(mirror.parameters)); |
| } |
| }); |
| return data; |
| @@ -282,13 +279,13 @@ class Docgen { |
| if (includePrivate || !mirror.isPrivate) { |
| _currentClass = mirror; |
| var superclass = (mirror.superclass != null) ? |
| - mirror.superclass.qualifiedName : ""; |
| + mirror.superclass.qualifiedName : ''; |
| var interfaces = |
| mirror.superinterfaces.map((interface) => interface.qualifiedName); |
| - data[mirrorName] = new Class(mirrorName, superclass, mirror.isAbstract, |
| - mirror.isTypedef, _getComment(mirror), interfaces.toList(), |
| - _getVariables(mirror.variables), _getMethods(mirror.methods), |
| - nextID); |
| + data[mirrorName] = new Class(mirrorName, mirror.qualifiedName, |
| + superclass, mirror.isAbstract, mirror.isTypedef, |
| + _getComment(mirror), interfaces.toList(), |
| + _getVariables(mirror.variables), _getMethods(mirror.methods)); |
| } |
| }); |
| return data; |
| @@ -302,8 +299,9 @@ class Docgen { |
| mirrorList.forEach((ParameterMirror mirror) { |
| _currentMember = mirror; |
| data[mirror.simpleName] = new Parameter(mirror.simpleName, |
| - mirror.isOptional, mirror.isNamed, mirror.hasDefaultValue, |
| - mirror.type.toString(), mirror.defaultValue, nextID); |
| + mirror.qualifiedName, mirror.isOptional, mirror.isNamed, |
| + mirror.hasDefaultValue, mirror.type.qualifiedName, |
| + mirror.defaultValue); |
| }); |
| return data; |
| } |
| @@ -325,9 +323,6 @@ Map recurseMap(Map inputMap) { |
| */ |
| class Library { |
| - /// Unique ID number for resolving links. |
| - int id; |
| - |
| /// Documentation comment with converted markdown. |
| String comment; |
| @@ -343,17 +338,16 @@ class Library { |
| String name; |
| Library(this.name, this.comment, this.variables, |
| - this.functions, this.classes, this.id); |
| + this.functions, this.classes); |
| /// Generates a map describing the [Library] object. |
| Map toMap() { |
| var libraryMap = {}; |
| - libraryMap["id"] = id; |
| - libraryMap["name"] = name; |
| - libraryMap["comment"] = comment; |
| - libraryMap["variables"] = recurseMap(variables); |
| - libraryMap["functions"] = recurseMap(functions); |
| - libraryMap["classes"] = recurseMap(classes); |
| + libraryMap['name'] = name; |
| + libraryMap['comment'] = comment; |
| + libraryMap['variables'] = recurseMap(variables); |
| + libraryMap['functions'] = recurseMap(functions); |
| + libraryMap['classes'] = recurseMap(classes); |
| return libraryMap; |
| } |
| } |
| @@ -364,9 +358,6 @@ class Library { |
| // TODO(tmandel): Figure out how to do typedefs (what is needed) |
| class Class { |
| - /// Unique ID number for resolving links. |
| - int id; |
| - |
| /// Documentation comment with converted markdown. |
| String comment; |
| @@ -380,25 +371,26 @@ class Class { |
| Map<String, Method> methods; |
| String name; |
| + String qualifiedName; |
| String superclass; |
| bool isAbstract; |
| bool isTypedef; |
| - Class(this.name, this.superclass, this.isAbstract, this.isTypedef, |
| - this.comment, this.interfaces, this.variables, this.methods, this.id); |
| + Class(this.name, this.qualifiedName, 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["id"] = id; |
| - 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); |
| + classMap['name'] = name; |
| + classMap['qualifiedname'] = qualifiedName; |
| + 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; |
| } |
| } |
| @@ -408,29 +400,27 @@ class Class { |
| */ |
| class Variable { |
| - /// Unique ID number for resolving links. |
| - int id; |
| - |
| /// Documentation comment with converted markdown. |
| String comment; |
| String name; |
| + String qualifiedName; |
| bool isFinal; |
| bool isStatic; |
| String type; |
| - Variable(this.name, this.isFinal, this.isStatic, this.type, |
| - this.comment, this.id); |
| + Variable(this.name, this.qualifiedName, this.isFinal, this.isStatic, |
| + this.type, this.comment); |
| /// Generates a map describing the [Variable] object. |
| Map toMap() { |
| var variableMap = {}; |
| - variableMap["id"] = id; |
| - variableMap["name"] = name; |
| - variableMap["comment"] = comment; |
| - variableMap["final"] = isFinal.toString(); |
| - variableMap["static"] = isStatic.toString(); |
| - variableMap["type"] = type; |
| + variableMap['name'] = name; |
| + variableMap['qualifiedname'] = qualifiedName; |
| + variableMap['comment'] = comment; |
| + variableMap['final'] = isFinal.toString(); |
| + variableMap['static'] = isStatic.toString(); |
| + variableMap['type'] = type; |
| return variableMap; |
| } |
| } |
| @@ -440,9 +430,6 @@ class Variable { |
| */ |
| class Method { |
| - /// Unique ID number for resolving links. |
| - int id; |
| - |
| /// Documentation comment with converted markdown. |
| String comment; |
| @@ -450,6 +437,7 @@ class Method { |
| Map<String, Parameter> parameters; |
| String name; |
| + String qualifiedName; |
| bool isSetter; |
| bool isGetter; |
| bool isConstructor; |
| @@ -457,21 +445,21 @@ class Method { |
| bool isStatic; |
| String returnType; |
| - Method(this.name, this.isSetter, this.isGetter, this.isConstructor, |
| - this.isOperator, this.isStatic, this.returnType, this.comment, |
| - this.parameters, this.id); |
| + Method(this.name, this.qualifiedName, 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["id"] = id; |
| - 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); |
| + methodMap['name'] = name; |
| + methodMap['qualifiedname'] = qualifiedName; |
| + 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; |
| } |
| } |
| @@ -481,29 +469,27 @@ class Method { |
| */ |
| class Parameter { |
| - /// Unique ID number for resolving links. |
| - int id; |
| - |
| String name; |
| + String qualifiedName; |
| bool isOptional; |
| bool isNamed; |
| bool hasDefaultValue; |
| String type; |
| String defaultValue; |
| - Parameter(this.name, this.isOptional, this.isNamed, this.hasDefaultValue, |
| - this.type, this.defaultValue, this.id); |
| + Parameter(this.name, this.qualifiedName, this.isOptional, this.isNamed, this.hasDefaultValue, |
| + this.type, this.defaultValue); |
| /// Generates a map describing the [Parameter] object. |
| Map toMap() { |
| var parameterMap = {}; |
| - parameterMap["id"] = id; |
| - parameterMap["name"] = name; |
| - parameterMap["optional"] = isOptional.toString(); |
| - parameterMap["named"] = isNamed.toString(); |
| - parameterMap["default"] = hasDefaultValue.toString(); |
| - parameterMap["type"] = type; |
| - parameterMap["value"] = defaultValue; |
| + parameterMap['name'] = name; |
| + parameterMap['qualifiedname'] = qualifiedName; |
| + parameterMap['optional'] = isOptional.toString(); |
| + parameterMap['named'] = isNamed.toString(); |
| + parameterMap['default'] = hasDefaultValue.toString(); |
| + parameterMap['type'] = type; |
| + parameterMap['value'] = defaultValue; |
| return parameterMap; |
| } |
| } |