| Index: client/web/ast.dart
|
| diff --git a/client/web/ast.dart b/client/web/ast.dart
|
| index 1a4801c58d00730f0df700dc1065ed13d742319b..02113ec9738fe40ccea15aeb701f2a8890832806 100644
|
| --- a/client/web/ast.dart
|
| +++ b/client/web/ast.dart
|
| @@ -1,3 +1,11 @@
|
| +// Copyright (c) 2013, 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.
|
| +
|
| +/**
|
| + * AST describing all information about Dart libraries required to render
|
| + * Dart documentation.
|
| + */
|
| library ast;
|
|
|
| import 'package:web_ui/safe_html.dart';
|
| @@ -11,95 +19,34 @@ import 'markdown.dart' as md;
|
| */
|
| Map<String, LibraryElement> libraries = <LibraryElement>{};
|
|
|
| -List<String> LIBRARY_KINDS = ['variable', 'property', 'method', 'class', 'exception', 'typedef'];
|
| -List<String> CLASS_KINDS = ['constructor', 'variable', 'property', 'method', 'operator'];
|
| -// TODO(jacobr): add package kinds?
|
| -
|
| -// TODO(jacobr): i18n
|
| /**
|
| - * Pretty names for the various kinds displayed.
|
| + * Children of a library are shown in the UI grouped by type sorted in the order
|
| + * specified by this list.
|
| */
|
| -final KIND_TITLES = {'property': 'Properties',
|
| - 'variable': 'Variables',
|
| - 'method': 'Functions',
|
| - 'constructor': 'Constructors',
|
| - 'class': 'Classes',
|
| - 'operator': 'Operators',
|
| - 'typedef': 'Typedefs',
|
| - 'exception': 'Exceptions'
|
| -};
|
| -
|
| +List<String> LIBRARY_ITEMS = ['variable', 'property', 'method', 'class',
|
| + 'exception', 'typedef'];
|
| /**
|
| - * Block of elements to render summary documentation for that all share the
|
| - * same kind.
|
| - *
|
| - * For example, all properties, all functions, or all constructors.
|
| + * Children of a class are shown in the UI grouped by type sorted in the order
|
| + * specified by this list.
|
| */
|
| -class ElementBlock {
|
| - String kind;
|
| - List<Element> elements;
|
| -
|
| - ElementBlock(this.kind, this.elements);
|
| -
|
| - String get kindTitle => KIND_TITLES[kind];
|
| -}
|
| -
|
| -Reference jsonDeserializeReference(Map json) {
|
| - return json != null ? new Reference(json) : null;
|
| -}
|
| +List<String> CLASS_ITEMS = ['constructor', 'variable', 'property', 'method',
|
| + 'operator'];
|
| +// TODO(jacobr): add package kinds?
|
|
|
| +// TODO(jacobr): i18n
|
| /**
|
| - * Deserializes JSON into [Element] or [Reference] objects.
|
| + * Pretty names for the various kinds displayed.
|
| */
|
| -Element jsonDeserialize(Map json, Element parent) {
|
| - if (json == null) return null;
|
| - if (!json.containsKey('kind')) {
|
| - throw "Unable to deserialize $json";
|
| - }
|
| -
|
| - switch (json['kind']) {
|
| - case 'class':
|
| - return new ClassElement(json, parent);
|
| - case 'typedef':
|
| - return new TypedefElement(json, parent);
|
| - case 'typeparam':
|
| - return new TypeParameterElement(json, parent);
|
| - case 'library':
|
| - return new LibraryElement(json, parent);
|
| - case 'method':
|
| - return new MethodElement(json, parent);
|
| - case 'property':
|
| - return new PropertyElement(json, parent);
|
| - case 'constructor':
|
| - return new ConstructorElement(json, parent);
|
| - case 'variable':
|
| - return new VariableElement(json, parent);
|
| - case 'param':
|
| - return new ParameterElement(json, parent);
|
| - default:
|
| - return new Element(json, parent);
|
| - }
|
| -}
|
| -
|
| -List<Element> jsonDeserializeArray(List json, Element parent) {
|
| - var ret = <Element>[];
|
| - if (json != null) {
|
| - for (Map elementJson in json) {
|
| - ret.add(jsonDeserialize(elementJson, parent));
|
| - }
|
| - }
|
| - return ret;
|
| -}
|
| -
|
| -List<Reference> jsonDeserializeReferenceArray(List json) {
|
| - var ret = <Reference>[];
|
| - if (json != null) {
|
| - for (Map referenceJson in json) {
|
| - ret.add(new Reference(referenceJson));
|
| - }
|
| - }
|
| - return ret;
|
| -}
|
| +final KIND_TITLES = {
|
| + 'property': 'Properties',
|
| + 'variable': 'Variables',
|
| + 'method': 'Functions',
|
| + 'constructor': 'Constructors',
|
| + 'class': 'Classes',
|
| + 'operator': 'Operators',
|
| + 'typedef': 'Typedefs',
|
| + 'exception': 'Exceptions'
|
| +};
|
|
|
| /**
|
| * Reference to an [Element].
|
| @@ -107,22 +54,33 @@ List<Reference> jsonDeserializeReferenceArray(List json) {
|
| class Reference {
|
| final String refId;
|
| final String name;
|
| + final List<Reference> arguments;
|
| +
|
| Reference(Map json) :
|
| name = json['name'],
|
| - refId = json['refId'];
|
| + refId = json['refId'],
|
| + arguments = _jsonDeserializeReferenceArray(json['arguments']);
|
| +
|
| + /**
|
| + * Short description appropriate for displaying in a tree control or other
|
| + * situtation where a short description is required.
|
| + */
|
| + String get shortDescription {
|
| + if (arguments.isEmpty) {
|
| + return name;
|
| + } else {
|
| + var params = Strings.join(
|
| + arguments.map((param) => param.shortDescription), ', ');
|
| + return '$name<$params>';
|
| + }
|
| + }
|
| }
|
|
|
| /**
|
| * Lookup a library based on the [libraryId].
|
| - *
|
| - * If the library cannot be found, a stub dummy [Library] will be returned.
|
| */
|
| LibraryElement lookupLibrary(String libraryId) {
|
| - var library = libraries[libraryId];
|
| - if (library == null) {
|
| - library = new LibraryElement.stub(libraryId, null);
|
| - }
|
| - return library;
|
| + return libraries[libraryId];
|
| }
|
|
|
| /**
|
| @@ -133,8 +91,7 @@ LibraryElement lookupLibrary(String libraryId) {
|
| Element lookupReferenceId(String referenceId) {
|
| var parts = referenceId.split(new RegExp('/'));
|
| Element current = lookupLibrary(parts.first);
|
| - var result = <Element>[current];
|
| - for (var i = 1; i < parts.length; i++) {
|
| + for (var i = 1; i < parts.length && current != null; i++) {
|
| var id = parts[i];
|
| var next = null;
|
| for (var child in current.children) {
|
| @@ -143,9 +100,6 @@ Element lookupReferenceId(String referenceId) {
|
| break;
|
| }
|
| }
|
| - if (next == null) {
|
| - next = new Element.stub(id, current);
|
| - }
|
| current = next;
|
| }
|
| return current;
|
| @@ -160,74 +114,73 @@ _traverseWorld(void callback(Element)) {
|
| }
|
| }
|
|
|
| -// TODO(jacobr): remove this method when templates handle safe HTML containing
|
| +// TODO(jacobr): remove this method when templates handle [SafeHTML] containing
|
| +// multiple top level nodes correct.
|
| SafeHtml _markdownToSafeHtml(String text) {
|
| // We currently have to insert an extra span for now because of
|
| - // https://github.com/dart-lang/dart-web-components/issues/212
|
| + // https://github.com/dart-lang/web-ui/issues/212
|
| return new SafeHtml.unsafe(text != null && !text.isEmpty ?
|
| '<span>${md.markdownToHtml(text)}</span>' : '<span><span>');
|
| }
|
|
|
| /**
|
| - * Specifies the order elements should appear in the UI.
|
| - */
|
| -int elementUiOrder(Element a, Element b) {
|
| - if (a.isPrivate != b.isPrivate) {
|
| - return a.isPrivate == true ? 1 : -1;
|
| - }
|
| - return a.name.compareTo(b.name);
|
| -}
|
| -
|
| -/**
|
| * Base class for all elements in the AST.
|
| */
|
| -class Element {
|
| +class Element implements Comparable {
|
| final Element parent;
|
| +
|
| /** Human readable type name for the node. */
|
| final String rawKind;
|
| +
|
| /** 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;
|
| +
|
| /** Whether the node is private. */
|
| final bool isPrivate;
|
|
|
| - final String _uri;
|
| - final String _line;
|
| -
|
| /** Children of the node. */
|
| List<Element> children;
|
|
|
| /** Whether the [Element] is currently being loaded. */
|
| final bool loading;
|
|
|
| + final String _uri;
|
| + final String _line;
|
| String _refId;
|
| -
|
| - Map _members;
|
| SafeHtml _commentHtml;
|
| List<Element> _references;
|
| + List<Element> _typeParameters;
|
|
|
| Element(Map json, this.parent) :
|
| name = json['name'],
|
| rawKind = json['kind'],
|
| id = json['id'],
|
| comment = json['comment'],
|
| - isPrivate = json['isPrivate'],
|
| + isPrivate = json['isPrivate'] == true,
|
| _uri = json['uri'],
|
| _line = json['line'],
|
| loading = false {
|
| - children = jsonDeserializeArray(json['children'], this);
|
| + children = _jsonDeserializeArray(json['children'], this);
|
| }
|
|
|
| /**
|
| * Returns a kind name that make sense for the UI rather than the AST
|
| * kinds. For example, setters are considered properties instead of
|
| - * methods.
|
| + * methods in the UI but not the AST.
|
| */
|
| String get uiKind => kind;
|
|
|
| + /**
|
| + * Longer possibly multiple word description of the [kind].
|
| + */
|
| + String get kindDescription => uiKind;
|
| +
|
| /** Invoke [callback] on this [Element] and all descendants. */
|
| void traverse(void callback(Element)) {
|
| callback(this);
|
| @@ -237,49 +190,22 @@ class Element {
|
| }
|
|
|
| /**
|
| - * Uri containing the definition of the element.
|
| + * Uri containing the source code for the definition of the element.
|
| */
|
| - String get uri {
|
| - Element current = this;
|
| - while (current != null) {
|
| - if (current._uri != null) return current._uri;
|
| - current = current.parent;
|
| - }
|
| - return null;
|
| - }
|
| + String get uri => _uri != null ? _uri : (parent != null ? parent.uri : null);
|
|
|
| /**
|
| - * Line in the original source file that starts the definition of the element.
|
| + * Line in the original source file that begins the definition of the element.
|
| */
|
| - String get line {
|
| - Element current = this;
|
| - while (current != null) {
|
| - if (current._line != null) return current._line;
|
| - current = current.parent;
|
| - }
|
| - return null;
|
| - }
|
| -
|
| - Element.stub(this.id, this.parent) :
|
| - name = '???', // TODO(jacobr): remove/add
|
| - _uri = null,
|
| - _line = null,
|
| - comment = null,
|
| - rawKind = null,
|
| - children = <Element>[],
|
| - isPrivate = null,
|
| - loading = true;
|
| + String get line => _line != null ?
|
| + _line : (parent != null ? parent.line : null);
|
|
|
| /**
|
| * Globally unique identifier for this element.
|
| */
|
| String get refId {
|
| if (_refId == null) {
|
| - if (parent == null) {
|
| - _refId = id;
|
| - } else {
|
| - _refId = '${parent.refId}/$id';
|
| - }
|
| + _refId = (parent == null) ? id : '${parent.refId}/$id';
|
| }
|
| return _refId;
|
| }
|
| @@ -287,20 +213,13 @@ class Element {
|
| /**
|
| * Whether this [Element] references the specified [referenceId].
|
| */
|
| - bool hasReference(String referenceId) {
|
| - for (var child in children) {
|
| - if (child.hasReference(referenceId)) {
|
| - return true;
|
| - }
|
| - }
|
| - return false;
|
| - }
|
| + bool hasReference(String referenceId) =>
|
| + children.some((child) => child.hasReference(referenceId));
|
|
|
| /** Returns all [Element]s that reference this [Element]. */
|
| List<Element> get references {
|
| if (_references == null) {
|
| _references = <Element>[];
|
| - // TODO(jacobr): change to filterWorld and tweak meaning.
|
| _traverseWorld((element) {
|
| if (element.hasReference(refId)) {
|
| _references.add(element);
|
| @@ -310,16 +229,23 @@ class Element {
|
| return _references;
|
| }
|
|
|
| - // TODO(jacobr): write without recursion.
|
| - /**
|
| - * Path from this [Element] to the root of the tree starting at the root.
|
| - */
|
| + /** Path from the root of the tree to this [Element]. */
|
| List<Element> get path {
|
| if (parent == null) {
|
| return <Element>[this];
|
| } else {
|
| return parent.path..add(this);
|
| }
|
| + // TODO(jacobr): replace this code with:
|
| + // return parent == null ? <Element>[this]) : parent.path..add(this);
|
| + // once http://code.google.com/p/dart/issues/detail?id=7665 is fixed.
|
| + }
|
| +
|
| + List<Element> get typeParameters {
|
| + if (_typeParameters == null) {
|
| + _typeParameters = _filterByKind('typeparam');
|
| + }
|
| + return _typeParameters;
|
| }
|
|
|
| /**
|
| @@ -337,9 +263,22 @@ class Element {
|
| * Short description appropriate for displaying in a tree control or other
|
| * situtation where a short description is required.
|
| */
|
| - String get shortDescription => name;
|
| + String get shortDescription {
|
| + if (typeParameters.isEmpty) {
|
| + return name;
|
| + } else {
|
| + var params = Strings.join(
|
| + typeParameters.map((param) => param.shortDescription),
|
| + ', ');
|
| + return '$name<$params>';
|
| + }
|
| + }
|
|
|
| - /** Possibly normalized representation of the node kind. */
|
| + /**
|
| + * Ui specific representation of the node kind.
|
| + * For example, currently operators are considered their own kind even though
|
| + * they aren't their own kind in the AST.
|
| + */
|
| String get kind => rawKind;
|
|
|
| /**
|
| @@ -361,7 +300,7 @@ class Element {
|
| for (var kind in desiredKinds) {
|
| var elements = blockMap[kind];
|
| if (elements != null) {
|
| - blocks.add(new ElementBlock(kind, elements..sort(elementUiOrder)));
|
| + blocks.add(new ElementBlock(kind, elements..sort()));
|
| }
|
| }
|
| return blocks;
|
| @@ -372,34 +311,24 @@ class Element {
|
|
|
| Map<String, Element> _mapForKind(String kind) {
|
| Map ret = {};
|
| - if (children != null) {
|
| - for (var child in children) {
|
| - if (child.kind == kind) {
|
| - ret[child.id] = child;
|
| - }
|
| - }
|
| - }
|
| - return ret;
|
| - }
|
| + if (children == null) return ret;
|
|
|
| - Map<String, Element> _mapForKinds(Map<String, Element> kinds) {
|
| - Map ret = {};
|
| - if (children != null) {
|
| - for (var child in children) {
|
| - if (kinds.containsKey(child.kind)) {
|
| - ret[child.id] = child;
|
| - }
|
| + for (var child in children) {
|
| + if (child.kind == kind) {
|
| + ret[child.id] = child;
|
| }
|
| }
|
| return ret;
|
| }
|
|
|
| - Map<String, Element> get members {
|
| - if (_members == null) {
|
| - // TODO(jacobr): include properties???!?
|
| - _members = _mapForKinds({'method': true, 'property' : true});
|
| + /**
|
| + * Specifies the order elements should appear in the UI.
|
| + */
|
| + int compareTo(Element other) {
|
| + if (isPrivate != other.isPrivate) {
|
| + return other.isPrivate ? 1 : -1;
|
| }
|
| - return _members;
|
| + return name.compareTo(other.name);
|
| }
|
| }
|
|
|
| @@ -414,7 +343,6 @@ class LibraryElement extends Element {
|
| List<ElementBlock> _childBlocks;
|
|
|
| LibraryElement(json, Element parent) : super(json, parent);
|
| - LibraryElement.stub(String id, Element parent) : super.stub(id, parent);
|
|
|
| /** Returns all classes defined by the library. */
|
| Map<String, ClassElement> get classes {
|
| @@ -430,7 +358,7 @@ class LibraryElement extends Element {
|
| */
|
| List<ClassElement> get sortedClasses {
|
| if (_sortedClasses == null) {
|
| - _sortedClasses = []..addAll(classes.values)..sort(elementUiOrder);
|
| + _sortedClasses = []..addAll(classes.values)..sort();
|
| }
|
| return _sortedClasses;
|
| }
|
| @@ -440,7 +368,9 @@ class LibraryElement extends Element {
|
| * the Library.
|
| */
|
| List<ElementBlock> get childBlocks {
|
| - if (_childBlocks == null) _childBlocks = _createElementBlocks(LIBRARY_KINDS);
|
| + if (_childBlocks == null) {
|
| + _childBlocks = _createElementBlocks(LIBRARY_ITEMS);
|
| + }
|
| return _childBlocks;
|
| }
|
| }
|
| @@ -449,25 +379,27 @@ class LibraryElement extends Element {
|
| * [Element] describing a Dart class.
|
| */
|
| class ClassElement extends Element {
|
| +
|
| /** Members of the class grouped into logical blocks. */
|
| List<ElementBlock> _childBlocks;
|
| +
|
| /** Interfaces the class implements. */
|
| final List<Reference> interfaces;
|
| +
|
| /** Superclass of this class. */
|
| final Reference superclass;
|
|
|
| + /** Whether the class is abstract. */
|
| + final bool isAbstract;
|
| +
|
| List<ClassElement> _superclasses;
|
| List<ClassElement> _subclasses;
|
|
|
| ClassElement(Map json, Element parent)
|
| : super(json, parent),
|
| - interfaces = jsonDeserializeReferenceArray(json['interfaces']),
|
| - superclass = jsonDeserializeReference(json['superclass']);
|
| -
|
| - ClassElement.stub(String id, Element parent)
|
| - : super.stub(id, parent),
|
| - interfaces = [],
|
| - superclass = null;
|
| + interfaces = _jsonDeserializeReferenceArray(json['interfaces']),
|
| + superclass = jsonDeserializeReference(json['superclass']),
|
| + isAbstract = json['isAbstract'] == true;
|
|
|
| /** Returns all superclasses of this class. */
|
| List<ClassElement> get superclasses {
|
| @@ -475,8 +407,7 @@ class ClassElement extends Element {
|
| _superclasses = <ClassElement>[];
|
| addSuperclasses(clazz) {
|
| if (clazz.superclass != null) {
|
| - ClassElement superclassElement =
|
| - lookupReferenceId(clazz.superclass.refId);
|
| + var superclassElement = lookupReferenceId(clazz.superclass.refId);
|
| addSuperclasses(superclassElement);
|
| _superclasses.add(superclassElement);
|
| }
|
| @@ -486,6 +417,9 @@ class ClassElement extends Element {
|
| return _superclasses;
|
| }
|
|
|
| + String get kindDescription =>
|
| + isAbstract ? 'abstract $uiKind' : uiKind;
|
| +
|
| /**
|
| * Returns classes that directly extend or implement this class.
|
| */
|
| @@ -519,14 +453,17 @@ class ClassElement extends Element {
|
| * order for describing a class definition.
|
| */
|
| List<ElementBlock> get childBlocks {
|
| - if (_childBlocks == null) _childBlocks = _createElementBlocks(CLASS_KINDS);
|
| + if (_childBlocks == null) _childBlocks = _createElementBlocks(CLASS_ITEMS);
|
| return _childBlocks;
|
| }
|
| }
|
|
|
| +/**
|
| + * Element describing a typedef.
|
| + */
|
| class TypedefElement extends Element {
|
| final Reference returnType;
|
| - List<ParameterElement> _parameters;
|
| + List<Element> _parameters;
|
|
|
| TypedefElement(Map json, Element parent) : super(json, parent),
|
| returnType = jsonDeserializeReference(json['returnType']);
|
| @@ -534,7 +471,7 @@ class TypedefElement extends Element {
|
| /**
|
| * Returns a list of the parameters of the typedef.
|
| */
|
| - List<ParameterElement> get parameters {
|
| + List<Element> get parameters {
|
| if (_parameters == null) {
|
| _parameters = _filterByKind('param');
|
| }
|
| @@ -546,13 +483,13 @@ class TypedefElement extends Element {
|
| * [Element] describing a method which may be a regular method, a setter, or an
|
| * operator.
|
| */
|
| -abstract class MethodElementBase extends Element {
|
| +abstract class MethodLikeElement extends Element {
|
|
|
| final bool isOperator;
|
| final bool isStatic;
|
| final bool isSetter;
|
|
|
| - MethodElementBase(Map json, Element parent)
|
| + MethodLikeElement(Map json, Element parent)
|
| : super(json, parent),
|
| isOperator = json['isOperator'] == true,
|
| isStatic = json['isStatic'] == true,
|
| @@ -571,8 +508,8 @@ abstract class MethodElementBase extends Element {
|
| * required.
|
| */
|
| String get shortDescription {
|
| - if (isSetter == true) {
|
| - var sb = new StringBuffer('${name.substring(0, name.length-1)}');
|
| + if (isSetter) {
|
| + var sb = new StringBuffer('${name.substring(0, name.length - 1)}');
|
| if (!parameters.isEmpty && parameters.first != null
|
| && parameters.first.type != null) {
|
| sb..add(' ')..add(parameters.first.type.name);
|
| @@ -584,19 +521,19 @@ abstract class MethodElementBase extends Element {
|
| }
|
|
|
| Reference get returnType;
|
| - List<ParameterElement> _parameters;
|
| + List<Element> _parameters;
|
|
|
| /**
|
| * Returns a list of the parameters of the Method.
|
| */
|
| - List<ParameterElement> get parameters {
|
| + List<Element> get parameters {
|
| if (_parameters == null) {
|
| _parameters = _filterByKind('param');
|
| }
|
| return _parameters;
|
| }
|
|
|
| - // For UI purposes we want to treat operators as their own kind.
|
| + /// For UI purposes we want to treat operators as their own kind.
|
| String get kind => isOperator ? 'operator' : rawKind;
|
| }
|
|
|
| @@ -631,13 +568,24 @@ class TypeParameterElement extends Element {
|
| super(json, parent),
|
| upperBound = jsonDeserializeReference(json['upperBound']);
|
|
|
| + String get shortDescription {
|
| + if (upperBound == null) {
|
| + return name;
|
| + } else {
|
| + return '$name extends ${upperBound.shortDescription}';
|
| + }
|
| + }
|
| +
|
| bool hasReference(String referenceId) {
|
| if (super.hasReference(referenceId)) return true;
|
| return upperBound != null && upperBound.refId == referenceId;
|
| }
|
| }
|
|
|
| -class MethodElement extends MethodElementBase {
|
| +/**
|
| + * Element describing a method.
|
| + */
|
| +class MethodElement extends MethodLikeElement {
|
|
|
| final Reference returnType;
|
|
|
| @@ -645,7 +593,10 @@ class MethodElement extends MethodElementBase {
|
| returnType = jsonDeserializeReference(json['returnType']);
|
| }
|
|
|
| -class PropertyElement extends MethodElementBase {
|
| +/**
|
| + * Element describing a property getter.
|
| + */
|
| +class PropertyElement extends MethodLikeElement {
|
| final Reference returnType;
|
|
|
| String get shortDescription => name;
|
| @@ -654,7 +605,10 @@ class PropertyElement extends MethodElementBase {
|
| returnType = jsonDeserializeReference(json['ref']);
|
| }
|
|
|
| -class VariableElement extends MethodElementBase {
|
| +/**
|
| + * Element describing a variable.
|
| + */
|
| +class VariableElement extends MethodLikeElement {
|
| final Reference returnType;
|
| /** Whether this variable is final. */
|
| final bool isFinal;
|
| @@ -666,8 +620,85 @@ class VariableElement extends MethodElementBase {
|
| isFinal = json['isFinal'];
|
| }
|
|
|
| -class ConstructorElement extends MethodElementBase {
|
| +/**
|
| + * Element describing a constructor.
|
| + */
|
| +class ConstructorElement extends MethodLikeElement {
|
| ConstructorElement(json, Element parent) : super(json, parent);
|
|
|
| Reference get returnType => null;
|
| }
|
| +
|
| +/**
|
| + * Block of elements to render summary documentation for all elements that share
|
| + * the same kind.
|
| + *
|
| + * For example, all properties, all functions, or all constructors.
|
| + */
|
| +class ElementBlock {
|
| + String kind;
|
| + List<Element> elements;
|
| +
|
| + ElementBlock(this.kind, this.elements);
|
| +
|
| + String get kindTitle => KIND_TITLES[kind];
|
| +}
|
| +
|
| +Reference jsonDeserializeReference(Map json) {
|
| + return json != null ? new Reference(json) : null;
|
| +}
|
| +
|
| +/**
|
| + * Deserializes JSON into an [Element] object.
|
| + */
|
| +Element jsonDeserialize(Map json, Element parent) {
|
| + if (json == null) return null;
|
| +
|
| + var kind = json['kind'];
|
| + if (kind == null) {
|
| + throw "Unable to deserialize $json";
|
| + }
|
| +
|
| + switch (kind) {
|
| + case 'class':
|
| + return new ClassElement(json, parent);
|
| + case 'typedef':
|
| + return new TypedefElement(json, parent);
|
| + case 'typeparam':
|
| + return new TypeParameterElement(json, parent);
|
| + case 'library':
|
| + return new LibraryElement(json, parent);
|
| + case 'method':
|
| + return new MethodElement(json, parent);
|
| + case 'property':
|
| + return new PropertyElement(json, parent);
|
| + case 'constructor':
|
| + return new ConstructorElement(json, parent);
|
| + case 'variable':
|
| + return new VariableElement(json, parent);
|
| + case 'param':
|
| + return new ParameterElement(json, parent);
|
| + default:
|
| + return new Element(json, parent);
|
| + }
|
| +}
|
| +
|
| +List<Element> _jsonDeserializeArray(List json, Element parent) {
|
| + var ret = <Element>[];
|
| + if (json == null) return ret;
|
| +
|
| + for (Map elementJson in json) {
|
| + ret.add(jsonDeserialize(elementJson, parent));
|
| + }
|
| + return ret;
|
| +}
|
| +
|
| +List<Reference> _jsonDeserializeReferenceArray(List json) {
|
| + var ret = <Reference>[];
|
| + if (json == null) return ret;
|
| +
|
| + for (Map referenceJson in json) {
|
| + ret.add(new Reference(referenceJson));
|
| + }
|
| + return ret;
|
| +}
|
|
|