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

Unified Diff: utils/dartdoc/dartdoc.dart

Issue 9271020: Include subtype information in generated docs. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Respond to review. Created 8 years, 11 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 | « utils/dartdoc/client-live-nav.dart ('k') | utils/dartdoc/static/styles.css » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: utils/dartdoc/dartdoc.dart
diff --git a/utils/dartdoc/dartdoc.dart b/utils/dartdoc/dartdoc.dart
index b62d9ae64839759ece2a365cbf2937ef2cf912c3..b6e02de9ed6780d5c8998afb288565decdea6185 100644
--- a/utils/dartdoc/dartdoc.dart
+++ b/utils/dartdoc/dartdoc.dart
@@ -376,23 +376,30 @@ class Dartdoc {
if ((types.length == 0) && (exceptions.length == 0)) return;
- writeType(String icon, Type type) {
- write('<li>');
- if (_currentType == type) {
- write(
- '<div class="icon-$icon"></div><strong>${typeName(type)}</strong>');
- } else {
- write(a(typeUrl(type),
- '<div class="icon-$icon"></div>${typeName(type)}'));
- }
- writeln('</li>');
+ writeln('<ul class="icon">');
+ types.forEach(docTypeNavigation);
+ exceptions.forEach(docTypeNavigation);
+ writeln('</ul>');
+ }
+
+ /** Writes a linked navigation list item for the given type. */
+ docTypeNavigation(Type type) {
+ var icon = 'interface';
+ if (type.name.endsWith('Exception')) {
+ icon = 'exception';
+ } else if (type.isClass) {
+ icon = 'class';
}
- writeln('<ul>');
- types.forEach((type) => writeType(type.isClass ? 'class' : 'interface',
- type));
- exceptions.forEach((type) => writeType('exception', type));
- writeln('</ul>');
+ write('<li>');
+ if (_currentType == type) {
+ write(
+ '<div class="icon-$icon"></div><strong>${typeName(type)}</strong>');
+ } else {
+ write(a(typeUrl(type),
+ '<div class="icon-$icon"></div>${typeName(type)}'));
+ }
+ writeln('</li>');
}
docLibrary(Library library) {
@@ -478,9 +485,8 @@ class Dartdoc {
<strong>${typeName(type, showBounds: true)}</strong></h2>
''');
- docInheritance(type);
-
docCode(type.span, getTypeComment(type));
+ docInheritance(type);
docConstructors(type);
docMembers(type);
@@ -488,35 +494,121 @@ class Dartdoc {
endFile();
}
- /** Document the superclass, superinterfaces and default class of [Type]. */
+ /**
+ * Writes an inline type span for the given type. This is a little box with
+ * an icon and the type's name. It's similar to how types appear in the
+ * navigation, but is suitable for inline (as opposed to in a `<ul>`) use.
+ */
+ typeSpan(Type type) {
+ var icon = 'interface';
+ if (type.name.endsWith('Exception')) {
+ icon = 'exception';
+ } else if (type.isClass) {
+ icon = 'class';
+ }
+
+ write('<span class="type-box"><span class="icon-$icon"></span>');
+ if (_currentType == type) {
+ write('<strong>${typeName(type)}</strong>');
+ } else {
+ write(a(typeUrl(type), typeName(type)));
+ }
+ write('</span>');
+ }
+
+ /**
+ * Document the other types that touch [Type] in the inheritance hierarchy:
+ * subclasses, superclasses, subinterfaces, superinferfaces, and default
+ * class.
+ */
docInheritance(Type type) {
- final isSubclass = (type.parent != null) && !type.parent.isObject;
+ // Don't show the inheritance details for Object. It doesn't have any base
+ // class (obviously) and it has too many subclasses to be useful.
+ if (type.isObject) return;
+
+ // Writes an unordered list of references to types with an optional header.
+ listTypes(types, header) {
+ if (types == null) return;
- Type defaultType;
- if (type.definition is TypeDefinition) {
- TypeDefinition definition = type.definition;
- if (definition.defaultType != null) {
- defaultType = definition.defaultType.type;
+ // Skip private types.
+ final publicTypes = types.filter((type) => !type.name.startsWith('_'));
+ if (publicTypes.length == 0) return;
+
+ writeln('<h3>$header</h3>');
+ writeln('<p>');
+ bool first = true;
+ for (final type in publicTypes) {
+ if (!first) write(', ');
+ typeSpan(type);
+ first = false;
}
+ writeln('</p>');
}
- if (isSubclass ||
- (type.interfaces != null && type.interfaces.length > 0) ||
- (defaultType != null)) {
- writeln('<p>');
+ if (type.isClass) {
+ // Show the chain of superclasses.
+ if (!type.parent.isObject) {
+ final supertypes = [];
+ var thisType = type.parent;
+ // As a sanity check, only show up to five levels of nesting, otherwise
+ // the box starts to get hideous.
+ do {
+ supertypes.add(thisType);
+ thisType = thisType.parent;
+ } while (!thisType.isObject);
+
+ writeln('<h3>Extends</h3>');
+ writeln('<p>');
+ for (var i = supertypes.length - 1; i >= 0; i--) {
+ typeSpan(supertypes[i]);
+ write('&nbsp;&gt;&nbsp;');
+ }
+
+ // Write this class.
+ typeSpan(type);
+ writeln('</p>');
+ }
- if (isSubclass) {
- write('Extends ${typeReference(type.parent)}. ');
+ // Find the immediate declared subclasses (Type.subtypes includes many
+ // transitive subtypes).
+ final subtypes = [];
+ for (final subtype in type.subtypes) {
+ if (subtype.parent == type) subtypes.add(subtype);
}
+ subtypes.sort((a, b) => a.name.compareTo(b.name));
- if (type.interfaces != null && type.interfaces.length > 0) {
- var interfaceStr = joinWithCommas(map(type.interfaces, typeReference));
- write('Implements ${interfaceStr}. ');
+ listTypes(subtypes, 'Subclasses');
+ listTypes(type.interfaces, 'Implements');
+ } else {
+ // Show the default class.
+ if (type.genericType.defaultType != null) {
+ listTypes([type.genericType.defaultType], 'Default class');
}
- if (defaultType != null) {
- write('Has default class ${typeReference(defaultType)}.');
+ // List extended interfaces.
+ listTypes(type.interfaces, 'Extends');
+
+ // List subinterfaces and implementing classes.
+ final subinterfaces = [];
+ final implementing = [];
+
+ for (final subtype in type.subtypes) {
+ // We only want explicitly declared subinterfaces, so check that this
+ // type is a superinterface.
+ for (final supertype in subtype.interfaces) {
+ if (supertype == type) {
+ if (subtype.isClass) {
+ implementing.add(subtype);
+ } else {
+ subinterfaces.add(subtype);
+ }
+ break;
+ }
+ }
}
+
+ listTypes(subinterfaces, 'Subinterfaces');
+ listTypes(implementing, 'Implemented by');
}
}
@@ -796,7 +888,7 @@ class Dartdoc {
// See if it's an instantiation of a generic type.
final typeArgs = type.typeArgsInOrder;
- if (typeArgs != null) {
+ if (typeArgs.length > 0) {
write('&lt;');
bool first = true;
for (final arg in typeArgs) {
@@ -837,7 +929,7 @@ class Dartdoc {
// See if it's an instantiation of a generic type.
final typeArgs = type.typeArgsInOrder;
- if (typeArgs != null) {
+ if (typeArgs.length > 0) {
final args = Strings.join(map(typeArgs, (arg) => typeName(arg)), ', ');
return '${type.genericType.name}&lt;$args&gt;';
}
« no previous file with comments | « utils/dartdoc/client-live-nav.dart ('k') | utils/dartdoc/static/styles.css » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698