| 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
|
| new file mode 100755
|
| index 0000000000000000000000000000000000000000..c6c1ec082b29fe49e594cf5f5812baaa99c68ad9
|
| --- /dev/null
|
| +++ b/sdk/lib/_internal/dartdoc/lib/universe_serializer.dart
|
| @@ -0,0 +1,231 @@
|
| +// 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 '../../compiler/implementation/mirrors/mirrors.dart';
|
| +import '../../compiler/implementation/mirrors/mirrors_util.dart';
|
| +import '../../compiler/implementation/mirrors/dart2js_mirror.dart' as dart2js;
|
| +import '../../libraries.dart';
|
| +import 'dartdoc.dart';
|
| +
|
| +/**
|
| + * Base class for all nodes.
|
| + */
|
| +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;
|
| + /** Children of the node. */
|
| + List<Element> children;
|
| +
|
| + Element(this.kind, this.name, this.id, this.comment);
|
| +
|
| + void addChild(Element child) {
|
| + if (children == null) {
|
| + children = <Element>[];
|
| + }
|
| + children.add(child);
|
| + }
|
| +}
|
| +
|
| +/**
|
| + * Converts false to null. Useful as the serialization scheme we use
|
| + * omits null values.
|
| + */
|
| +bool _optionalBool(bool value) => value == true ? true : null;
|
| +
|
| +/**
|
| + * [Element] describing a Dart library.
|
| + */
|
| +class LibraryElement extends Element {
|
| + LibraryElement(String name, LibraryMirror mirror, CommentMap comments)
|
| + : super('library', name, mirror.uri.toString(),
|
| + comments.findLibrary(mirror.location)) {
|
| +
|
| + mirror.functions.forEach((childName, childMirror) {
|
| + addChild(new MethodElement(childName, childMirror, comments));
|
| + });
|
| +
|
| + mirror.getters.forEach((childName, childMirror) {
|
| + addChild(new GetterElement(childName, childMirror, comments));
|
| + });
|
| +
|
| + mirror.variables.forEach((childName, childMirror) {
|
| + addChild(new VariableElement(childName, childMirror));
|
| + });
|
| +
|
| + mirror.classes.forEach((className, classMirror) {
|
| + if (!classMirror.isPrivate) {
|
| + if (classMirror is TypedefMirror) {
|
| + addChild(new TypedefElement(className, classMirror, comments));
|
| + } else {
|
| + addChild(new ClassElement(className, classMirror, comments));
|
| + }
|
| + }
|
| + });
|
| + }
|
| +}
|
| +
|
| +/**
|
| + * [Element] describing a Dart class.
|
| + */
|
| +class ClassElement extends Element {
|
| + /** Base class.*/
|
| + final Reference superclass;
|
| + /** Interfaces the class implements. */
|
| + List<Reference> interfaces;
|
| +
|
| + ClassElement(String name, ClassMirror mirror, CommentMap comments)
|
| + : super('class', mirror.simpleName, name,
|
| + comments.find(mirror.location)),
|
| + superclass = mirror.superclass != null ?
|
| + new Reference(mirror.superclass) : null {
|
| + for (var interface in mirror.superinterfaces) {
|
| + if (this.interfaces == null) {
|
| + this.interfaces = <Reference>[];
|
| + }
|
| + this.interfaces.add(new Reference(interface));
|
| + }
|
| +
|
| + mirror.methods.forEach((childName, childMirror) {
|
| + addChild(new MethodElement(childName, childMirror, comments));
|
| + });
|
| +
|
| + mirror.getters.forEach((childName, childMirror) {
|
| + addChild(new GetterElement(childName, childMirror, comments));
|
| + });
|
| +
|
| + mirror.variables.forEach((childName, childMirror) {
|
| + addChild(new VariableElement(childName, childMirror));
|
| + });
|
| +
|
| + mirror.constructors.forEach((constructorName, methodMirror) {
|
| + addChild(new MethodElement(constructorName, methodMirror, comments, 'constructor'));
|
| + });
|
| + }
|
| +}
|
| +
|
| +/**
|
| + * [Element] describing a getter.
|
| + */
|
| +class GetterElement extends Element {
|
| + /** Type of the getter. */
|
| + final Reference ref;
|
| + final bool isStatic;
|
| +
|
| + GetterElement(String name, MethodMirror mirror, CommentMap comments)
|
| + : super('property', mirror.simpleName, name,
|
| + comments.find(mirror.location)),
|
| + ref = mirror.returnType != null ?
|
| + new Reference(mirror.returnType) : null,
|
| + 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, CommentMap comments, [String kind = 'method'])
|
| + : super(kind, name, '$name${mirror.parameters.length}()',
|
| + comments.find(mirror.location)),
|
| + returnType = mirror.returnType != null ?
|
| + new Reference(mirror.returnType) : null,
|
| + 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;
|
| + /** Whether the parameter is optional. */
|
| + final bool isOptional;
|
| +
|
| + ParameterElement(ParameterMirror mirror)
|
| + : super('param', mirror.simpleName, mirror.simpleName, null),
|
| + ref = new Reference(mirror.type),
|
| + isOptional = _optionalBool(mirror.isOptional) {
|
| + }
|
| +}
|
| +
|
| +/**
|
| + * Element describing a variable.
|
| + */
|
| +class VariableElement extends Element {
|
| + /** Type of the variable. */
|
| + final Reference ref;
|
| + final bool isStatic;
|
| +
|
| + VariableElement(String name, VariableMirror mirror)
|
| + : super('property', mirror.simpleName, name, null),
|
| + ref = new Reference(mirror.type),
|
| + isStatic = _optionalBool(mirror.isStatic);
|
| +}
|
| +// TODO(jacobr): this seems incomplete.
|
| +/**
|
| + * Element describing a typedef element.
|
| + */
|
| +class TypedefElement extends Element {
|
| + TypedefElement(String name, TypedefMirror mirror, CommentMap comments)
|
| + : super('typedef', mirror.simpleName, name,
|
| + comments.find(mirror.location));
|
| +}
|
| +
|
| +/**
|
| + * Reference to an Element with type argument if the reference is parameterized.
|
| + */
|
| +class Reference {
|
| + final String name;
|
| + final String refId;
|
| + List<Reference> arguments;
|
| +
|
| + Reference(Mirror mirror)
|
| + : name = mirror.simpleName,
|
| + refId = getId(mirror) {
|
| + if (mirror is ClassMirror) {
|
| + if (mirror is !TypedefMirror
|
| + && mirror.typeArguments.length > 0) {
|
| + arguments = <Reference>[];
|
| + for (var typeArg in mirror.typeArguments) {
|
| + arguments.add(new Reference(typeArg));
|
| + }
|
| + }
|
| + }
|
| + }
|
| +
|
| + static String getId(Mirror mirror) {
|
| + String id = mirror.simpleName;
|
| + if (mirror is MemberMirror) {
|
| + MemberMirror memberMirror = mirror;
|
| + if (memberMirror.owner != null) {
|
| + id = '${getId(memberMirror.owner)}/$id';
|
| + }
|
| + }
|
| + return id;
|
| + }
|
| +}
|
|
|