OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |