Chromium Code Reviews| Index: client/web/ast.dart | 
| diff --git a/client/web/ast.dart b/client/web/ast.dart | 
| index 1a4801c58d00730f0df700dc1065ed13d742319b..d5c982ea6243da1376d27df3c5c26239fc85ee73 100644 | 
| --- a/client/web/ast.dart | 
| +++ b/client/web/ast.dart | 
| @@ -49,15 +49,16 @@ Reference jsonDeserializeReference(Map json) { | 
| } | 
| /** | 
| - * Deserializes JSON into [Element] or [Reference] objects. | 
| + * Deserializes JSON into an [Element] object. | 
| */ | 
| Element jsonDeserialize(Map json, Element parent) { | 
| if (json == null) return null; | 
| - if (!json.containsKey('kind')) { | 
| + var kind = json['kind']; | 
| + if (kind == null) { | 
| throw "Unable to deserialize $json"; | 
| } | 
| - switch (json['kind']) { | 
| + switch (kind) { | 
| case 'class': | 
| return new ClassElement(json, parent); | 
| case 'typedef': | 
| @@ -81,7 +82,7 @@ Element jsonDeserialize(Map json, Element parent) { | 
| } | 
| } | 
| -List<Element> jsonDeserializeArray(List json, Element parent) { | 
| +List<Element> _jsonDeserializeArray(List json, Element parent) { | 
| var ret = <Element>[]; | 
| if (json != null) { | 
| 
 
Siggi Cherem (dart-lang)
2012/12/19 19:47:33
nit: consider switchting this to
if (json == null
 
Jacob
2013/01/02 19:54:58
Done.
 
 | 
| for (Map elementJson in json) { | 
| @@ -91,7 +92,7 @@ List<Element> jsonDeserializeArray(List json, Element parent) { | 
| return ret; | 
| } | 
| -List<Reference> jsonDeserializeReferenceArray(List json) { | 
| +List<Reference> _jsonDeserializeReferenceArray(List json) { | 
| var ret = <Reference>[]; | 
| if (json != null) { | 
| 
 
Siggi Cherem (dart-lang)
2012/12/19 19:47:33
same here
 
Jacob
2013/01/02 19:54:58
Done.
 
 | 
| for (Map referenceJson in json) { | 
| @@ -107,22 +108,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]; | 
| } | 
| /** | 
| @@ -134,7 +146,7 @@ Element lookupReferenceId(String referenceId) { | 
| var parts = referenceId.split(new RegExp('/')); | 
| Element current = lookupLibrary(parts.first); | 
| var result = <Element>[current]; | 
| 
 
Siggi Cherem (dart-lang)
2012/12/19 19:47:33
'result' seems unused?
 
Jacob
2013/01/02 19:54:58
yep that was obsolete. fixed.
 
 | 
| - 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 +155,6 @@ Element lookupReferenceId(String referenceId) { | 
| break; | 
| } | 
| } | 
| - if (next == null) { | 
| - next = new Element.stub(id, current); | 
| - } | 
| current = next; | 
| } | 
| return current; | 
| @@ -160,7 +169,8 @@ _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 | 
| 
 
Siggi Cherem (dart-lang)
2012/12/19 19:47:33
dart-web-components ==> web-ui
 
Jacob
2013/01/02 19:54:58
Done.
 
 | 
| @@ -209,6 +219,8 @@ class Element { | 
| SafeHtml _commentHtml; | 
| List<Element> _references; | 
| + List<Element> _typeParameters; | 
| + | 
| Element(Map json, this.parent) : | 
| name = json['name'], | 
| rawKind = json['kind'], | 
| @@ -218,16 +230,21 @@ class Element { | 
| _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. | 
| 
 
Siggi Cherem (dart-lang)
2012/12/19 19:47:33
[kind. => [kind].
 
Jacob
2013/01/02 19:54:58
Done.
 
 | 
| + */ | 
| + String get kindDescription => uiKind; | 
| + | 
| /** Invoke [callback] on this [Element] and all descendants. */ | 
| void traverse(void callback(Element)) { | 
| callback(this); | 
| @@ -237,7 +254,7 @@ 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; | 
| @@ -249,7 +266,7 @@ class Element { | 
| } | 
| 
 
Siggi Cherem (dart-lang)
2012/12/19 19:47:33
maybe use a recursive pattern here instead:
Strin
 
Jacob
2013/01/02 19:54:58
Done.
 
 | 
| /** | 
| - * 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; | 
| @@ -260,16 +277,6 @@ class Element { | 
| return null; | 
| } | 
| 
 
Siggi Cherem (dart-lang)
2012/12/19 19:47:33
similary - use recursive pattern for line too.
 
Jacob
2013/01/02 19:54:58
Done.
 
 | 
| - 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; | 
| - | 
| /** | 
| * Globally unique identifier for this element. | 
| */ | 
| @@ -300,7 +307,6 @@ class 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); | 
| @@ -322,6 +328,13 @@ class Element { | 
| } | 
| } | 
| + List<Element> get typeParameters { | 
| + if (_typeParameters == null) { | 
| + _typeParameters = _filterByKind('typeparam'); | 
| + } | 
| + return _typeParameters; | 
| + } | 
| + | 
| /** | 
| * [SafeHtml] for the comment associated with this [Element] generated from | 
| * the markdow comment associated with the element. | 
| @@ -337,7 +350,16 @@ 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. */ | 
| 
 
Siggi Cherem (dart-lang)
2012/12/19 19:47:33
strange to see 'possibly' here, maybe explain we c
 
Jacob
2013/01/02 19:54:58
rewrote comment.
 
 | 
| String get kind => rawKind; | 
| @@ -414,7 +436,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 { | 
| @@ -440,7 +461,9 @@ class LibraryElement extends Element { | 
| * the Library. | 
| */ | 
| List<ElementBlock> get childBlocks { | 
| - if (_childBlocks == null) _childBlocks = _createElementBlocks(LIBRARY_KINDS); | 
| + if (_childBlocks == null) { | 
| + _childBlocks = _createElementBlocks(LIBRARY_KINDS); | 
| + } | 
| return _childBlocks; | 
| } | 
| } | 
| @@ -458,16 +481,13 @@ class ClassElement extends Element { | 
| List<ClassElement> _superclasses; | 
| List<ClassElement> _subclasses; | 
| + final bool isAbstract; | 
| 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']; | 
| /** Returns all superclasses of this class. */ | 
| List<ClassElement> get superclasses { | 
| @@ -486,6 +506,9 @@ class ClassElement extends Element { | 
| return _superclasses; | 
| } | 
| + String get kindDescription => | 
| + isAbstract == true ? 'abstract $uiKind' : uiKind; | 
| + | 
| /** | 
| * Returns classes that directly extend or implement this class. | 
| */ | 
| @@ -524,9 +547,12 @@ class ClassElement extends Element { | 
| } | 
| } | 
| +/** | 
| + * 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 +560,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'); | 
| } | 
| @@ -584,12 +610,12 @@ 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'); | 
| } | 
| @@ -631,12 +657,23 @@ 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}'; | 
| 
 
Siggi Cherem (dart-lang)
2012/12/19 19:47:33
mmm. I wonder if we want to simply make shortDecri
 
Jacob
2013/01/02 19:54:58
I like to be specific about this as there are many
 
 | 
| + } | 
| + } | 
| + | 
| bool hasReference(String referenceId) { | 
| if (super.hasReference(referenceId)) return true; | 
| return upperBound != null && upperBound.refId == referenceId; | 
| } | 
| } | 
| +/** | 
| + * Element describing a method. | 
| + */ | 
| class MethodElement extends MethodElementBase { | 
| final Reference returnType; | 
| @@ -645,6 +682,9 @@ class MethodElement extends MethodElementBase { | 
| returnType = jsonDeserializeReference(json['returnType']); | 
| } | 
| +/** | 
| + * Element describing a property getter. | 
| + */ | 
| class PropertyElement extends MethodElementBase { | 
| final Reference returnType; | 
| @@ -654,6 +694,9 @@ class PropertyElement extends MethodElementBase { | 
| returnType = jsonDeserializeReference(json['ref']); | 
| } | 
| +/** | 
| + * Element describing a variable. | 
| + */ | 
| class VariableElement extends MethodElementBase { | 
| final Reference returnType; | 
| /** Whether this variable is final. */ | 
| @@ -666,6 +709,9 @@ class VariableElement extends MethodElementBase { | 
| isFinal = json['isFinal']; | 
| } | 
| +/** | 
| + * Element describing a constructor. | 
| + */ | 
| class ConstructorElement extends MethodElementBase { | 
| ConstructorElement(json, Element parent) : super(json, parent); |