Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: client/web/ast.dart

Issue 11636011: Web components based app to view dart docs. Still has rough edges. (Closed) Base URL: https://github.com/dart-lang/dart-api-app.git@master
Patch Set: Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | client/web/doc_link.html » ('j') | client/web/doc_link.html » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 library ast; 1 library ast;
Siggi Cherem (dart-lang) 2012/12/19 19:47:33 + copyright + library level doc
Jacob 2013/01/02 19:54:58 Done.
2 2
3 import 'package:web_ui/safe_html.dart'; 3 import 'package:web_ui/safe_html.dart';
4 import 'markdown.dart' as md; 4 import 'markdown.dart' as md;
5 5
6 /** 6 /**
7 * Top level data model for the app. 7 * Top level data model for the app.
8 * Mapping from String ids to [LibraryElement] objects describing all currently 8 * Mapping from String ids to [LibraryElement] objects describing all currently
9 * loaded libraries. All code must be written to work properly if more libraries 9 * loaded libraries. All code must be written to work properly if more libraries
10 * are loaded incrementally. 10 * are loaded incrementally.
11 */ 11 */
12 Map<String, LibraryElement> libraries = <LibraryElement>{}; 12 Map<String, LibraryElement> libraries = <LibraryElement>{};
13 13
14 List<String> LIBRARY_KINDS = ['variable', 'property', 'method', 'class', 'except ion', 'typedef']; 14 List<String> LIBRARY_KINDS = ['variable', 'property', 'method', 'class', 'except ion', 'typedef'];
Siggi Cherem (dart-lang) 2012/12/19 19:47:33 style nit: 80 col (here and the line below)
Siggi Cherem (dart-lang) 2012/12/19 19:47:33 nit: rename to LIBRARY_ITEMS? for a moment I thoug
Jacob 2013/01/02 19:54:58 Changed to LIBRARY_CHILD_KINDS these are the KIND
Jacob 2013/01/02 19:54:58 renamed to LIBRARY_ITEMS
15 List<String> CLASS_KINDS = ['constructor', 'variable', 'property', 'method', 'op erator']; 15 List<String> CLASS_KINDS = ['constructor', 'variable', 'property', 'method', 'op erator'];
Siggi Cherem (dart-lang) 2012/12/19 19:47:33 maybe rename as CLASS_ITEMS? or CLASS_ELEMENTS?
Jacob 2013/01/02 19:54:58 renamed to CLASS_ITEMS.
16 // TODO(jacobr): add package kinds? 16 // TODO(jacobr): add package kinds?
17 17
18 // TODO(jacobr): i18n 18 // TODO(jacobr): i18n
19 /** 19 /**
20 * Pretty names for the various kinds displayed. 20 * Pretty names for the various kinds displayed.
21 */ 21 */
22 final KIND_TITLES = {'property': 'Properties', 22 final KIND_TITLES = {'property': 'Properties',
Siggi Cherem (dart-lang) 2012/12/19 19:47:33 style nit: feel free to ignore, but I might prefer
Jacob 2013/01/02 19:54:58 Done.
23 'variable': 'Variables', 23 'variable': 'Variables',
24 'method': 'Functions', 24 'method': 'Functions',
25 'constructor': 'Constructors', 25 'constructor': 'Constructors',
26 'class': 'Classes', 26 'class': 'Classes',
27 'operator': 'Operators', 27 'operator': 'Operators',
28 'typedef': 'Typedefs', 28 'typedef': 'Typedefs',
29 'exception': 'Exceptions' 29 'exception': 'Exceptions'
30 }; 30 };
31 31
32 /** 32 /**
33 * Block of elements to render summary documentation for that all share the 33 * Block of elements to render summary documentation for that all share the
Siggi Cherem (dart-lang) 2012/12/19 19:47:33 for that all => for all that
Jacob 2013/01/02 19:54:58 Done.
34 * same kind. 34 * same kind.
35 * 35 *
36 * For example, all properties, all functions, or all constructors. 36 * For example, all properties, all functions, or all constructors.
37 */ 37 */
38 class ElementBlock { 38 class ElementBlock {
39 String kind; 39 String kind;
40 List<Element> elements; 40 List<Element> elements;
41 41
42 ElementBlock(this.kind, this.elements); 42 ElementBlock(this.kind, this.elements);
43 43
44 String get kindTitle => KIND_TITLES[kind]; 44 String get kindTitle => KIND_TITLES[kind];
45 } 45 }
46 46
47 Reference jsonDeserializeReference(Map json) { 47 Reference jsonDeserializeReference(Map json) {
Siggi Cherem (dart-lang) 2012/12/19 19:47:33 nit: consider reordering the code here to put the
Jacob 2013/01/02 19:54:58 Agreed. Moved to the bottom of the file.
48 return json != null ? new Reference(json) : null; 48 return json != null ? new Reference(json) : null;
49 } 49 }
50 50
51 /** 51 /**
52 * Deserializes JSON into [Element] or [Reference] objects. 52 * Deserializes JSON into an [Element] object.
53 */ 53 */
54 Element jsonDeserialize(Map json, Element parent) { 54 Element jsonDeserialize(Map json, Element parent) {
55 if (json == null) return null; 55 if (json == null) return null;
56 if (!json.containsKey('kind')) { 56 var kind = json['kind'];
57 if (kind == null) {
57 throw "Unable to deserialize $json"; 58 throw "Unable to deserialize $json";
58 } 59 }
59 60
60 switch (json['kind']) { 61 switch (kind) {
61 case 'class': 62 case 'class':
62 return new ClassElement(json, parent); 63 return new ClassElement(json, parent);
63 case 'typedef': 64 case 'typedef':
64 return new TypedefElement(json, parent); 65 return new TypedefElement(json, parent);
65 case 'typeparam': 66 case 'typeparam':
66 return new TypeParameterElement(json, parent); 67 return new TypeParameterElement(json, parent);
67 case 'library': 68 case 'library':
68 return new LibraryElement(json, parent); 69 return new LibraryElement(json, parent);
69 case 'method': 70 case 'method':
70 return new MethodElement(json, parent); 71 return new MethodElement(json, parent);
71 case 'property': 72 case 'property':
72 return new PropertyElement(json, parent); 73 return new PropertyElement(json, parent);
73 case 'constructor': 74 case 'constructor':
74 return new ConstructorElement(json, parent); 75 return new ConstructorElement(json, parent);
75 case 'variable': 76 case 'variable':
76 return new VariableElement(json, parent); 77 return new VariableElement(json, parent);
77 case 'param': 78 case 'param':
78 return new ParameterElement(json, parent); 79 return new ParameterElement(json, parent);
79 default: 80 default:
80 return new Element(json, parent); 81 return new Element(json, parent);
81 } 82 }
82 } 83 }
83 84
84 List<Element> jsonDeserializeArray(List json, Element parent) { 85 List<Element> _jsonDeserializeArray(List json, Element parent) {
85 var ret = <Element>[]; 86 var ret = <Element>[];
86 if (json != null) { 87 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.
87 for (Map elementJson in json) { 88 for (Map elementJson in json) {
88 ret.add(jsonDeserialize(elementJson, parent)); 89 ret.add(jsonDeserialize(elementJson, parent));
89 } 90 }
90 } 91 }
91 return ret; 92 return ret;
92 } 93 }
93 94
94 List<Reference> jsonDeserializeReferenceArray(List json) { 95 List<Reference> _jsonDeserializeReferenceArray(List json) {
95 var ret = <Reference>[]; 96 var ret = <Reference>[];
96 if (json != null) { 97 if (json != null) {
Siggi Cherem (dart-lang) 2012/12/19 19:47:33 same here
Jacob 2013/01/02 19:54:58 Done.
97 for (Map referenceJson in json) { 98 for (Map referenceJson in json) {
98 ret.add(new Reference(referenceJson)); 99 ret.add(new Reference(referenceJson));
99 } 100 }
100 } 101 }
101 return ret; 102 return ret;
102 } 103 }
103 104
104 /** 105 /**
105 * Reference to an [Element]. 106 * Reference to an [Element].
106 */ 107 */
107 class Reference { 108 class Reference {
108 final String refId; 109 final String refId;
109 final String name; 110 final String name;
111 final List<Reference> arguments;
112
110 Reference(Map json) : 113 Reference(Map json) :
111 name = json['name'], 114 name = json['name'],
112 refId = json['refId']; 115 refId = json['refId'],
116 arguments = _jsonDeserializeReferenceArray(json['arguments']);
117
118 /**
119 * Short description appropriate for displaying in a tree control or other
120 * situtation where a short description is required.
121 */
122 String get shortDescription {
123 if (arguments.isEmpty) {
124 return name;
125 } else {
126 var params = Strings.join(
127 arguments.map((param) => param.shortDescription), ', ');
128 return '$name<$params>';
129 }
130 }
113 } 131 }
114 132
115 /** 133 /**
116 * Lookup a library based on the [libraryId]. 134 * Lookup a library based on the [libraryId].
117 *
118 * If the library cannot be found, a stub dummy [Library] will be returned.
119 */ 135 */
120 LibraryElement lookupLibrary(String libraryId) { 136 LibraryElement lookupLibrary(String libraryId) {
121 var library = libraries[libraryId]; 137 return libraries[libraryId];
122 if (library == null) {
123 library = new LibraryElement.stub(libraryId, null);
124 }
125 return library;
126 } 138 }
127 139
128 /** 140 /**
129 * Resolve the [Element] matching the [referenceId]. 141 * Resolve the [Element] matching the [referenceId].
130 * 142 *
131 * If the Element cannot be found, a stub dummy [Element] will be returned. 143 * If the Element cannot be found, a stub dummy [Element] will be returned.
132 */ 144 */
133 Element lookupReferenceId(String referenceId) { 145 Element lookupReferenceId(String referenceId) {
134 var parts = referenceId.split(new RegExp('/')); 146 var parts = referenceId.split(new RegExp('/'));
135 Element current = lookupLibrary(parts.first); 147 Element current = lookupLibrary(parts.first);
136 var result = <Element>[current]; 148 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.
137 for (var i = 1; i < parts.length; i++) { 149 for (var i = 1; i < parts.length && current != null; i++) {
138 var id = parts[i]; 150 var id = parts[i];
139 var next = null; 151 var next = null;
140 for (var child in current.children) { 152 for (var child in current.children) {
141 if (child.id == id) { 153 if (child.id == id) {
142 next = child; 154 next = child;
Siggi Cherem (dart-lang) 2012/12/19 19:47:33 you could directly do: current = child; and remo
Jacob 2013/01/02 19:54:58 The trouble is that isn't quite right. You need t
143 break; 155 break;
144 } 156 }
145 } 157 }
146 if (next == null) {
147 next = new Element.stub(id, current);
148 }
149 current = next; 158 current = next;
150 } 159 }
151 return current; 160 return current;
152 } 161 }
153 162
154 /** 163 /**
155 * Invoke [callback] on every [Element] in the ast. 164 * Invoke [callback] on every [Element] in the ast.
156 */ 165 */
157 _traverseWorld(void callback(Element)) { 166 _traverseWorld(void callback(Element)) {
158 for (var library in libraries.values) { 167 for (var library in libraries.values) {
159 library.traverse(callback); 168 library.traverse(callback);
160 } 169 }
161 } 170 }
162 171
163 // TODO(jacobr): remove this method when templates handle safe HTML containing 172 // TODO(jacobr): remove this method when templates handle [SafeHTML] containing
173 // multiple top level nodes correct.
164 SafeHtml _markdownToSafeHtml(String text) { 174 SafeHtml _markdownToSafeHtml(String text) {
165 // We currently have to insert an extra span for now because of 175 // We currently have to insert an extra span for now because of
166 // https://github.com/dart-lang/dart-web-components/issues/212 176 // 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.
167 return new SafeHtml.unsafe(text != null && !text.isEmpty ? 177 return new SafeHtml.unsafe(text != null && !text.isEmpty ?
168 '<span>${md.markdownToHtml(text)}</span>' : '<span><span>'); 178 '<span>${md.markdownToHtml(text)}</span>' : '<span><span>');
169 } 179 }
170 180
171 /** 181 /**
172 * Specifies the order elements should appear in the UI. 182 * Specifies the order elements should appear in the UI.
173 */ 183 */
174 int elementUiOrder(Element a, Element b) { 184 int elementUiOrder(Element a, Element b) {
Siggi Cherem (dart-lang) 2012/12/19 19:47:33 should Element implement Comparable and this funct
Jacob 2013/01/02 19:54:58 Done.
175 if (a.isPrivate != b.isPrivate) { 185 if (a.isPrivate != b.isPrivate) {
176 return a.isPrivate == true ? 1 : -1; 186 return a.isPrivate == true ? 1 : -1;
177 } 187 }
178 return a.name.compareTo(b.name); 188 return a.name.compareTo(b.name);
179 } 189 }
180 190
181 /** 191 /**
182 * Base class for all elements in the AST. 192 * Base class for all elements in the AST.
183 */ 193 */
184 class Element { 194 class Element {
185 final Element parent; 195 final Element parent;
186 /** Human readable type name for the node. */ 196 /** Human readable type name for the node. */
Siggi Cherem (dart-lang) 2012/12/19 19:47:33 nit: add empty line above comment, here and in eve
187 final String rawKind; 197 final String rawKind;
188 /** Human readable name for the element. */ 198 /** Human readable name for the element. */
189 final String name; 199 final String name;
190 /** Id for the node that is unique within its parent's children. */ 200 /** Id for the node that is unique within its parent's children. */
191 final String id; 201 final String id;
192 /** Raw text of the comment associated with the Element if any. */ 202 /** Raw text of the comment associated with the Element if any. */
193 final String comment; 203 final String comment;
194 /** Whether the node is private. */ 204 /** Whether the node is private. */
195 final bool isPrivate; 205 final bool isPrivate;
196 206
197 final String _uri; 207 final String _uri;
Siggi Cherem (dart-lang) 2012/12/19 19:47:33 nit: move these private members down with the othe
Jacob 2013/01/02 19:54:58 Done.
198 final String _line; 208 final String _line;
199 209
200 /** Children of the node. */ 210 /** Children of the node. */
201 List<Element> children; 211 List<Element> children;
202 212
203 /** Whether the [Element] is currently being loaded. */ 213 /** Whether the [Element] is currently being loaded. */
204 final bool loading; 214 final bool loading;
205 215
206 String _refId; 216 String _refId;
207 217
208 Map _members; 218 Map _members;
209 SafeHtml _commentHtml; 219 SafeHtml _commentHtml;
210 List<Element> _references; 220 List<Element> _references;
211 221
222 List<Element> _typeParameters;
223
212 Element(Map json, this.parent) : 224 Element(Map json, this.parent) :
213 name = json['name'], 225 name = json['name'],
214 rawKind = json['kind'], 226 rawKind = json['kind'],
215 id = json['id'], 227 id = json['id'],
216 comment = json['comment'], 228 comment = json['comment'],
217 isPrivate = json['isPrivate'], 229 isPrivate = json['isPrivate'],
218 _uri = json['uri'], 230 _uri = json['uri'],
219 _line = json['line'], 231 _line = json['line'],
220 loading = false { 232 loading = false {
221 children = jsonDeserializeArray(json['children'], this); 233 children = _jsonDeserializeArray(json['children'], this);
222 } 234 }
223 235
224 /** 236 /**
225 * Returns a kind name that make sense for the UI rather than the AST 237 * Returns a kind name that make sense for the UI rather than the AST
226 * kinds. For example, setters are considered properties instead of 238 * kinds. For example, setters are considered properties instead of
227 * methods. 239 * methods in the UI but not the AST.
228 */ 240 */
229 String get uiKind => kind; 241 String get uiKind => kind;
230 242
243 /**
244 * 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.
245 */
246 String get kindDescription => uiKind;
247
231 /** Invoke [callback] on this [Element] and all descendants. */ 248 /** Invoke [callback] on this [Element] and all descendants. */
232 void traverse(void callback(Element)) { 249 void traverse(void callback(Element)) {
233 callback(this); 250 callback(this);
234 for (var child in children) { 251 for (var child in children) {
235 callback(child); 252 callback(child);
236 } 253 }
237 } 254 }
238 255
239 /** 256 /**
240 * Uri containing the definition of the element. 257 * Uri containing the source code for the definition of the element.
241 */ 258 */
242 String get uri { 259 String get uri {
243 Element current = this; 260 Element current = this;
244 while (current != null) { 261 while (current != null) {
245 if (current._uri != null) return current._uri; 262 if (current._uri != null) return current._uri;
246 current = current.parent; 263 current = current.parent;
247 } 264 }
248 return null; 265 return null;
249 } 266 }
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.
250 267
251 /** 268 /**
252 * Line in the original source file that starts the definition of the element. 269 * Line in the original source file that begins the definition of the element.
253 */ 270 */
254 String get line { 271 String get line {
255 Element current = this; 272 Element current = this;
256 while (current != null) { 273 while (current != null) {
257 if (current._line != null) return current._line; 274 if (current._line != null) return current._line;
258 current = current.parent; 275 current = current.parent;
259 } 276 }
260 return null; 277 return null;
261 } 278 }
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.
262 279
263 Element.stub(this.id, this.parent) :
264 name = '???', // TODO(jacobr): remove/add
265 _uri = null,
266 _line = null,
267 comment = null,
268 rawKind = null,
269 children = <Element>[],
270 isPrivate = null,
271 loading = true;
272
273 /** 280 /**
274 * Globally unique identifier for this element. 281 * Globally unique identifier for this element.
275 */ 282 */
276 String get refId { 283 String get refId {
277 if (_refId == null) { 284 if (_refId == null) {
278 if (parent == null) { 285 if (parent == null) {
279 _refId = id; 286 _refId = id;
280 } else { 287 } else {
281 _refId = '${parent.refId}/$id'; 288 _refId = '${parent.refId}/$id';
282 } 289 }
Siggi Cherem (dart-lang) 2012/12/19 19:47:33 style nit: feel free to ignore, maybe compact the
Jacob 2013/01/02 19:54:58 Done.
283 } 290 }
284 return _refId; 291 return _refId;
285 } 292 }
286 293
287 /** 294 /**
288 * Whether this [Element] references the specified [referenceId]. 295 * Whether this [Element] references the specified [referenceId].
289 */ 296 */
290 bool hasReference(String referenceId) { 297 bool hasReference(String referenceId) {
291 for (var child in children) { 298 for (var child in children) {
Siggi Cherem (dart-lang) 2012/12/19 19:47:33 use List.some? bool hasReference(String reference
292 if (child.hasReference(referenceId)) { 299 if (child.hasReference(referenceId)) {
293 return true; 300 return true;
294 } 301 }
295 } 302 }
296 return false; 303 return false;
297 } 304 }
298 305
299 /** Returns all [Element]s that reference this [Element]. */ 306 /** Returns all [Element]s that reference this [Element]. */
300 List<Element> get references { 307 List<Element> get references {
301 if (_references == null) { 308 if (_references == null) {
302 _references = <Element>[]; 309 _references = <Element>[];
303 // TODO(jacobr): change to filterWorld and tweak meaning.
304 _traverseWorld((element) { 310 _traverseWorld((element) {
305 if (element.hasReference(refId)) { 311 if (element.hasReference(refId)) {
306 _references.add(element); 312 _references.add(element);
307 } 313 }
308 }); 314 });
309 } 315 }
310 return _references; 316 return _references;
311 } 317 }
312 318
313 // TODO(jacobr): write without recursion. 319 // TODO(jacobr): write without recursion.
Siggi Cherem (dart-lang) 2012/12/19 19:47:33 why :)?
Jacob 2013/01/02 19:54:58 performance :) for this case the paths are pretty
314 /** 320 /**
315 * Path from this [Element] to the root of the tree starting at the root. 321 * Path from this [Element] to the root of the tree starting at the root.
Siggi Cherem (dart-lang) 2012/12/19 19:47:33 maybe rephrase as follows? Path from the root of
Jacob 2013/01/02 19:54:58 Done.
316 */ 322 */
317 List<Element> get path { 323 List<Element> get path {
318 if (parent == null) { 324 if (parent == null) {
319 return <Element>[this]; 325 return <Element>[this];
320 } else { 326 } else {
321 return parent.path..add(this); 327 return parent.path..add(this);
322 } 328 }
323 } 329 }
324 330
331 List<Element> get typeParameters {
332 if (_typeParameters == null) {
333 _typeParameters = _filterByKind('typeparam');
334 }
335 return _typeParameters;
336 }
337
325 /** 338 /**
326 * [SafeHtml] for the comment associated with this [Element] generated from 339 * [SafeHtml] for the comment associated with this [Element] generated from
327 * the markdow comment associated with the element. 340 * the markdow comment associated with the element.
328 */ 341 */
329 SafeHtml get commentHtml { 342 SafeHtml get commentHtml {
330 if (_commentHtml == null) { 343 if (_commentHtml == null) {
331 _commentHtml = _markdownToSafeHtml(comment); 344 _commentHtml = _markdownToSafeHtml(comment);
332 } 345 }
333 return _commentHtml; 346 return _commentHtml;
334 } 347 }
335 348
336 /** 349 /**
337 * Short description appropriate for displaying in a tree control or other 350 * Short description appropriate for displaying in a tree control or other
338 * situtation where a short description is required. 351 * situtation where a short description is required.
339 */ 352 */
340 String get shortDescription => name; 353 String get shortDescription {
354 if (typeParameters.isEmpty) {
355 return name;
356 } else {
357 var params = Strings.join(
358 typeParameters.map((param) => param.shortDescription),
359 ', ');
360 return '$name<$params>';
361 }
362 }
341 363
342 /** Possibly normalized representation of the node kind. */ 364 /** 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.
343 String get kind => rawKind; 365 String get kind => rawKind;
344 366
345 /** 367 /**
346 * Generate blocks of Elements for each kind in the list of [desiredKinds]. 368 * Generate blocks of Elements for each kind in the list of [desiredKinds].
347 * 369 *
348 * This is helpful when rendering UI that segments members into blocks. 370 * This is helpful when rendering UI that segments members into blocks.
349 * Uses the kind types that make sense for the UI rather than the AST 371 * Uses the kind types that make sense for the UI rather than the AST
350 * kinds. For example, setters are considered properties instead of methods. 372 * kinds. For example, setters are considered properties instead of methods.
351 */ 373 */
352 List<ElementBlock> _createElementBlocks(List<String> desiredKinds) { 374 List<ElementBlock> _createElementBlocks(List<String> desiredKinds) {
(...skipping 12 matching lines...) Expand all
365 } 387 }
366 } 388 }
367 return blocks; 389 return blocks;
368 } 390 }
369 391
370 List<Element> _filterByKind(String kind) => 392 List<Element> _filterByKind(String kind) =>
371 children.filter((child) => child.kind == kind); 393 children.filter((child) => child.kind == kind);
372 394
373 Map<String, Element> _mapForKind(String kind) { 395 Map<String, Element> _mapForKind(String kind) {
374 Map ret = {}; 396 Map ret = {};
375 if (children != null) { 397 if (children != null) {
Siggi Cherem (dart-lang) 2012/12/19 19:47:33 nit: if(children == null) return ret;
Jacob 2013/01/02 19:54:58 Done.
376 for (var child in children) { 398 for (var child in children) {
377 if (child.kind == kind) { 399 if (child.kind == kind) {
378 ret[child.id] = child; 400 ret[child.id] = child;
379 } 401 }
380 } 402 }
381 } 403 }
382 return ret; 404 return ret;
383 } 405 }
384 406
385 Map<String, Element> _mapForKinds(Map<String, Element> kinds) { 407 Map<String, Element> _mapForKinds(Map<String, Element> kinds) {
Siggi Cherem (dart-lang) 2012/12/19 19:47:33 change argument type to Set<String> ?
Jacob 2013/01/02 19:54:58 This method isn't really needed. Removed.
386 Map ret = {}; 408 Map ret = {};
387 if (children != null) { 409 if (children != null) {
388 for (var child in children) { 410 for (var child in children) {
389 if (kinds.containsKey(child.kind)) { 411 if (kinds.containsKey(child.kind)) {
390 ret[child.id] = child; 412 ret[child.id] = child;
391 } 413 }
392 } 414 }
393 } 415 }
394 return ret; 416 return ret;
395 } 417 }
(...skipping 11 matching lines...) Expand all
407 * [Element] describing a Dart library. 429 * [Element] describing a Dart library.
408 * 430 *
409 * Adds convenience helpers for quickly accessing data about libraries. 431 * Adds convenience helpers for quickly accessing data about libraries.
410 */ 432 */
411 class LibraryElement extends Element { 433 class LibraryElement extends Element {
412 Map<String, ClassElement> _classes; 434 Map<String, ClassElement> _classes;
413 List<ClassElement> _sortedClasses; 435 List<ClassElement> _sortedClasses;
414 List<ElementBlock> _childBlocks; 436 List<ElementBlock> _childBlocks;
415 437
416 LibraryElement(json, Element parent) : super(json, parent); 438 LibraryElement(json, Element parent) : super(json, parent);
417 LibraryElement.stub(String id, Element parent) : super.stub(id, parent);
418 439
419 /** Returns all classes defined by the library. */ 440 /** Returns all classes defined by the library. */
420 Map<String, ClassElement> get classes { 441 Map<String, ClassElement> get classes {
421 if (_classes == null) { 442 if (_classes == null) {
422 _classes = _mapForKind('class'); 443 _classes = _mapForKind('class');
423 } 444 }
424 return _classes; 445 return _classes;
425 } 446 }
426 447
427 /** 448 /**
428 * Returns all classes defined by the library sorted name and whether they 449 * Returns all classes defined by the library sorted name and whether they
429 * are private. 450 * are private.
430 */ 451 */
431 List<ClassElement> get sortedClasses { 452 List<ClassElement> get sortedClasses {
432 if (_sortedClasses == null) { 453 if (_sortedClasses == null) {
433 _sortedClasses = []..addAll(classes.values)..sort(elementUiOrder); 454 _sortedClasses = []..addAll(classes.values)..sort(elementUiOrder);
434 } 455 }
435 return _sortedClasses; 456 return _sortedClasses;
436 } 457 }
437 458
438 /** 459 /**
439 * Returns all blocks of elements that should be rendered by UI summarizing 460 * Returns all blocks of elements that should be rendered by UI summarizing
440 * the Library. 461 * the Library.
441 */ 462 */
442 List<ElementBlock> get childBlocks { 463 List<ElementBlock> get childBlocks {
443 if (_childBlocks == null) _childBlocks = _createElementBlocks(LIBRARY_KINDS) ; 464 if (_childBlocks == null) {
465 _childBlocks = _createElementBlocks(LIBRARY_KINDS);
466 }
444 return _childBlocks; 467 return _childBlocks;
445 } 468 }
446 } 469 }
447 470
448 /** 471 /**
449 * [Element] describing a Dart class. 472 * [Element] describing a Dart class.
450 */ 473 */
451 class ClassElement extends Element { 474 class ClassElement extends Element {
452 /** Members of the class grouped into logical blocks. */ 475 /** Members of the class grouped into logical blocks. */
453 List<ElementBlock> _childBlocks; 476 List<ElementBlock> _childBlocks;
454 /** Interfaces the class implements. */ 477 /** Interfaces the class implements. */
Siggi Cherem (dart-lang) 2012/12/19 19:47:33 nit: + empty line above comment here and below
Jacob 2013/01/02 19:54:58 Done.
455 final List<Reference> interfaces; 478 final List<Reference> interfaces;
456 /** Superclass of this class. */ 479 /** Superclass of this class. */
457 final Reference superclass; 480 final Reference superclass;
458 481
459 List<ClassElement> _superclasses; 482 List<ClassElement> _superclasses;
460 List<ClassElement> _subclasses; 483 List<ClassElement> _subclasses;
484 final bool isAbstract;
461 485
462 ClassElement(Map json, Element parent) 486 ClassElement(Map json, Element parent)
463 : super(json, parent), 487 : super(json, parent),
464 interfaces = jsonDeserializeReferenceArray(json['interfaces']), 488 interfaces = _jsonDeserializeReferenceArray(json['interfaces']),
465 superclass = jsonDeserializeReference(json['superclass']); 489 superclass = jsonDeserializeReference(json['superclass']),
466 490 isAbstract = json['isAbstract'];
467 ClassElement.stub(String id, Element parent)
468 : super.stub(id, parent),
469 interfaces = [],
470 superclass = null;
471 491
472 /** Returns all superclasses of this class. */ 492 /** Returns all superclasses of this class. */
473 List<ClassElement> get superclasses { 493 List<ClassElement> get superclasses {
474 if (_superclasses == null) { 494 if (_superclasses == null) {
475 _superclasses = <ClassElement>[]; 495 _superclasses = <ClassElement>[];
476 addSuperclasses(clazz) { 496 addSuperclasses(clazz) {
Siggi Cherem (dart-lang) 2012/12/19 19:47:33 nit: consider adding here the type parameter and r
Jacob 2013/01/02 19:54:58 i don't follow.
Siggi Cherem (dart-lang) 2013/01/02 21:40:55 In line 498 (now line 402) you seem to have a down
Jacob 2013/01/03 00:09:33 just removed the ClassElement and changed it to a
477 if (clazz.superclass != null) { 497 if (clazz.superclass != null) {
478 ClassElement superclassElement = 498 ClassElement superclassElement =
479 lookupReferenceId(clazz.superclass.refId); 499 lookupReferenceId(clazz.superclass.refId);
Siggi Cherem (dart-lang) 2012/12/19 19:47:33 one thing I was wondering is whether Reference cou
Jacob 2013/01/02 19:54:58 I don't think the times when references are resolv
Siggi Cherem (dart-lang) 2013/01/02 21:40:55 We can wait and see later how this would work afte
Jacob 2013/01/03 00:09:33 Lets chat about this offline. On 2013/01/02 21:40:
480 addSuperclasses(superclassElement); 500 addSuperclasses(superclassElement);
481 _superclasses.add(superclassElement); 501 _superclasses.add(superclassElement);
482 } 502 }
483 } 503 }
484 addSuperclasses(this); 504 addSuperclasses(this);
485 } 505 }
486 return _superclasses; 506 return _superclasses;
487 } 507 }
488 508
509 String get kindDescription =>
510 isAbstract == true ? 'abstract $uiKind' : uiKind;
511
489 /** 512 /**
490 * Returns classes that directly extend or implement this class. 513 * Returns classes that directly extend or implement this class.
491 */ 514 */
492 List<ClassElement> get subclasses { 515 List<ClassElement> get subclasses {
493 if (_subclasses == null) { 516 if (_subclasses == null) {
494 _subclasses = <ClassElement>[]; 517 _subclasses = <ClassElement>[];
495 for (var library in libraries.values) { 518 for (var library in libraries.values) {
496 for (ClassElement candidateClass in library.sortedClasses) { 519 for (ClassElement candidateClass in library.sortedClasses) {
497 if (candidateClass.implementsOrExtends(refId)) { 520 if (candidateClass.implementsOrExtends(refId)) {
498 _subclasses.add(candidateClass); 521 _subclasses.add(candidateClass);
(...skipping 18 matching lines...) Expand all
517 /** 540 /**
518 * Returns blocks of elements clustered by kind ordered in the desired 541 * Returns blocks of elements clustered by kind ordered in the desired
519 * order for describing a class definition. 542 * order for describing a class definition.
520 */ 543 */
521 List<ElementBlock> get childBlocks { 544 List<ElementBlock> get childBlocks {
522 if (_childBlocks == null) _childBlocks = _createElementBlocks(CLASS_KINDS); 545 if (_childBlocks == null) _childBlocks = _createElementBlocks(CLASS_KINDS);
523 return _childBlocks; 546 return _childBlocks;
524 } 547 }
525 } 548 }
526 549
550 /**
551 * Element describing a typedef.
552 */
527 class TypedefElement extends Element { 553 class TypedefElement extends Element {
528 final Reference returnType; 554 final Reference returnType;
529 List<ParameterElement> _parameters; 555 List<Element> _parameters;
530 556
531 TypedefElement(Map json, Element parent) : super(json, parent), 557 TypedefElement(Map json, Element parent) : super(json, parent),
532 returnType = jsonDeserializeReference(json['returnType']); 558 returnType = jsonDeserializeReference(json['returnType']);
533 559
534 /** 560 /**
535 * Returns a list of the parameters of the typedef. 561 * Returns a list of the parameters of the typedef.
536 */ 562 */
537 List<ParameterElement> get parameters { 563 List<Element> get parameters {
538 if (_parameters == null) { 564 if (_parameters == null) {
539 _parameters = _filterByKind('param'); 565 _parameters = _filterByKind('param');
540 } 566 }
541 return _parameters; 567 return _parameters;
542 } 568 }
543 } 569 }
544 570
545 /** 571 /**
546 * [Element] describing a method which may be a regular method, a setter, or an 572 * [Element] describing a method which may be a regular method, a setter, or an
547 * operator. 573 * operator.
548 */ 574 */
549 abstract class MethodElementBase extends Element { 575 abstract class MethodElementBase extends Element {
Siggi Cherem (dart-lang) 2012/12/19 19:47:33 consider renaming this class? some ideas: * ClassM
Jacob 2013/01/03 00:09:33 Went with MethodLikeElement. ClassMemberElement is
550 576
551 final bool isOperator; 577 final bool isOperator;
552 final bool isStatic; 578 final bool isStatic;
553 final bool isSetter; 579 final bool isSetter;
554 580
555 MethodElementBase(Map json, Element parent) 581 MethodElementBase(Map json, Element parent)
556 : super(json, parent), 582 : super(json, parent),
557 isOperator = json['isOperator'] == true, 583 isOperator = json['isOperator'] == true,
558 isStatic = json['isStatic'] == true, 584 isStatic = json['isStatic'] == true,
559 isSetter = json['isSetter'] == true; 585 isSetter = json['isSetter'] == true;
560 586
561 bool hasReference(String referenceId) { 587 bool hasReference(String referenceId) {
562 if (super.hasReference(referenceId)) return true; 588 if (super.hasReference(referenceId)) return true;
563 return returnType != null && returnType.refId == referenceId; 589 return returnType != null && returnType.refId == referenceId;
564 } 590 }
565 591
566 String get uiKind => isSetter ? 'property' : kind; 592 String get uiKind => isSetter ? 'property' : kind;
567 593
568 /** 594 /**
569 * Returns a plain text short description of the method suitable for rendering 595 * Returns a plain text short description of the method suitable for rendering
570 * in a tree control or other case where a short method description is 596 * in a tree control or other case where a short method description is
571 * required. 597 * required.
572 */ 598 */
573 String get shortDescription { 599 String get shortDescription {
574 if (isSetter == true) { 600 if (isSetter == true) {
Siggi Cherem (dart-lang) 2012/12/19 19:47:33 this should not be null by this point, you could s
Jacob 2013/01/02 19:54:58 sadly in the AST, setters aren't property elements
575 var sb = new StringBuffer('${name.substring(0, name.length-1)}'); 601 var sb = new StringBuffer('${name.substring(0, name.length-1)}');
Siggi Cherem (dart-lang) 2012/12/19 19:47:33 nit: spaces around '-' (name.length - 1)
Jacob 2013/01/02 19:54:58 Done.
576 if (!parameters.isEmpty && parameters.first != null 602 if (!parameters.isEmpty && parameters.first != null
577 && parameters.first.type != null) { 603 && parameters.first.type != null) {
578 sb..add(' ')..add(parameters.first.type.name); 604 sb..add(' ')..add(parameters.first.type.name);
Siggi Cherem (dart-lang) 2012/12/19 19:47:33 what you have seems fine, but it makes me ask some
Jacob 2013/01/02 19:54:58 my take is StringBuffer should just return void fr
579 } 605 }
580 return sb.toString(); 606 return sb.toString();
581 } 607 }
582 return '$name(${Strings.join(parameters.map( 608 return '$name(${Strings.join(parameters.map(
583 (arg) => arg.type != null ? arg.type.name : ''), ', ')})'; 609 (arg) => arg.type != null ? arg.type.name : ''), ', ')})';
584 } 610 }
585 611
586 Reference get returnType; 612 Reference get returnType;
587 List<ParameterElement> _parameters; 613 List<Element> _parameters;
588 614
589 /** 615 /**
590 * Returns a list of the parameters of the Method. 616 * Returns a list of the parameters of the Method.
591 */ 617 */
592 List<ParameterElement> get parameters { 618 List<Element> get parameters {
593 if (_parameters == null) { 619 if (_parameters == null) {
594 _parameters = _filterByKind('param'); 620 _parameters = _filterByKind('param');
595 } 621 }
596 return _parameters; 622 return _parameters;
597 } 623 }
598 624
599 // For UI purposes we want to treat operators as their own kind. 625 // For UI purposes we want to treat operators as their own kind.
600 String get kind => isOperator ? 'operator' : rawKind; 626 String get kind => isOperator ? 'operator' : rawKind;
601 } 627 }
602 628
603 /** 629 /**
604 * Element describing a parameter. 630 * Element describing a parameter.
605 */ 631 */
606 class ParameterElement extends Element { 632 class ParameterElement extends Element {
607 /** Type of the parameter. */ 633 /** Type of the parameter. */
608 final Reference type; 634 final Reference type;
609 /** Whether the parameter is optional. */ 635 /** Whether the parameter is optional. */
610 final bool isOptional; 636 final bool isOptional;
611 637
612 ParameterElement(Map json, Element parent) : 638 ParameterElement(Map json, Element parent) :
613 super(json, parent), 639 super(json, parent),
614 type = jsonDeserializeReference(json['ref']), 640 type = jsonDeserializeReference(json['ref']),
615 isOptional = json['isOptional']; 641 isOptional = json['isOptional'];
616 642
617 bool hasReference(String referenceId) { 643 bool hasReference(String referenceId) {
618 if (super.hasReference(referenceId)) return true; 644 if (super.hasReference(referenceId)) return true;
619 return type != null && type.refId == referenceId; 645 return type != null && type.refId == referenceId;
Siggi Cherem (dart-lang) 2012/12/19 19:47:33 consider swapping the order of the conditions? see
Jacob 2013/01/02 19:54:58 super.hasReference is cheap. In any case, both co
620 } 646 }
621 } 647 }
622 648
623 /** 649 /**
624 * Element describing a generic type parameter. 650 * Element describing a generic type parameter.
625 */ 651 */
626 class TypeParameterElement extends Element { 652 class TypeParameterElement extends Element {
627 /** Upper bound for the parameter. */ 653 /** Upper bound for the parameter. */
628 Reference upperBound; 654 Reference upperBound;
629 655
630 TypeParameterElement(Map json, Element parent) : 656 TypeParameterElement(Map json, Element parent) :
631 super(json, parent), 657 super(json, parent),
632 upperBound = jsonDeserializeReference(json['upperBound']); 658 upperBound = jsonDeserializeReference(json['upperBound']);
633 659
660 String get shortDescription {
661 if (upperBound == null) {
662 return name;
663 } else {
664 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
665 }
666 }
667
634 bool hasReference(String referenceId) { 668 bool hasReference(String referenceId) {
635 if (super.hasReference(referenceId)) return true; 669 if (super.hasReference(referenceId)) return true;
636 return upperBound != null && upperBound.refId == referenceId; 670 return upperBound != null && upperBound.refId == referenceId;
637 } 671 }
638 } 672 }
639 673
674 /**
675 * Element describing a method.
676 */
640 class MethodElement extends MethodElementBase { 677 class MethodElement extends MethodElementBase {
641 678
642 final Reference returnType; 679 final Reference returnType;
643 680
644 MethodElement(Map json, Element parent) : super(json, parent), 681 MethodElement(Map json, Element parent) : super(json, parent),
645 returnType = jsonDeserializeReference(json['returnType']); 682 returnType = jsonDeserializeReference(json['returnType']);
646 } 683 }
647 684
685 /**
686 * Element describing a property getter.
687 */
648 class PropertyElement extends MethodElementBase { 688 class PropertyElement extends MethodElementBase {
649 final Reference returnType; 689 final Reference returnType;
650 690
651 String get shortDescription => name; 691 String get shortDescription => name;
652 692
653 PropertyElement(Map json, Element parent) : super(json, parent), 693 PropertyElement(Map json, Element parent) : super(json, parent),
654 returnType = jsonDeserializeReference(json['ref']); 694 returnType = jsonDeserializeReference(json['ref']);
655 } 695 }
656 696
697 /**
698 * Element describing a variable.
699 */
657 class VariableElement extends MethodElementBase { 700 class VariableElement extends MethodElementBase {
658 final Reference returnType; 701 final Reference returnType;
659 /** Whether this variable is final. */ 702 /** Whether this variable is final. */
660 final bool isFinal; 703 final bool isFinal;
661 704
662 String get shortDescription => name; 705 String get shortDescription => name;
663 706
664 VariableElement(Map json, Element parent) : super(json, parent), 707 VariableElement(Map json, Element parent) : super(json, parent),
665 returnType = jsonDeserializeReference(json['ref']), 708 returnType = jsonDeserializeReference(json['ref']),
666 isFinal = json['isFinal']; 709 isFinal = json['isFinal'];
667 } 710 }
668 711
712 /**
713 * Element describing a constructor.
714 */
669 class ConstructorElement extends MethodElementBase { 715 class ConstructorElement extends MethodElementBase {
670 ConstructorElement(json, Element parent) : super(json, parent); 716 ConstructorElement(json, Element parent) : super(json, parent);
671 717
672 Reference get returnType => null; 718 Reference get returnType => null;
673 } 719 }
OLDNEW
« no previous file with comments | « no previous file | client/web/doc_link.html » ('j') | client/web/doc_link.html » ('J')

Powered by Google App Engine
This is Rietveld 408576698