| Index: sdk/lib/_internal/dartdoc/lib/universe_serializer.dart
|
| diff --git a/sdk/lib/_internal/dartdoc/lib/universe_serializer.dart b/sdk/lib/_internal/dartdoc/lib/universe_serializer.dart
|
| index f2ffbcfecb88ecbd65c572587a34a7182bb50c9d..53da5830f5a2d778c542f0d263686c5f99090a14 100755
|
| --- a/sdk/lib/_internal/dartdoc/lib/universe_serializer.dart
|
| +++ b/sdk/lib/_internal/dartdoc/lib/universe_serializer.dart
|
| @@ -24,6 +24,10 @@ String _stripUri(String uri) {
|
| }
|
| }
|
|
|
| +String _escapeId(String id) {
|
| + return id.replaceAll(new RegExp('[/]'), '#slash');
|
| +}
|
| +
|
| /**
|
| * Base class for all elements in the AST.
|
| */
|
| @@ -36,6 +40,14 @@ class Element {
|
| final String id;
|
| /** Raw text of the comment associated with the Element if any. */
|
| final String comment;
|
| + /** Raw html comment for the Element from MDN. */
|
| + String mdnCommentHtml;
|
| + /**
|
| + * The URL to the page on MDN that content was pulled from for the current
|
| + * type being documented. Will be `null` if the type doesn't use any MDN
|
| + * content.
|
| + */
|
| + String mdnUrl;
|
| /** Children of the node. */
|
| List<Element> children;
|
| /** Whether the element is private. */
|
| @@ -50,10 +62,20 @@ class Element {
|
| */
|
| String line;
|
|
|
| - Element(Mirror mirror, this.kind, this.name, this.id, this.comment)
|
| + Element(Mirror mirror, this.kind, this.name, String id, this.comment,
|
| + MdnComment lookupMdnComment(Mirror))
|
| : line = mirror.location.line.toString(),
|
| + id = _escapeId(id),
|
| isPrivate = _optionalBool(mirror.isPrivate),
|
| - uri = _stripUri(mirror.location.sourceUri.toString());
|
| + uri = _stripUri(mirror.location.sourceUri.toString()) {
|
| + if (lookupMdnComment != null) {
|
| + var mdnComment = lookupMdnComment(mirror);
|
| + if (mdnComment != null) {
|
| + mdnCommentHtml = mdnComment.mdnComment;
|
| + mdnUrl = mdnComment.mdnUrl;
|
| + }
|
| + }
|
| + }
|
|
|
| void addChild(Element child) {
|
| if (children == null) {
|
| @@ -97,31 +119,69 @@ Reference _optionalReference(Mirror mirror) {
|
| * [Element] describing a Dart library.
|
| */
|
| class LibraryElement extends Element {
|
| - LibraryElement(String name, LibraryMirror mirror)
|
| - : super(mirror, 'library', name, name, computeComment(mirror)) {
|
| -
|
| + LibraryElement(String name, LibraryMirror mirror,
|
| + MdnComment lookupMdnComment(Mirror))
|
| + : super(mirror, 'library', _libraryName(mirror), name,
|
| + computeComment(mirror), lookupMdnComment) {
|
| +
|
| mirror.functions.forEach((childName, childMirror) {
|
| - addChild(new MethodElement(childName, childMirror));
|
| + addChild(new MethodElement(childName, childMirror, lookupMdnComment));
|
| });
|
|
|
| mirror.getters.forEach((childName, childMirror) {
|
| - addChild(new GetterElement(childName, childMirror));
|
| + addChild(new GetterElement(childName, childMirror, lookupMdnComment));
|
| });
|
|
|
| mirror.variables.forEach((childName, childMirror) {
|
| - addChild(new VariableElement(childName, childMirror));
|
| + addChild(new VariableElement(childName, childMirror, lookupMdnComment));
|
| });
|
|
|
| mirror.classes.forEach((className, classMirror) {
|
| - if (!classMirror.isPrivate) {
|
| - if (classMirror is TypedefMirror) {
|
| - addChild(new TypedefElement(className, classMirror));
|
| - } else {
|
| - addChild(new ClassElement(className, classMirror));
|
| - }
|
| + if (classMirror is TypedefMirror) {
|
| + addChild(new TypedefElement(className, classMirror));
|
| + } else {
|
| + addChild(new ClassElement(className, classMirror, lookupMdnComment));
|
| }
|
| });
|
| }
|
| +
|
| + static String _libraryName(LibraryMirror mirror) {
|
| + if (mirror.uri.scheme == 'file') {
|
| + // TODO(jacobr): this is a hack. Remove once these libraries are removed
|
| + // from the sdk.
|
| + var uri = mirror.uri;
|
| + var path = uri.path;
|
| + var pattern = new RegExp(r'[\\/]dart[\\/]pkg[\\/]([^\\/]+)[\\/]lib[\\/](.+)$');
|
| + var match = pattern.firstMatch(path);
|
| + var package;
|
| + if (match != null) {
|
| + package = match.group(1);
|
| + path = match.group(2);
|
| + }
|
| + // TODO(jacobr): add a second pattern for a more typical pub environment.
|
| + if (package != null) {
|
| + return 'package:$package/$path';
|
| + } else {
|
| + // TODO(jacobr): this is a lousy fallback.
|
| + print("Unable to determine package for $path.");
|
| + return mirror.uri.toString();
|
| + }
|
| + } else {
|
| + return mirror.uri.toString();
|
| + }
|
| + }
|
| +}
|
| +
|
| +/**
|
| + * Returns whether the class implements or extends [Error] or [Exception].
|
| + */
|
| +bool _isThrowable(ClassMirror mirror) {
|
| + if (mirror.library.uri.toString() == 'dart:core' &&
|
| + mirror.simpleName == 'Error' || mirror.simpleName == 'Exception')
|
| + return true;
|
| + if (mirror.superclass != null && _isThrowable(mirror.superclass))
|
| + return true;
|
| + return mirror.superinterfaces.any(_isThrowable);
|
| }
|
|
|
| /**
|
| @@ -134,11 +194,16 @@ class ClassElement extends Element {
|
| final bool isAbstract;
|
| /** Interfaces the class implements. */
|
| List<Reference> interfaces;
|
| + /** Whether the class implements or extends [Error] or [Exception]. */
|
| + bool isThrowable;
|
|
|
| - ClassElement(String name, ClassMirror mirror)
|
| - : super(mirror, 'class', mirror.simpleName, name, computeComment(mirror)),
|
| + ClassElement(String name, ClassMirror mirror,
|
| + MdnComment lookupMdnComment(Mirror))
|
| + : super(mirror, 'class', mirror.simpleName, name, computeComment(mirror),
|
| + lookupMdnComment),
|
| superclass = _optionalReference(mirror.superclass),
|
| isAbstract = _optionalBool(mirror.isAbstract) {
|
| + isThrowable = _optionalBool(_isThrowable(mirror));
|
| for (var interface in mirror.superinterfaces) {
|
| if (this.interfaces == null) {
|
| this.interfaces = <Reference>[];
|
| @@ -148,20 +213,22 @@ class ClassElement extends Element {
|
|
|
| mirror.methods.forEach((childName, childMirror) {
|
| if (!childMirror.isConstructor && !childMirror.isGetter) {
|
| - addChild(new MethodElement(childName, childMirror));
|
| + addChild(new MethodElement(childName, childMirror, lookupMdnComment));
|
| }
|
| });
|
|
|
| mirror.getters.forEach((childName, childMirror) {
|
| - addChild(new GetterElement(childName, childMirror));
|
| + addChild(new GetterElement(childName, childMirror, lookupMdnComment));
|
| });
|
|
|
| mirror.variables.forEach((childName, childMirror) {
|
| - addChild(new VariableElement(childName, childMirror));
|
| + addChild(new VariableElement(childName, childMirror,
|
| + lookupMdnComment));
|
| });
|
|
|
| mirror.constructors.forEach((constructorName, methodMirror) {
|
| - addChild(new MethodElement(constructorName, methodMirror, 'constructor'));
|
| + addChild(new MethodElement(constructorName, methodMirror,
|
| + lookupMdnComment, 'constructor'));
|
| });
|
|
|
| for (var typeVariable in mirror.originalDeclaration.typeVariables) {
|
| @@ -178,8 +245,10 @@ class GetterElement extends Element {
|
| final Reference ref;
|
| final bool isStatic;
|
|
|
| - GetterElement(String name, MethodMirror mirror)
|
| - : super(mirror, 'property', mirror.simpleName, name, computeComment(mirror)),
|
| + GetterElement(String name, MethodMirror mirror,
|
| + MdnComment lookupMdnComment(Mirror))
|
| + : super(mirror, 'property', mirror.simpleName, name, computeComment(mirror),
|
| + lookupMdnComment),
|
| ref = _optionalReference(mirror.returnType),
|
| isStatic = _optionalBool(mirror.isStatic);
|
| }
|
| @@ -194,9 +263,10 @@ class MethodElement extends Element {
|
| final bool isOperator;
|
| final bool isStatic;
|
|
|
| - MethodElement(String name, MethodMirror mirror, [String kind = 'method'])
|
| + MethodElement(String name, MethodMirror mirror,
|
| + MdnComment lookupMdnComment(Mirror), [String kind = 'method'])
|
| : super(mirror, kind, name, '$name${mirror.parameters.length}()',
|
| - computeComment(mirror)),
|
| + computeComment(mirror), lookupMdnComment),
|
| returnType = _optionalReference(mirror.returnType),
|
| isSetter = _optionalBool(mirror.isSetter),
|
| isOperator = _optionalBool(mirror.isOperator),
|
| @@ -214,13 +284,55 @@ class MethodElement extends Element {
|
| class ParameterElement extends Element {
|
| /** Type of the parameter. */
|
| final Reference ref;
|
| - /** Whether the parameter is optional. */
|
| +
|
| + /**
|
| + * Returns the default value for this parameter.
|
| + */
|
| + final String defaultValue;
|
| +
|
| + /**
|
| + * Is this parameter optional?
|
| + */
|
| final bool isOptional;
|
|
|
| + /**
|
| + * Is this parameter named?
|
| + */
|
| + final bool isNamed;
|
| +
|
| + /**
|
| + * Returns the initialized field, if this parameter is an initializing formal.
|
| + */
|
| + final Reference initializedField;
|
| +
|
| ParameterElement(ParameterMirror mirror)
|
| - : super(mirror, 'param', mirror.simpleName, mirror.simpleName, null),
|
| + : super(mirror, 'param', mirror.simpleName, mirror.simpleName, null,
|
| + null),
|
| ref = _optionalReference(mirror.type),
|
| - isOptional = _optionalBool(mirror.isOptional) {
|
| + isOptional = _optionalBool(mirror.isOptional),
|
| + defaultValue = mirror.defaultValue,
|
| + isNamed = _optionalBool(mirror.isNamed),
|
| + initializedField = _optionalReference(mirror.initializedField) {
|
| +
|
| + if (mirror.type is FunctionTypeMirror) {
|
| + addChild(new FunctionTypeElement(mirror.type));
|
| + }
|
| + }
|
| +}
|
| +
|
| +class FunctionTypeElement extends Element {
|
| + final Reference returnType;
|
| +
|
| + FunctionTypeElement(FunctionTypeMirror mirror)
|
| + : super(mirror, 'functiontype', mirror.simpleName, mirror.simpleName, null, null),
|
| + returnType = _optionalReference(mirror.returnType) {
|
| + for (var param in mirror.parameters) {
|
| + addChild(new ParameterElement(param));
|
| + }
|
| + // TODO(jacobr): can a FunctionTypeElement really have type variables?
|
| + for (var typeVariable in mirror.originalDeclaration.typeVariables) {
|
| + addChild(new TypeParameterElement(typeVariable));
|
| + }
|
| }
|
| }
|
|
|
| @@ -234,10 +346,11 @@ class TypeParameterElement extends Element {
|
| * In the following code sample, [:Bar:] is an upper bound:
|
| * [: class Bar<T extends Foo> { } :]
|
| */
|
| - Reference upperBound;
|
| + final Reference upperBound;
|
|
|
| TypeParameterElement(TypeMirror mirror)
|
| - : super(mirror, 'typeparam', mirror.simpleName, mirror.simpleName, null),
|
| + : super(mirror, 'typeparam', mirror.simpleName, mirror.simpleName, null,
|
| + null),
|
| upperBound = mirror.upperBound != null && !mirror.upperBound.isObject ?
|
| new Reference(mirror.upperBound) : null;
|
| }
|
| @@ -253,8 +366,10 @@ class VariableElement extends Element {
|
| /** Whether the variable is final. */
|
| final bool isFinal;
|
|
|
| - VariableElement(String name, VariableMirror mirror)
|
| - : super(mirror, 'variable', mirror.simpleName, name, null),
|
| + VariableElement(String name, VariableMirror mirror,
|
| + MdnComment lookupMdnComment(Mirror))
|
| + : super(mirror, 'variable', mirror.simpleName, name,
|
| + computeComment(mirror), lookupMdnComment),
|
| ref = _optionalReference(mirror.type),
|
| isStatic = _optionalBool(mirror.isStatic),
|
| isFinal = _optionalBool(mirror.isFinal);
|
| @@ -270,7 +385,7 @@ class TypedefElement extends Element {
|
|
|
| TypedefElement(String name, TypedefMirror mirror)
|
| : super(mirror, 'typedef', mirror.simpleName, name,
|
| - computeComment(mirror)),
|
| + computeComment(mirror), null),
|
| returnType = _optionalReference(mirror.value.returnType) {
|
| for (var param in mirror.value.parameters) {
|
| addChild(new ParameterElement(param));
|
| @@ -301,9 +416,13 @@ class Reference {
|
| }
|
| }
|
| }
|
| +
|
| + // TODO(jacobr): compute the referenceId correctly for the general case so
|
| + // that this method can work with all element types not just LibraryElements.
|
| + Reference.fromElement(LibraryElement e) : name = e.name, refId = e.id;
|
|
|
| static String getId(Mirror mirror) {
|
| - String id = mirror.simpleName;
|
| + String id = _escapeId(mirror.simpleName);
|
| if (mirror.owner != null) {
|
| id = '${getId(mirror.owner)}/$id';
|
| }
|
|
|