| Index: sdk/lib/_internal/dartdoc/lib/universe_serializer.dart
|
| ===================================================================
|
| --- sdk/lib/_internal/dartdoc/lib/universe_serializer.dart (revision 32349)
|
| +++ sdk/lib/_internal/dartdoc/lib/universe_serializer.dart (working copy)
|
| @@ -1,541 +0,0 @@
|
| -// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
| -// 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.
|
| -
|
| -/**
|
| - * This library serializes the Dart2Js AST into a compact and easy to use
|
| - * [Element] tree useful for code exploration tools such as DartDoc.
|
| - */
|
| -library universe_serializer;
|
| -
|
| -import 'dartdoc.dart';
|
| -
|
| -// TODO(rnystrom): Use "package:" URL (#4968).
|
| -import 'package:path/path.dart' as path;
|
| -import '../../compiler/implementation/mirrors/source_mirrors.dart';
|
| -import '../../compiler/implementation/mirrors/mirrors_util.dart';
|
| -
|
| -String _stripUri(String uri) {
|
| - String prefix = "/dart/";
|
| - int start = uri.indexOf(prefix);
|
| - if (start != -1) {
|
| - return uri.substring(start + prefix.length);
|
| - } else {
|
| - return uri;
|
| - }
|
| -}
|
| -
|
| -String _escapeId(String id) {
|
| - return id.replaceAll(new RegExp('[/]'), '#slash');
|
| -}
|
| -
|
| -/**
|
| - * Base class for all elements in the AST.
|
| - */
|
| -class Element {
|
| - /** Human readable type name for the node. */
|
| - final String kind;
|
| - /** Human readable name for the element. */
|
| - final String name;
|
| - /** Id for the node that is unique within its parent's children. */
|
| - 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. */
|
| - final bool isPrivate;
|
| -
|
| - /**
|
| - * Uri containing the definition of the element.
|
| - */
|
| - String uri;
|
| - /**
|
| - * Line in the original source file that starts the definition of the element.
|
| - */
|
| - String line;
|
| -
|
| - // TODO(jacobr): refactor the code so that lookupMdnComment does not need to
|
| - // be passed to every Element constructor.
|
| - Element(DeclarationMirror 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()) {
|
| - if (lookupMdnComment != null) {
|
| - var mdnComment = lookupMdnComment(mirror);
|
| - if (mdnComment != null) {
|
| - mdnCommentHtml = mdnComment.mdnComment;
|
| - mdnUrl = mdnComment.mdnUrl;
|
| - }
|
| - }
|
| - }
|
| -
|
| - void addChild(Element child) {
|
| - if (children == null) {
|
| - children = <Element>[];
|
| - }
|
| - children.add(child);
|
| - }
|
| -
|
| - /**
|
| - * Remove all URIs that exactly match the parent node's URI.
|
| - * This reduces output file size by about 20%.
|
| - */
|
| - void stripDuplicateUris(String parentUri, parentLine) {
|
| - if (children != null) {
|
| - for (var child in children) {
|
| - child.stripDuplicateUris(uri, line);
|
| - }
|
| - }
|
| - if (parentUri == uri) {
|
| - uri = null;
|
| - }
|
| - if (line == parentLine) {
|
| - line = null;
|
| - }
|
| - }
|
| -}
|
| -
|
| -/**
|
| - * Converts false to null. Useful as the serialization scheme we use
|
| - * omits null values.
|
| - */
|
| -bool _optionalBool(bool value) => value == true ? true : null;
|
| -
|
| -Reference _optionalReference(DeclarationMirror mirror) {
|
| - return (mirror != null && nameOf(mirror) != "Dynamic_" &&
|
| - nameOf(mirror) != "dynamic") ?
|
| - new Reference(mirror) : null;
|
| -}
|
| -
|
| -/**
|
| - * Helper class to track what members of a library should be included.
|
| - */
|
| -class LibrarySubset {
|
| - final LibraryMirror library;
|
| - Set<String> includedChildren;
|
| -
|
| - LibrarySubset(this.library) : includedChildren = new Set<String>();
|
| -}
|
| -
|
| -/**
|
| - * [Element] describing a Dart library.
|
| - */
|
| -class LibraryElement extends Element {
|
| - /**
|
| - * Partial versions of LibraryElements containing classes that are extended
|
| - * or implemented by classes in this library.
|
| - */
|
| - List<LibraryElement> dependencies;
|
| -
|
| - /**
|
| - * Construct a LibraryElement from a [mirror].
|
| - *
|
| - * If [includedChildren] is specified, only elements matching names in
|
| - * [includedChildren] are included and no dependencies are included.
|
| - * [lookupMdnComment] is an optional function that returns the MDN
|
| - * documentation for elements. [dependencies] is an optional map
|
| - * tracking all classes dependend on by this [ClassElement].
|
| - */
|
| - LibraryElement(LibraryMirror mirror,
|
| - {MdnComment lookupMdnComment(Mirror), Set<String> includedChildren})
|
| - : super(mirror, 'library', _libraryName(mirror), nameOf(mirror),
|
| - computeComment(mirror), lookupMdnComment) {
|
| - var requiredDependencies;
|
| - // We don't need to track our required dependencies when generating a
|
| - // filtered version of this library which will be used as a dependency for
|
| - // another library.
|
| - if (includedChildren == null)
|
| - requiredDependencies = new Map<String, LibrarySubset>();
|
| - methodsOf(mirror.declarations).forEach((childMirror) {
|
| - var childName = nameOf(childMirror);
|
| - if (includedChildren == null || includedChildren.contains(childName))
|
| - addChild(new MethodElement(childName, childMirror, lookupMdnComment));
|
| - });
|
| -
|
| - gettersOf(mirror.declarations).forEach((childMirror) {
|
| - var childName = nameOf(childMirror);
|
| - if (includedChildren == null || includedChildren.contains(childName))
|
| - addChild(new GetterElement(childName, childMirror, lookupMdnComment));
|
| - });
|
| -
|
| - variablesOf(mirror.declarations).forEach((childMirror) {
|
| - var childName = nameOf(childMirror);
|
| - if (includedChildren == null || includedChildren.contains(childName))
|
| - addChild(new VariableElement(childName, childMirror, lookupMdnComment));
|
| - });
|
| -
|
| - typesOf(mirror.declarations).forEach((classMirror) {
|
| - var className = nameOf(classMirror);
|
| - if (includedChildren == null || includedChildren.contains(className)) {
|
| - if (classMirror is TypedefMirror) {
|
| - addChild(new TypedefElement(className, classMirror));
|
| - } else {
|
| - addChild(new ClassElement(classMirror,
|
| - dependencies: requiredDependencies,
|
| - lookupMdnComment: lookupMdnComment));
|
| - }
|
| - }
|
| - });
|
| -
|
| - if (requiredDependencies != null && !requiredDependencies.isEmpty) {
|
| - dependencies = requiredDependencies.values.map((librarySubset) =>
|
| - new LibraryElement(
|
| - librarySubset.library,
|
| - lookupMdnComment: lookupMdnComment,
|
| - includedChildren: librarySubset.includedChildren)).toList();
|
| - }
|
| - }
|
| -
|
| - 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 uriPath = uri.path;
|
| -
|
| - var parts = path.split(uriPath);
|
| -
|
| - // Find either pkg/ or packages/
|
| - var pkgDir = parts.lastIndexOf('pkg');
|
| - var packageDir = parts.lastIndexOf('packages');
|
| -
|
| - if (pkgDir >= 0) {
|
| - packageDir = pkgDir;
|
| - }
|
| -
|
| - var libDir = parts.lastIndexOf('lib');
|
| - var rest = parts.sublist(libDir + 1);
|
| -
|
| - // If there's no lib, we can't find the package.
|
| - if (libDir < 0 || libDir < packageDir) {
|
| - // TODO(jacobr): this is a lousy fallback.
|
| - print("Unable to determine package for $uriPath.");
|
| - return mirror.uri.toString();
|
| - } else if (packageDir >= 0 && rest.length >= 1) {
|
| - // For URI: foo/bar/packages/widget/lib/sprocket.dart will return:
|
| - // 'package:widget/sprocket.dart'
|
| - return 'package:${parts[packageDir + 1]}/${rest.join('/')}';
|
| - }
|
| - } else {
|
| - return mirror.uri.toString();
|
| - }
|
| - }
|
| -
|
| - void stripDuplicateUris(String parentUri, parentLine) {
|
| - super.stripDuplicateUris(parentUri, parentLine);
|
| -
|
| - if (dependencies != null) {
|
| - for (var child in dependencies) {
|
| - child.stripDuplicateUris(null, null);
|
| - }
|
| - }
|
| - }
|
| -}
|
| -
|
| -/**
|
| - * Returns whether the class implements or extends [Error] or [Exception].
|
| - */
|
| -bool _isThrowable(ClassMirror mirror) {
|
| - if (getLibrary(mirror).uri.toString() == 'dart:core' &&
|
| - nameOf(mirror) == 'Error' || nameOf(mirror) == 'Exception')
|
| - return true;
|
| - if (mirror.superclass != null && _isThrowable(mirror.superclass))
|
| - return true;
|
| - return mirror.superinterfaces.any(_isThrowable);
|
| -}
|
| -
|
| -/**
|
| - * [Element] describing a Dart class.
|
| - */
|
| -class ClassElement extends Element {
|
| - /** Base class.*/
|
| - final Reference superclass;
|
| - /** Whether the class is abstract. */
|
| - final bool isAbstract;
|
| - /** Interfaces the class implements. */
|
| - List<Reference> interfaces;
|
| - /** Whether the class implements or extends [Error] or [Exception]. */
|
| - bool isThrowable;
|
| -
|
| - /**
|
| - * Constructs a [ClassElement] from a [ClassMirror].
|
| - *
|
| - * [dependencies] is an optional map updated as a side effect of running
|
| - * this constructor that tracks what classes from other libraries are
|
| - * dependencies of classes in this library. A class is considered a
|
| - * dependency if it implements or extends another class.
|
| - * [lookupMdnComment] is an optional function that returns the MDN
|
| - * documentation for elements. [dependencies] is an optional map
|
| - * tracking all classes dependend on by this [ClassElement].
|
| - */
|
| - ClassElement(ClassSourceMirror mirror,
|
| - {Map<String, LibrarySubset> dependencies,
|
| - MdnComment lookupMdnComment(Mirror)})
|
| - : super(mirror, 'class', nameOf(mirror),
|
| - nameOf(mirror), computeComment(mirror),
|
| - lookupMdnComment),
|
| - superclass = _optionalReference(mirror.superclass),
|
| - isAbstract = _optionalBool(mirror.isAbstract),
|
| - isThrowable = _optionalBool(_isThrowable(mirror)){
|
| -
|
| - addCrossLibraryDependencies(clazz) {
|
| - if (clazz == null) return;
|
| -
|
| - var clazzLibrary = getLibrary(clazz);
|
| - if (getLibrary(mirror) != clazzLibrary) {
|
| - String name = nameOf(clazz);
|
| - var libraryStub = dependencies.putIfAbsent(name,
|
| - () => new LibrarySubset(clazzLibrary));
|
| - libraryStub.includedChildren.add(name);
|
| - }
|
| -
|
| - for (var interface in clazz.superinterfaces) {
|
| - addCrossLibraryDependencies(interface);
|
| - }
|
| - addCrossLibraryDependencies(clazz.superclass);
|
| - }
|
| -
|
| - if (dependencies != null) {
|
| - addCrossLibraryDependencies(mirror);
|
| - }
|
| -
|
| - for (var interface in mirror.superinterfaces) {
|
| - if (this.interfaces == null) {
|
| - this.interfaces = <Reference>[];
|
| - }
|
| - this.interfaces.add(_optionalReference(interface));
|
| - }
|
| -
|
| - methodsOf(mirror.declarations).forEach((childMirror) {
|
| - String childName = nameOf(childMirror);
|
| - addChild(new MethodElement(childName, childMirror, lookupMdnComment));
|
| - });
|
| -
|
| - gettersOf(mirror.declarations).forEach((childMirror) {
|
| - String childName = nameOf(childMirror);
|
| - addChild(new GetterElement(childName, childMirror, lookupMdnComment));
|
| - });
|
| -
|
| - variablesOf(mirror.declarations).forEach((childMirror) {
|
| - String childName = nameOf(childMirror);
|
| - addChild(new VariableElement(childName, childMirror,
|
| - lookupMdnComment));
|
| - });
|
| -
|
| - constructorsOf(mirror.declarations).forEach((methodMirror) {
|
| - String constructorName = nameOf(methodMirror);
|
| - addChild(new MethodElement(constructorName, methodMirror,
|
| - lookupMdnComment, 'constructor'));
|
| - });
|
| -
|
| - for (var typeVariable in mirror.originalDeclaration.typeVariables) {
|
| - addChild(new TypeParameterElement(typeVariable));
|
| - }
|
| - }
|
| -}
|
| -
|
| -/**
|
| - * [Element] describing a getter.
|
| - */
|
| -class GetterElement extends Element {
|
| - /** Type of the getter. */
|
| - final Reference ref;
|
| - final bool isStatic;
|
| -
|
| - GetterElement(String name, MethodMirror mirror,
|
| - MdnComment lookupMdnComment(Mirror))
|
| - : super(mirror, 'property', nameOf(mirror),
|
| - name, computeComment(mirror), lookupMdnComment),
|
| - ref = _optionalReference(mirror.returnType),
|
| - isStatic = _optionalBool(mirror.isStatic);
|
| -}
|
| -
|
| -/**
|
| - * [Element] describing a method which may be a regular method, a setter, or an
|
| - * operator.
|
| - */
|
| -class MethodElement extends Element {
|
| - final Reference returnType;
|
| - final bool isSetter;
|
| - final bool isOperator;
|
| - final bool isStatic;
|
| -
|
| - MethodElement(String name, MethodMirror mirror,
|
| - MdnComment lookupMdnComment(Mirror), [String kind = 'method'])
|
| - : super(mirror, kind, name, '$name${mirror.parameters.length}()',
|
| - computeComment(mirror), lookupMdnComment),
|
| - returnType = _optionalReference(mirror.returnType),
|
| - isSetter = _optionalBool(mirror.isSetter),
|
| - isOperator = _optionalBool(mirror.isOperator),
|
| - isStatic = _optionalBool(mirror.isStatic) {
|
| -
|
| - for (var param in mirror.parameters) {
|
| - addChild(new ParameterElement(param));
|
| - }
|
| - }
|
| -}
|
| -
|
| -/**
|
| - * Element describing a parameter.
|
| - */
|
| -class ParameterElement extends Element {
|
| - /** Type of the parameter. */
|
| - final Reference ref;
|
| -
|
| - /**
|
| - * 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(ParameterSourceMirror mirror)
|
| - : super(mirror, 'param', nameOf(mirror),
|
| - nameOf(mirror), null, null),
|
| - ref = _optionalReference(mirror.type),
|
| - 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', nameOf(mirror),
|
| - nameOf(mirror), 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));
|
| - }
|
| - }
|
| -}
|
| -
|
| -/**
|
| - * Element describing a generic type parameter.
|
| - */
|
| -class TypeParameterElement extends Element {
|
| - /**
|
| - * Upper bound for the parameter.
|
| - *
|
| - * In the following code sample, [:Bar:] is an upper bound:
|
| - * [: class Bar<T extends Foo> { } :]
|
| - */
|
| - final Reference upperBound;
|
| -
|
| - TypeParameterElement(TypeVariableMirror mirror)
|
| - : super(mirror, 'typeparam', nameOf(mirror),
|
| - nameOf(mirror), null, null),
|
| - upperBound = mirror.upperBound != null && !isObject(mirror.upperBound) ?
|
| - new Reference(mirror.upperBound) : null;
|
| -}
|
| -
|
| -/**
|
| - * Element describing a variable.
|
| - */
|
| -class VariableElement extends Element {
|
| - /** Type of the variable. */
|
| - final Reference ref;
|
| - /** Whether the variable is static. */
|
| - final bool isStatic;
|
| - /** Whether the variable is final. */
|
| - final bool isFinal;
|
| -
|
| - VariableElement(String name, VariableMirror mirror,
|
| - MdnComment lookupMdnComment(Mirror))
|
| - : super(mirror, 'variable', nameOf(mirror), name,
|
| - computeComment(mirror), lookupMdnComment),
|
| - ref = _optionalReference(mirror.type),
|
| - isStatic = _optionalBool(mirror.isStatic),
|
| - isFinal = _optionalBool(mirror.isFinal);
|
| -}
|
| -
|
| -/**
|
| - * Element describing a typedef.
|
| - */
|
| -
|
| -class TypedefElement extends Element {
|
| - /** Return type of the typedef. */
|
| - final Reference returnType;
|
| -
|
| - TypedefElement(String name, TypedefMirror mirror)
|
| - : super(mirror, 'typedef', nameOf(mirror), name,
|
| - computeComment(mirror), null),
|
| - returnType = _optionalReference(mirror.referent.returnType) {
|
| - for (var param in mirror.referent.parameters) {
|
| - addChild(new ParameterElement(param));
|
| - }
|
| - for (var typeVariable in mirror.originalDeclaration.typeVariables) {
|
| - addChild(new TypeParameterElement(typeVariable));
|
| - }
|
| - }
|
| -}
|
| -
|
| -/**
|
| - * Reference to an Element with type argument if the reference is parameterized.
|
| - */
|
| -class Reference {
|
| - final String name;
|
| - final String refId;
|
| - List<Reference> arguments;
|
| -
|
| - Reference(DeclarationMirror mirror)
|
| - : name = displayName(mirror),
|
| - refId = getId(mirror) {
|
| - if (mirror is ClassMirror) {
|
| - if (mirror is !TypedefMirror && !mirror.typeArguments.isEmpty) {
|
| - arguments = <Reference>[];
|
| - for (var typeArg in mirror.typeArguments) {
|
| - arguments.add(_optionalReference(typeArg));
|
| - }
|
| - }
|
| - }
|
| - }
|
| -
|
| - // 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(DeclarationMirror mirror) {
|
| - String id = _escapeId(nameOf(mirror));
|
| - if (mirror.owner != null) {
|
| - id = '${getId(mirror.owner)}/$id';
|
| - }
|
| - return id;
|
| - }
|
| -}
|
|
|