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

Side by Side Diff: pkg/analysis_server/tool/spec/to_html.dart

Issue 725143004: Format and sort analyzer and analysis_server packages. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « pkg/analysis_server/tool/spec/text_formatter.dart ('k') | pkg/analyzer/bin/analyzer.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 /** 5 /**
6 * Code for displaying the API as HTML. This is used both for generating a 6 * Code for displaying the API as HTML. This is used both for generating a
7 * full description of the API as a web page, and for generating doc comments 7 * full description of the API as a web page, and for generating doc comments
8 * in generated code. 8 * in generated code.
9 */ 9 */
10 library to.html; 10 library to.html;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 font-weight: bold; 56 font-weight: bold;
57 } 57 }
58 dt.request { 58 dt.request {
59 font-weight: bold; 59 font-weight: bold;
60 } 60 }
61 dt.typeDefinition { 61 dt.typeDefinition {
62 font-weight: bold; 62 font-weight: bold;
63 } 63 }
64 '''.trim(); 64 '''.trim();
65 65
66 final GeneratedFile target = new GeneratedFile('../../doc/api.html', () {
67 ToHtmlVisitor visitor = new ToHtmlVisitor(readApi());
68 dom.Document document = new dom.Document();
69 for (dom.Node node in visitor.collectHtml(visitor.visitApi)) {
70 document.append(node);
71 }
72 return document.outerHtml;
73 });
74
75 /**
76 * Translate spec_input.html into api.html.
77 */
78 main() {
79 target.generate();
80 }
81
82 /**
83 * Visitor that records the mapping from HTML elements to various kinds of API
84 * nodes.
85 */
86 class ApiMappings extends HierarchicalApiVisitor {
87 Map<dom.Element, Domain> domains = <dom.Element, Domain>{};
88
89 ApiMappings(Api api) : super(api);
90
91 @override
92 void visitDomain(Domain domain) {
93 domains[domain.html] = domain;
94 }
95 }
96
66 /** 97 /**
67 * Helper methods for creating HTML elements. 98 * Helper methods for creating HTML elements.
68 */ 99 */
69 abstract class HtmlMixin { 100 abstract class HtmlMixin {
70 void element(String name, Map<dynamic, String> attributes, [void callback()]);
71
72 void anchor(String id, void callback()) { 101 void anchor(String id, void callback()) {
73 element('a', { 102 element('a', {
74 'name': id 103 'name': id
75 }, callback); 104 }, callback);
76 } 105 }
77 void link(String id, void callback()) { 106
78 element('a', {
79 'href': '#$id'
80 }, callback);
81 }
82 void b(void callback()) => element('b', {}, callback); 107 void b(void callback()) => element('b', {}, callback);
108 void body(void callback()) => element('body', {}, callback);
83 void box(void callback()) { 109 void box(void callback()) {
84 element('div', { 110 element('div', {
85 'class': 'box' 111 'class': 'box'
86 }, callback); 112 }, callback);
87 } 113 }
88 void br() => element('br', {}); 114 void br() => element('br', {});
89 void body(void callback()) => element('body', {}, callback);
90 void dd(void callback()) => element('dd', {}, callback); 115 void dd(void callback()) => element('dd', {}, callback);
91 void dl(void callback()) => element('dl', {}, callback); 116 void dl(void callback()) => element('dl', {}, callback);
92 void dt(String cls, void callback()) => element('dt', { 117 void dt(String cls, void callback()) => element('dt', {
93 'class': cls 118 'class': cls
94 }, callback); 119 }, callback);
120 void element(String name, Map<dynamic, String> attributes, [void callback()]);
95 void gray(void callback()) => element('span', { 121 void gray(void callback()) => element('span', {
96 'style': 'color:#999999' 122 'style': 'color:#999999'
97 }, callback); 123 }, callback);
98 void h1(void callback()) => element('h1', {}, callback); 124 void h1(void callback()) => element('h1', {}, callback);
99 void h2(String cls, void callback()) { 125 void h2(String cls, void callback()) {
100 if (cls == null) { 126 if (cls == null) {
101 return element('h2', {}, callback); 127 return element('h2', {}, callback);
102 } 128 }
103 return element('h2', { 129 return element('h2', {
104 'class': cls 130 'class': cls
105 }, callback); 131 }, callback);
106 } 132 }
107 void h3(void callback()) => element('h3', {}, callback); 133 void h3(void callback()) => element('h3', {}, callback);
108 void h4(void callback()) => element('h4', {}, callback); 134 void h4(void callback()) => element('h4', {}, callback);
109 void hangingIndent(void callback()) => element('div', { 135 void hangingIndent(void callback()) => element('div', {
110 'class': 'hangingIndent' 136 'class': 'hangingIndent'
111 }, callback); 137 }, callback);
112 void head(void callback()) => element('head', {}, callback); 138 void head(void callback()) => element('head', {}, callback);
113 void html(void callback()) => element('html', {}, callback); 139 void html(void callback()) => element('html', {}, callback);
114 void i(void callback()) => element('i', {}, callback); 140 void i(void callback()) => element('i', {}, callback);
141 void link(String id, void callback()) {
142 element('a', {
143 'href': '#$id'
144 }, callback);
145 }
115 void p(void callback()) => element('p', {}, callback); 146 void p(void callback()) => element('p', {}, callback);
116 void pre(void callback()) => element('pre', {}, callback); 147 void pre(void callback()) => element('pre', {}, callback);
117 void title(void callback()) => element('title', {}, callback); 148 void title(void callback()) => element('title', {}, callback);
118 void tt(void callback()) => element('tt', {}, callback); 149 void tt(void callback()) => element('tt', {}, callback);
119 } 150 }
120 151
121 /** 152 /**
122 * Visitor that generates a compact representation of a type, such as:
123 *
124 * {
125 * "id": String
126 * "error": optional Error
127 * "result": {
128 * "version": String
129 * }
130 * }
131 */
132 class TypeVisitor extends HierarchicalApiVisitor with HtmlMixin, HtmlCodeGenerat or {
133 /**
134 * Set of fields which should be shown in boldface, or null if no field
135 * should be shown in boldface.
136 */
137 final Set<String> fieldsToBold;
138
139 /**
140 * True if a short description should be generated. In a short description,
141 * objects are shown as simply "object", and enums are shown as "String".
142 */
143 final bool short;
144
145 TypeVisitor(Api api, {this.fieldsToBold, this.short: false}) : super(api);
146
147 @override
148 void visitTypeEnum(TypeEnum typeEnum) {
149 if (short) {
150 write('String');
151 return;
152 }
153 writeln('enum {');
154 indent(() {
155 for (TypeEnumValue value in typeEnum.values) {
156 writeln(value.value);
157 }
158 });
159 write('}');
160 }
161
162 @override
163 void visitTypeList(TypeList typeList) {
164 write('List<');
165 visitTypeDecl(typeList.itemType);
166 write('>');
167 }
168
169 @override
170 void visitTypeMap(TypeMap typeMap) {
171 write('Map<');
172 visitTypeDecl(typeMap.keyType);
173 write(', ');
174 visitTypeDecl(typeMap.valueType);
175 write('>');
176 }
177
178 @override
179 void visitTypeObject(TypeObject typeObject) {
180 if (short) {
181 write('object');
182 return;
183 }
184 writeln('{');
185 indent(() {
186 for (TypeObjectField field in typeObject.fields) {
187 write('"');
188 if (fieldsToBold != null && fieldsToBold.contains(field.name)) {
189 b(() {
190 write(field.name);
191 });
192 } else {
193 write(field.name);
194 }
195 write('": ');
196 if (field.value != null) {
197 write(JSON.encode(field.value));
198 } else {
199 if (field.optional) {
200 gray(() {
201 write('optional');
202 });
203 write(' ');
204 }
205 visitTypeDecl(field.type);
206 }
207 writeln();
208 }
209 });
210 write('}');
211 }
212
213 @override
214 void visitTypeReference(TypeReference typeReference) {
215 String displayName = typeReference.typeName;
216 if (api.types.containsKey(typeReference.typeName)) {
217 link('type_${typeReference.typeName}', () {
218 write(displayName);
219 });
220 } else {
221 write(displayName);
222 }
223 }
224
225 @override
226 void visitTypeUnion(TypeUnion typeUnion) {
227 bool verticalBarNeeded = false;
228 for (TypeDecl choice in typeUnion.choices) {
229 if (verticalBarNeeded) {
230 write(' | ');
231 }
232 visitTypeDecl(choice);
233 verticalBarNeeded = true;
234 }
235 }
236 }
237
238 /**
239 * Visitor that records the mapping from HTML elements to various kinds of API
240 * nodes.
241 */
242 class ApiMappings extends HierarchicalApiVisitor {
243 ApiMappings(Api api) : super(api);
244
245 Map<dom.Element, Domain> domains = <dom.Element, Domain>{};
246
247 @override
248 void visitDomain(Domain domain) {
249 domains[domain.html] = domain;
250 }
251 }
252
253 /**
254 * Visitor that generates HTML documentation of the API. 153 * Visitor that generates HTML documentation of the API.
255 */ 154 */
256 class ToHtmlVisitor extends HierarchicalApiVisitor with HtmlMixin, HtmlGenerator { 155 class ToHtmlVisitor extends HierarchicalApiVisitor with HtmlMixin, HtmlGenerator
156 {
257 /** 157 /**
258 * Set of types defined in the API. 158 * Set of types defined in the API.
259 */ 159 */
260 Set<String> definedTypes = new Set<String>(); 160 Set<String> definedTypes = new Set<String>();
261 161
262 /** 162 /**
263 * Mappings from HTML elements to API nodes. 163 * Mappings from HTML elements to API nodes.
264 */ 164 */
265 ApiMappings apiMappings; 165 ApiMappings apiMappings;
266 166
267 ToHtmlVisitor(Api api) 167 ToHtmlVisitor(Api api)
268 : super(api), 168 : super(api),
269 apiMappings = new ApiMappings(api) { 169 apiMappings = new ApiMappings(api) {
270 apiMappings.visitApi(); 170 apiMappings.visitApi();
271 } 171 }
272 172
273 @override 173 /**
274 void visitApi() { 174 * Describe the payload of request, response, notification, refactoring
275 definedTypes = api.types.keys.toSet(); 175 * feedback, or refactoring options.
176 *
177 * If [force] is true, then a section is inserted even if the payload is
178 * null.
179 */
180 void describePayload(TypeObject subType, String name, {bool force: false}) {
181 if (force || subType != null) {
182 h4(() {
183 write(name);
184 });
185 if (subType == null) {
186 p(() {
187 write('none');
188 });
189 } else {
190 visitTypeDecl(subType);
191 }
192 }
193 }
276 194
277 html(() { 195 void javadocParams(TypeObject typeObject) {
278 translateHtml(api.html); 196 if (typeObject != null) {
197 for (TypeObjectField field in typeObject.fields) {
198 hangingIndent(() {
199 write('@param ${field.name} ');
200 translateHtml(field.html, squashParagraphs: true);
201 });
202 }
203 }
204 }
205
206 /**
207 * Generate a description of [type] using [TypeVisitor].
208 *
209 * If [shortDesc] is non-null, the output is prefixed with this string
210 * and a colon.
211 *
212 * If [typeForBolding] is supplied, then fields in this type are shown in
213 * boldface.
214 */
215 void showType(String shortDesc, TypeDecl type, [TypeObject typeForBolding]) {
216 Set<String> fieldsToBold = new Set<String>();
217 if (typeForBolding != null) {
218 for (TypeObjectField field in typeForBolding.fields) {
219 fieldsToBold.add(field.name);
220 }
221 }
222 pre(() {
223 if (shortDesc != null) {
224 write('$shortDesc: ');
225 }
226 TypeVisitor typeVisitor =
227 new TypeVisitor(api, fieldsToBold: fieldsToBold);
228 addAll(typeVisitor.collectHtml(() {
229 typeVisitor.visitTypeDecl(type);
230 }));
279 }); 231 });
280 } 232 }
281 233
282 @override
283 void visitRefactorings(Refactorings refactorings) {
284 translateHtml(refactorings.html);
285 dl(() {
286 super.visitRefactorings(refactorings);
287 });
288 }
289
290 @override visitRefactoring(Refactoring refactoring) {
291 dt('refactoring', () {
292 write(refactoring.kind);
293 });
294 dd(() {
295 translateHtml(refactoring.html);
296 describePayload(refactoring.feedback, 'Feedback', force: true);
297 describePayload(refactoring.options, 'Options', force: true);
298 });
299 }
300
301 @override
302 void visitTypes(Types types) {
303 translateHtml(types.html);
304 dl(() {
305 super.visitTypes(types);
306 });
307 }
308
309 @override
310 void visitDomain(Domain domain) {
311 h2('domain', () {
312 anchor('domain_${domain.name}', () {
313 write('Domain: ${domain.name}');
314 });
315 });
316 translateHtml(domain.html);
317 if (domain.requests.isNotEmpty) {
318 h3(() {
319 write('Requests');
320 });
321 dl(() {
322 domain.requests.forEach(visitRequest);
323 });
324 }
325 if (domain.notifications.isNotEmpty) {
326 h3(() {
327 write('Notifications');
328 });
329 dl(() {
330 domain.notifications.forEach(visitNotification);
331 });
332 }
333 }
334
335 @override
336 void visitNotification(Notification notification) {
337 dt('notification', () {
338 write(notification.longEvent);
339 });
340 dd(() {
341 box(() {
342 showType('notification', notification.notificationType, notification.par ams);
343 });
344 translateHtml(notification.html);
345 describePayload(notification.params, 'Parameters');
346 });
347 }
348
349 /** 234 /**
350 * Copy the contents of the given HTML element, translating the special 235 * Copy the contents of the given HTML element, translating the special
351 * elements that define the API appropriately. 236 * elements that define the API appropriately.
352 */ 237 */
353 void translateHtml(dom.Element html, {bool squashParagraphs: false}) { 238 void translateHtml(dom.Element html, {bool squashParagraphs: false}) {
354 for (dom.Node node in html.nodes) { 239 for (dom.Node node in html.nodes) {
355 if (node is dom.Element) { 240 if (node is dom.Element) {
356 if (squashParagraphs && node.localName == 'p') { 241 if (squashParagraphs && node.localName == 'p') {
357 translateHtml(node, squashParagraphs: squashParagraphs); 242 translateHtml(node, squashParagraphs: squashParagraphs);
358 continue; 243 continue;
(...skipping 29 matching lines...) Expand all
388 }); 273 });
389 } 274 }
390 } 275 }
391 } else if (node is dom.Text) { 276 } else if (node is dom.Text) {
392 String text = node.text; 277 String text = node.text;
393 write(text); 278 write(text);
394 } 279 }
395 } 280 }
396 } 281 }
397 282
398 /**
399 * Generate a description of [type] using [TypeVisitor].
400 *
401 * If [shortDesc] is non-null, the output is prefixed with this string
402 * and a colon.
403 *
404 * If [typeForBolding] is supplied, then fields in this type are shown in
405 * boldface.
406 */
407 void showType(String shortDesc, TypeDecl type, [TypeObject typeForBolding]) {
408 Set<String> fieldsToBold = new Set<String>();
409 if (typeForBolding != null) {
410 for (TypeObjectField field in typeForBolding.fields) {
411 fieldsToBold.add(field.name);
412 }
413 }
414 pre(() {
415 if (shortDesc != null) {
416 write('$shortDesc: ');
417 }
418 TypeVisitor typeVisitor = new TypeVisitor(api, fieldsToBold: fieldsToBold) ;
419 addAll(typeVisitor.collectHtml(() {
420 typeVisitor.visitTypeDecl(type);
421 }));
422 });
423 }
424
425 /**
426 * Describe the payload of request, response, notification, refactoring
427 * feedback, or refactoring options.
428 *
429 * If [force] is true, then a section is inserted even if the payload is
430 * null.
431 */
432 void describePayload(TypeObject subType, String name, {bool force: false}) {
433 if (force || subType != null) {
434 h4(() {
435 write(name);
436 });
437 if (subType == null) {
438 p(() {
439 write('none');
440 });
441 } else {
442 visitTypeDecl(subType);
443 }
444 }
445 }
446
447 void javadocParams(TypeObject typeObject) {
448 if (typeObject != null) {
449 for (TypeObjectField field in typeObject.fields) {
450 hangingIndent(() {
451 write('@param ${field.name} ');
452 translateHtml(field.html, squashParagraphs: true);
453 });
454 }
455 }
456 }
457
458 @override 283 @override
284 void visitApi() {
285 definedTypes = api.types.keys.toSet();
286
287 html(() {
288 translateHtml(api.html);
289 });
290 }
291
292 @override
293 void visitDomain(Domain domain) {
294 h2('domain', () {
295 anchor('domain_${domain.name}', () {
296 write('Domain: ${domain.name}');
297 });
298 });
299 translateHtml(domain.html);
300 if (domain.requests.isNotEmpty) {
301 h3(() {
302 write('Requests');
303 });
304 dl(() {
305 domain.requests.forEach(visitRequest);
306 });
307 }
308 if (domain.notifications.isNotEmpty) {
309 h3(() {
310 write('Notifications');
311 });
312 dl(() {
313 domain.notifications.forEach(visitNotification);
314 });
315 }
316 }
317
318 @override
319 void visitNotification(Notification notification) {
320 dt('notification', () {
321 write(notification.longEvent);
322 });
323 dd(() {
324 box(() {
325 showType(
326 'notification',
327 notification.notificationType,
328 notification.params);
329 });
330 translateHtml(notification.html);
331 describePayload(notification.params, 'Parameters');
332 });
333 }
334
335 @override visitRefactoring(Refactoring refactoring) {
336 dt('refactoring', () {
337 write(refactoring.kind);
338 });
339 dd(() {
340 translateHtml(refactoring.html);
341 describePayload(refactoring.feedback, 'Feedback', force: true);
342 describePayload(refactoring.options, 'Options', force: true);
343 });
344 }
345
346 @override
347 void visitRefactorings(Refactorings refactorings) {
348 translateHtml(refactorings.html);
349 dl(() {
350 super.visitRefactorings(refactorings);
351 });
352 }
353
354 @override
459 void visitRequest(Request request) { 355 void visitRequest(Request request) {
460 dt('request', () { 356 dt('request', () {
461 write(request.longMethod); 357 write(request.longMethod);
462 }); 358 });
463 dd(() { 359 dd(() {
464 box(() { 360 box(() {
465 showType('request', request.requestType, request.params); 361 showType('request', request.requestType, request.params);
466 br(); 362 br();
467 showType('response', request.responseType, request.result); 363 showType('response', request.responseType, request.result);
468 }); 364 });
(...skipping 24 matching lines...) Expand all
493 void visitTypeEnum(TypeEnum typeEnum) { 389 void visitTypeEnum(TypeEnum typeEnum) {
494 dl(() { 390 dl(() {
495 super.visitTypeEnum(typeEnum); 391 super.visitTypeEnum(typeEnum);
496 }); 392 });
497 } 393 }
498 394
499 @override 395 @override
500 void visitTypeEnumValue(TypeEnumValue typeEnumValue) { 396 void visitTypeEnumValue(TypeEnumValue typeEnumValue) {
501 bool isDocumented = false; 397 bool isDocumented = false;
502 for (dom.Node node in typeEnumValue.html.nodes) { 398 for (dom.Node node in typeEnumValue.html.nodes) {
503 if ((node is dom.Element && node.localName != 'code') || (node is dom.Text && node.text.trim().isNotEmpty)) { 399 if ((node is dom.Element && node.localName != 'code') ||
400 (node is dom.Text && node.text.trim().isNotEmpty)) {
504 isDocumented = true; 401 isDocumented = true;
505 break; 402 break;
506 } 403 }
507 } 404 }
508 dt('value', () { 405 dt('value', () {
509 write(typeEnumValue.value); 406 write(typeEnumValue.value);
510 }); 407 });
511 if (isDocumented) { 408 if (isDocumented) {
512 dd(() { 409 dd(() {
513 translateHtml(typeEnumValue.html); 410 translateHtml(typeEnumValue.html);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
558 }); 455 });
559 }); 456 });
560 dd(() { 457 dd(() {
561 translateHtml(typeObjectField.html); 458 translateHtml(typeObjectField.html);
562 }); 459 });
563 } 460 }
564 461
565 @override 462 @override
566 void visitTypeReference(TypeReference typeReference) { 463 void visitTypeReference(TypeReference typeReference) {
567 } 464 }
465
466 @override
467 void visitTypes(Types types) {
468 translateHtml(types.html);
469 dl(() {
470 super.visitTypes(types);
471 });
472 }
568 } 473 }
569 474
570 final GeneratedFile target = new GeneratedFile('../../doc/api.html', () { 475 /**
571 ToHtmlVisitor visitor = new ToHtmlVisitor(readApi()); 476 * Visitor that generates a compact representation of a type, such as:
572 dom.Document document = new dom.Document(); 477 *
573 for (dom.Node node in visitor.collectHtml(visitor.visitApi)) { 478 * {
574 document.append(node); 479 * "id": String
480 * "error": optional Error
481 * "result": {
482 * "version": String
483 * }
484 * }
485 */
486 class TypeVisitor extends HierarchicalApiVisitor with HtmlMixin,
487 HtmlCodeGenerator {
488 /**
489 * Set of fields which should be shown in boldface, or null if no field
490 * should be shown in boldface.
491 */
492 final Set<String> fieldsToBold;
493
494 /**
495 * True if a short description should be generated. In a short description,
496 * objects are shown as simply "object", and enums are shown as "String".
497 */
498 final bool short;
499
500 TypeVisitor(Api api, {this.fieldsToBold, this.short: false}) : super(api);
501
502 @override
503 void visitTypeEnum(TypeEnum typeEnum) {
504 if (short) {
505 write('String');
506 return;
507 }
508 writeln('enum {');
509 indent(() {
510 for (TypeEnumValue value in typeEnum.values) {
511 writeln(value.value);
512 }
513 });
514 write('}');
575 } 515 }
576 return document.outerHtml;
577 });
578 516
579 /** 517 @override
580 * Translate spec_input.html into api.html. 518 void visitTypeList(TypeList typeList) {
581 */ 519 write('List<');
582 main() { 520 visitTypeDecl(typeList.itemType);
583 target.generate(); 521 write('>');
522 }
523
524 @override
525 void visitTypeMap(TypeMap typeMap) {
526 write('Map<');
527 visitTypeDecl(typeMap.keyType);
528 write(', ');
529 visitTypeDecl(typeMap.valueType);
530 write('>');
531 }
532
533 @override
534 void visitTypeObject(TypeObject typeObject) {
535 if (short) {
536 write('object');
537 return;
538 }
539 writeln('{');
540 indent(() {
541 for (TypeObjectField field in typeObject.fields) {
542 write('"');
543 if (fieldsToBold != null && fieldsToBold.contains(field.name)) {
544 b(() {
545 write(field.name);
546 });
547 } else {
548 write(field.name);
549 }
550 write('": ');
551 if (field.value != null) {
552 write(JSON.encode(field.value));
553 } else {
554 if (field.optional) {
555 gray(() {
556 write('optional');
557 });
558 write(' ');
559 }
560 visitTypeDecl(field.type);
561 }
562 writeln();
563 }
564 });
565 write('}');
566 }
567
568 @override
569 void visitTypeReference(TypeReference typeReference) {
570 String displayName = typeReference.typeName;
571 if (api.types.containsKey(typeReference.typeName)) {
572 link('type_${typeReference.typeName}', () {
573 write(displayName);
574 });
575 } else {
576 write(displayName);
577 }
578 }
579
580 @override
581 void visitTypeUnion(TypeUnion typeUnion) {
582 bool verticalBarNeeded = false;
583 for (TypeDecl choice in typeUnion.choices) {
584 if (verticalBarNeeded) {
585 write(' | ');
586 }
587 visitTypeDecl(choice);
588 verticalBarNeeded = true;
589 }
590 }
584 } 591 }
OLDNEW
« no previous file with comments | « pkg/analysis_server/tool/spec/text_formatter.dart ('k') | pkg/analyzer/bin/analyzer.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698