Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(273)

Unified Diff: pkg/docgen/lib/docgen.dart

Issue 21096002: added inherited methods and variables (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/docgen/example/test.dart ('k') | pkg/docgen/test/single_library_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/docgen/lib/docgen.dart
diff --git a/pkg/docgen/lib/docgen.dart b/pkg/docgen/lib/docgen.dart
index 6ad260988ed81ff2477cc6d544e4242bf6a8e149..64d3dbb9ddffd3d574b6491ee66b08d02a773a0a 100644
--- a/pkg/docgen/lib/docgen.dart
+++ b/pkg/docgen/lib/docgen.dart
@@ -53,6 +53,10 @@ markdown.Resolver linkResolver;
/// Index of all the qualified names documented.
Set<String> qualifiedNameIndex = new Set<String>();
+/// Index of all the items to output. This also ensures that no class is
+/// created more than once.
+Map<String, Indexable> entityMap = new Map<String, Indexable>();
+
/**
* Docgen constructor initializes the link resolver for markdown parsing.
* Also initializes the command line arguments.
@@ -195,21 +199,23 @@ Future<MirrorSystem> _analyzeLibraries(List<String> libraries,
/**
* Creates documentation for filtered libraries.
*/
-void _documentLibraries(List<LibraryMirror> libraries,
+void _documentLibraries(List<LibraryMirror> libs,
{bool includeSdk:false, bool includePrivate:false, bool
outputToYaml:true}) {
- libraries.forEach((lib) {
+ libs.forEach((lib) {
// Files belonging to the SDK have a uri that begins with 'dart:'.
if (includeSdk || !lib.uri.toString().startsWith('dart:')) {
var library = generateLibrary(lib, includePrivate: includePrivate);
- _writeLibraryToFile(library, outputToYaml);
+ entityMap[library.qualifiedName] = library;
}
});
- // Outputs a text file with a list of files available after creating all
- // the libraries. This will help the viewer know what files are available
+ // Output libraries and classes to file after all information is generated.
+ entityMap.values.forEach((e) => _writeIndexableToFile(e, outputToYaml));
+ // Outputs a text file with a list of libraries available after creating all
+ // the libraries. This will help the viewer know what libraries are available
// to read in.
- _writeToFile(listDir('docs').join('\n').replaceAll('docs/', ''),
- 'library_list.txt');
+ _writeToFile(entityMap.values.where((e) => e is Library)
+ .map((e) => e.qualifiedName).join('\n'), 'library_list.txt');
// Outputs all the qualified names documented. This will help generate search
// results.
_writeToFile(qualifiedNameIndex.join('\n'), 'index.txt');
@@ -218,27 +224,26 @@ void _documentLibraries(List<LibraryMirror> libraries,
Library generateLibrary(dart2js.Dart2JsLibraryMirror library,
{bool includePrivate:false}) {
_currentLibrary = library;
- var result = new Library(library.qualifiedName, _getComment(library),
- _getVariables(library.variables, includePrivate),
- _getMethods(library.functions, includePrivate),
- _getClasses(library.classes, includePrivate));
+ var result = new Library(library.qualifiedName, _commentToHtml(library),
+ _variables(library.variables, includePrivate),
+ _methods(library.functions, includePrivate),
+ _classes(library.classes, includePrivate));
logger.fine('Generated library for ${result.name}');
return result;
}
-void _writeLibraryToFile(Library result, bool outputToYaml) {
+void _writeIndexableToFile(Indexable result, bool outputToYaml) {
if (outputToYaml) {
- _writeToFile(getYamlString(result.toMap()), '${result.name}.yaml');
+ _writeToFile(getYamlString(result.toMap()), '${result.qualifiedName}.yaml');
} else {
- _writeToFile(stringify(result.toMap()), '${result.name}.json');
+ _writeToFile(stringify(result.toMap()), '${result.qualifiedName}.json');
}
-
}
/**
* Returns a list of meta annotations assocated with a mirror.
*/
-List<String> _getAnnotations(DeclarationMirror mirror) {
+List<String> _annotations(DeclarationMirror mirror) {
var annotations = mirror.metadata.where((e) =>
e is dart2js.Dart2JsConstructedConstantMirror);
return annotations.map((e) => e.type.qualifiedName).toList();
@@ -248,7 +253,7 @@ List<String> _getAnnotations(DeclarationMirror mirror) {
* Returns any documentation comments associated with a mirror with
* simple markdown converted to html.
*/
-String _getComment(DeclarationMirror mirror) {
+String _commentToHtml(DeclarationMirror mirror) {
String commentText;
mirror.metadata.forEach((metadata) {
if (metadata is CommentInstanceMirror) {
@@ -288,7 +293,7 @@ markdown.Node fixReference(String name, LibraryMirror currentLibrary,
/**
* Returns a map of [Variable] objects constructed from [mirrorMap].
*/
-Map<String, Variable> _getVariables(Map<String, VariableMirror> mirrorMap,
+Map<String, Variable> _variables(Map<String, VariableMirror> mirrorMap,
bool includePrivate) {
var data = {};
// TODO(janicejl): When map to map feature is created, replace the below with
@@ -298,7 +303,7 @@ Map<String, Variable> _getVariables(Map<String, VariableMirror> mirrorMap,
_currentMember = mirror;
data[mirrorName] = new Variable(mirrorName, mirror.isFinal,
mirror.isStatic, mirror.isConst, _type(mirror.type),
- _getComment(mirror), _getAnnotations(mirror), mirror.qualifiedName);
+ _commentToHtml(mirror), _annotations(mirror), mirror.qualifiedName);
}
});
return data;
@@ -307,104 +312,116 @@ Map<String, Variable> _getVariables(Map<String, VariableMirror> mirrorMap,
/**
* Returns a map of [Method] objects constructed from [mirrorMap].
*/
-Map<String, Map<String, Method>> _getMethods
+MethodGroup _methods
(Map<String, MethodMirror> mirrorMap, bool includePrivate) {
- var setters = {};
- var getters = {};
- var constructors = {};
- var operators = {};
- var methods = {};
+ var group = new MethodGroup();
mirrorMap.forEach((String mirrorName, MethodMirror mirror) {
if (includePrivate || !mirror.isPrivate) {
var method = new Method(mirrorName, mirror.isStatic, mirror.isAbstract,
mirror.isConstConstructor, _type(mirror.returnType),
- _getComment(mirror), _getParameters(mirror.parameters),
- _getAnnotations(mirror), mirror.qualifiedName);
+ _commentToHtml(mirror), _parameters(mirror.parameters),
+ _annotations(mirror), mirror.qualifiedName);
_currentMember = mirror;
Alan Knight 2013/07/30 22:12:53 This whole method seems more like it should be a
if (mirror.isSetter) {
- setters[mirrorName] = method;
+ group.setters[mirrorName] = method;
} else if (mirror.isGetter) {
- getters[mirrorName] = method;
+ group.getters[mirrorName] = method;
} else if (mirror.isConstructor) {
- constructors[mirrorName] = method;
+ group.constructors[mirrorName] = method;
} else if (mirror.isOperator) {
- operators[mirrorName] = method;
+ group.operators[mirrorName] = method;
} else if (mirror.isRegularMethod) {
- methods[mirrorName] = method;
+ group.regularMethods[mirrorName] = method;
} else {
throw new ArgumentError('$mirrorName - no method type match');
}
}
});
- return {
- 'setters': setters,
- 'getters': getters,
- 'constructors': constructors,
- 'operators': operators,
- 'methods': methods
- };
+ return group;
}
/**
+ * Returns the [Class] for the given [mirror] has already been created, and if
+ * it does not exist, creates it.
+ */
+Class _findOrCreateClass(ClassMirror mirror, bool includePrivate) {
Alan Knight 2013/07/30 22:12:53 Naming nit. The fact that we're caching these isn'
janicejl 2013/08/01 04:30:26 Done.
+ var clazz = entityMap[mirror.qualifiedName];
+ if (clazz == null) {
+ var superclass = (mirror.superclass != null) ?
+ mirror.superclass.qualifiedName : '';
+ var interfaces =
+ mirror.superinterfaces.map((interface) => interface.qualifiedName);
+ clazz = new Class(mirror.simpleName, superclass, _commentToHtml(mirror),
+ interfaces.toList(),
+ _variables(mirror.variables, includePrivate),
+ _methods(mirror.methods, includePrivate),
+ _annotations(mirror),
+ _generics(mirror), mirror.qualifiedName);
+ entityMap[mirror.qualifiedName] = clazz;
+ }
+ return clazz;
+}
+
+/**
* Returns a map of [Class] objects constructed from [mirrorMap].
*/
-Map<String, Class> _getClasses(Map<String, ClassMirror> mirrorMap,
+ClassGroup _classes(Map<String, ClassMirror> mirrorMap,
bool includePrivate) {
- var abstractClasses = {};
- var classes = {};
- var typedefs = {};
- var errors = {};
+ var group = new ClassGroup();
mirrorMap.forEach((String mirrorName, ClassMirror mirror) {
if (includePrivate || !mirror.isPrivate) {
- var superclass = (mirror.superclass != null) ?
- mirror.superclass.qualifiedName : '';
- var interfaces =
- mirror.superinterfaces.map((interface) => interface.qualifiedName);
- var clazz = new Class(mirrorName, superclass, _getComment(mirror),
- interfaces.toList(), _getVariables(mirror.variables, includePrivate),
- _getMethods(mirror.methods, includePrivate),
- _getAnnotations(mirror), _getGenerics(mirror), mirror.qualifiedName);
_currentClass = mirror;
+ var clazz = _findOrCreateClass(mirror, includePrivate);
+
+ // Adding inherited superclass variables and methods.
+ if (clazz.superclass != '') {
+ var superclazz = _findOrCreateClass(mirror.superclass, includePrivate);
+ superclazz.subclasses.add(clazz.qualifiedName);
+ clazz.inheritedMethods.addInherited(superclazz);
+ }
+
+ // Adding inherited interface variables and methods.
+ mirror.superinterfaces.forEach((interface) {
+ var interfaceClass = _findOrCreateClass(interface, includePrivate);
+ interfaceClass.subclasses.add(clazz.qualifiedName);
+ clazz.inheritedVariables.addAll(interfaceClass.variables);
+ clazz.inheritedMethods.addInherited(interfaceClass);
+ });
if (isError(mirror.qualifiedName)) {
- errors[mirrorName] = clazz;
+ group.errors[mirrorName] = clazz;
} else if (mirror.isTypedef) {
- typedefs[mirrorName] = new Typedef(mirrorName,
- mirror.value.returnType.qualifiedName, _getComment(mirror),
- _getGenerics(mirror), _getParameters(mirror.value.parameters),
- _getAnnotations(mirror), mirror.qualifiedName);
+ group.typedefs[mirrorName] = new Typedef(mirrorName,
+ mirror.value.returnType.qualifiedName, _commentToHtml(mirror),
+ _generics(mirror), _parameters(mirror.value.parameters),
+ _annotations(mirror), mirror.qualifiedName);
} else if (mirror.isAbstract) {
- abstractClasses[mirrorName] = clazz;
+ group.abstractClasses[mirrorName] = clazz;
} else if (mirror.isClass) {
- classes[mirrorName] = clazz;
+ group.regularClasses[mirrorName] = clazz;
} else {
throw new ArgumentError('$mirrorName - no class type match. ');
}
}
});
- return {
- 'abstract': abstractClasses,
- 'class': classes,
- 'typedef': typedefs,
- 'error': errors
- };
+ return group;
}
/**
* Returns a map of [Parameter] objects constructed from [mirrorList].
*/
-Map<String, Parameter> _getParameters(List<ParameterMirror> mirrorList) {
+Map<String, Parameter> _parameters(List<ParameterMirror> mirrorList) {
var data = {};
mirrorList.forEach((ParameterMirror mirror) {
_currentMember = mirror;
data[mirror.simpleName] = new Parameter(mirror.simpleName,
mirror.isOptional, mirror.isNamed, mirror.hasDefaultValue,
_type(mirror.type), mirror.defaultValue,
- _getAnnotations(mirror));
+ _annotations(mirror));
});
return data;
}
@@ -412,7 +429,7 @@ Map<String, Parameter> _getParameters(List<ParameterMirror> mirrorList) {
/**
* Returns a map of [Generic] objects constructed from the class mirror.
*/
-Map<String, Generic> _getGenerics(ClassMirror mirror) {
+Map<String, Generic> _generics(ClassMirror mirror) {
return new Map.fromIterable(mirror.typeVariables,
key: (e) => e.toString(),
value: (e) => new Generic(e.toString(), e.upperBound.qualifiedName));
@@ -501,23 +518,23 @@ class Library extends Indexable {
Map<String, Variable> variables;
/// Top-level functions in the library.
- Map<String, Map<String, Method>> functions;
+ MethodGroup functions;
/// Classes defined within the library
- Map<String, Class> classes;
+ ClassGroup classes;
Library(String name, String comment, this.variables,
this.functions, this.classes) : super(name, comment, name) {}
/// Generates a map describing the [Library] object.
Map toMap() => {
- 'name': name,
- 'qualifiedname': qualifiedName,
- 'comment': comment,
- 'variables': recurseMap(variables),
- 'functions': recurseMap(functions),
- 'classes': recurseMap(classes)
- };
+ 'name': name,
+ 'qualifiedname': qualifiedName,
+ 'comment': comment,
+ 'variables': recurseMap(variables),
+ 'functions': functions.toMap(),
+ 'classes': classes.toMap()
+ };
}
/**
@@ -527,12 +544,21 @@ class Class extends Indexable {
/// List of the names of interfaces that this class implements.
List<String> interfaces;
+
+ /// Names of classes that extends or implements this class.
+ List<String> subclasses = [];
/// Top-level variables in the class.
Map<String, Variable> variables;
+
+ /// Inherited variables in the class.
+ Map<String, Variable> inheritedVariables = {};
/// Methods in the class.
- Map<String, Map<String, Method>> methods;
+ MethodGroup methods;
+
+ /// Inherited methods in the class.
+ MethodGroup inheritedMethods = new MethodGroup();
/// Generic infomation about the class.
Map<String, Generic> generics;
@@ -548,16 +574,38 @@ class Class extends Indexable {
/// Generates a map describing the [Class] object.
Map toMap() => {
- 'name': name,
- 'qualifiedname': qualifiedName,
- 'comment': comment,
- 'superclass': superclass,
- 'implements': new List.from(interfaces),
- 'variables': recurseMap(variables),
- 'methods': recurseMap(methods),
- 'annotations': new List.from(annotations),
- 'generics': recurseMap(generics)
- };
+ 'name': name,
+ 'qualifiedname': qualifiedName,
+ 'comment': comment,
+ 'superclass': superclass,
+ 'implements': new List.from(interfaces),
+ 'subclass': new List.from(subclasses),
+ 'variables': recurseMap(variables),
+ 'inheritedvariables': recurseMap(inheritedVariables),
+ 'methods': methods.toMap(),
+ 'inheritedmethods': inheritedMethods.toMap(),
+ 'annotations': new List.from(annotations),
+ 'generics': recurseMap(generics)
+ };
+}
+
+/**
+ * A container to categorize classes into the following groups: abstract
+ * classes, regular classes, typedefs, and errors.
+ */
+class ClassGroup {
+ Map<String, Class> abstractClasses = {};
+ Map<String, Class> regularClasses = {};
+ Map<String, Typedef> typedefs = {};
+ Map<String, Class> errors = {};
+
+ Map toMap() => {
+ 'abstract': new List.from(abstractClasses.values
+ .map((e) => e.qualifiedName)),
+ 'class': new List.from(regularClasses.values.map((e) => e.qualifiedName)),
+ 'typedef': recurseMap(typedefs),
+ 'error': new List.from(errors.values.map((e) => e.qualifiedName))
+ };
}
class Typedef extends Indexable {
@@ -576,14 +624,14 @@ class Typedef extends Indexable {
String qualifiedName) : super(name, comment, qualifiedName) {}
Map toMap() => {
- 'name': name,
- 'qualifiedname': qualifiedName,
- 'comment': comment,
- 'return': returnType,
- 'parameters': recurseMap(parameters),
- 'annotations': new List.from(annotations),
- 'generics': recurseMap(generics)
- };
+ 'name': name,
+ 'qualifiedname': qualifiedName,
+ 'comment': comment,
+ 'return': returnType,
+ 'parameters': recurseMap(parameters),
+ 'annotations': new List.from(annotations),
+ 'generics': recurseMap(generics)
+ };
}
/**
@@ -605,15 +653,15 @@ class Variable extends Indexable {
/// Generates a map describing the [Variable] object.
Map toMap() => {
- 'name': name,
- 'qualifiedname': qualifiedName,
- 'comment': comment,
- 'final': isFinal.toString(),
- 'static': isStatic.toString(),
- 'constant': isConst.toString(),
- 'type': new List.filled(1, type.toMap()),
- 'annotations': new List.from(annotations)
- };
+ 'name': name,
+ 'qualifiedname': qualifiedName,
+ 'comment': comment,
+ 'final': isFinal.toString(),
+ 'static': isStatic.toString(),
+ 'constant': isConst.toString(),
+ 'type': new List.filled(1, type.toMap()),
+ 'annotations': new List.from(annotations)
+ };
}
/**
@@ -639,16 +687,43 @@ class Method extends Indexable {
/// Generates a map describing the [Method] object.
Map toMap() => {
- 'name': name,
- 'qualifiedname': qualifiedName,
- 'comment': comment,
- 'static': isStatic.toString(),
- 'abstract': isAbstract.toString(),
- 'constant': isConst.toString(),
- 'return': new List.filled(1, returnType.toMap()),
- 'parameters': recurseMap(parameters),
- 'annotations': new List.from(annotations)
- };
+ 'name': name,
+ 'qualifiedname': qualifiedName,
+ 'comment': comment,
+ 'static': isStatic.toString(),
+ 'abstract': isAbstract.toString(),
+ 'constant': isConst.toString(),
+ 'return': new List.filled(1, returnType.toMap()),
+ 'parameters': recurseMap(parameters),
+ 'annotations': new List.from(annotations)
+ };
+}
+
+/**
+ * A container to categorize methods into the following groups: setters,
+ * getters, constructors, operators, regular methods.
+ */
+class MethodGroup {
+ Map<String, Method> setters = {};
+ Map<String, Method> getters = {};
+ Map<String, Method> constructors = {};
+ Map<String, Method> operators = {};
+ Map<String, Method> regularMethods = {};
+
+ void addInherited(Class implemented) {
+ setters.addAll(implemented.methods.setters);
+ getters.addAll(implemented.methods.getters);
+ operators.addAll(implemented.methods.operators);
+ regularMethods.addAll(implemented.methods.regularMethods);
+ }
+
+ Map toMap() => {
+ 'setters': recurseMap(setters),
+ 'getters': recurseMap(getters),
+ 'constructors': recurseMap(constructors),
+ 'operators': recurseMap(operators),
+ 'methods': recurseMap(regularMethods)
+ };
}
/**
@@ -671,14 +746,14 @@ class Parameter {
/// Generates a map describing the [Parameter] object.
Map toMap() => {
- 'name': name,
- 'optional': isOptional.toString(),
- 'named': isNamed.toString(),
- 'default': hasDefaultValue.toString(),
- 'type': new List.filled(1, type.toMap()),
- 'value': defaultValue,
- 'annotations': new List.from(annotations)
- };
+ 'name': name,
+ 'optional': isOptional.toString(),
+ 'named': isNamed.toString(),
+ 'default': hasDefaultValue.toString(),
+ 'type': new List.filled(1, type.toMap()),
+ 'value': defaultValue,
+ 'annotations': new List.from(annotations)
+ };
}
/**
@@ -691,9 +766,9 @@ class Generic {
Generic(this.name, this.type);
Map toMap() => {
- 'name': name,
- 'type': type
- };
+ 'name': name,
+ 'type': type
+ };
}
/**
@@ -733,7 +808,7 @@ class Type {
Type(this.outer, this.inner);
Map toMap() => {
- 'outer': outer,
- 'inner': new List.from(inner.map((e) => e.toMap()))
- };
+ 'outer': outer,
+ 'inner': new List.from(inner.map((e) => e.toMap()))
+ };
}
« no previous file with comments | « pkg/docgen/example/test.dart ('k') | pkg/docgen/test/single_library_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698