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

Side by Side Diff: pkg/analyzer_experimental/lib/src/services/formatter_impl.dart

Issue 23308004: Formatter checkpoint. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 4 months 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 | « no previous file | pkg/analyzer_experimental/test/services/formatter_test.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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 library formatter_impl; 5 library formatter_impl;
6 6
7 import 'dart:math'; 7 import 'dart:math';
8 8
9 import 'package:analyzer_experimental/analyzer.dart'; 9 import 'package:analyzer_experimental/analyzer.dart';
10 import 'package:analyzer_experimental/src/generated/parser.dart'; 10 import 'package:analyzer_experimental/src/generated/parser.dart';
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 143
144 /// The writer to which the source is to be written. 144 /// The writer to which the source is to be written.
145 final SourceWriter writer; 145 final SourceWriter writer;
146 146
147 /// Cached line info for calculating blank lines. 147 /// Cached line info for calculating blank lines.
148 LineInfo lineInfo; 148 LineInfo lineInfo;
149 149
150 /// Cached previous token for calculating preceding whitespace. 150 /// Cached previous token for calculating preceding whitespace.
151 Token previousToken; 151 Token previousToken;
152 152
153 /// A flag to indicate that a newline should be emitted before the next token.
154 bool needsNewline = false;
155
156 /// A flag to indicate that user introduced newlines should be emitted before
157 /// the next token.
158 bool preservePrecedingNewlines = false;
159
153 /// Initialize a newly created visitor to write source code representing 160 /// Initialize a newly created visitor to write source code representing
154 /// the visited nodes to the given [writer]. 161 /// the visited nodes to the given [writer].
155 SourceVisitor(FormatterOptions options, this.lineInfo) : 162 SourceVisitor(FormatterOptions options, this.lineInfo) :
156 writer = new SourceWriter(indentCount: options.initialIndentationLevel, 163 writer = new SourceWriter(indentCount: options.initialIndentationLevel,
157 lineSeparator: options.lineSeparator); 164 lineSeparator: options.lineSeparator);
158 165
159 visitAdjacentStrings(AdjacentStrings node) { 166 visitAdjacentStrings(AdjacentStrings node) {
160 visitList(node.strings, ' '); 167 visitList(node.strings, ' ');
161 } 168 }
162 169
163 visitAnnotation(Annotation node) { 170 visitAnnotation(Annotation node) {
164 emitToken(node.atSign); 171 token(node.atSign);
165 visit(node.name); 172 visit(node.name);
166 visitPrefixed('.', node.constructorName); 173 visitPrefixed('.', node.constructorName);
167 visit(node.arguments); 174 visit(node.arguments);
168 } 175 }
169 176
170 visitArgumentDefinitionTest(ArgumentDefinitionTest node) { 177 visitArgumentDefinitionTest(ArgumentDefinitionTest node) {
171 emitToken(node.question); 178 token(node.question);
172 visit(node.identifier); 179 visit(node.identifier);
173 } 180 }
174 181
175 visitArgumentList(ArgumentList node) { 182 visitArgumentList(ArgumentList node) {
176 emitToken(node.leftParenthesis); 183 token(node.leftParenthesis);
177 visitList(node.arguments, ', '); 184 visitList(node.arguments, ', ');
178 emitToken(node.rightParenthesis); 185 token(node.rightParenthesis);
179 } 186 }
180 187
181 visitAsExpression(AsExpression node) { 188 visitAsExpression(AsExpression node) {
182 visit(node.expression); 189 visit(node.expression);
183 emitToken(node.asOperator, prefix: ' ', suffix: ' '); 190 space();
191 token(node.asOperator);
192 space();
184 visit(node.type); 193 visit(node.type);
185 } 194 }
186 195
187 visitAssertStatement(AssertStatement node) { 196 visitAssertStatement(AssertStatement node) {
188 emitToken(node.keyword, suffix: ' ('); 197 token(node.keyword);
198 space();
199 token(node.leftParenthesis);
189 visit(node.condition); 200 visit(node.condition);
190 emitToken(node.semicolon, prefix: ')'); 201 token(node.rightParenthesis);
202 token(node.semicolon);
191 } 203 }
192 204
193 visitAssignmentExpression(AssignmentExpression node) { 205 visitAssignmentExpression(AssignmentExpression node) {
194 visit(node.leftHandSide); 206 visit(node.leftHandSide);
195 emitToken(node.operator, prefix: ' ', suffix: ' '); 207 space();
208 token(node.operator);
209 space();
196 visit(node.rightHandSide); 210 visit(node.rightHandSide);
197 } 211 }
198 212
199 visitBinaryExpression(BinaryExpression node) { 213 visitBinaryExpression(BinaryExpression node) {
200 visit(node.leftOperand); 214 visit(node.leftOperand);
201 emitToken(node.operator, prefix: ' ', suffix: ' '); 215 space();
216 token(node.operator);
217 space();
202 visit(node.rightOperand); 218 visit(node.rightOperand);
203 } 219 }
204 220
205 visitBlock(Block node) { 221 visitBlock(Block node) {
206 emitToken(node.leftBracket); 222 token(node.leftBracket);
223 needsNewline = true;
207 indent(); 224 indent();
208 225
209 for (var stmt in node.statements) { 226 for (var stmt in node.statements) {
210 visit(stmt); 227 visit(stmt);
211 } 228 }
212 229
213 unindent(); 230 unindent();
214 newline(); 231 preservePrecedingNewlines = true;
215 print('}'); 232 needsNewline = true;
216 //TODO(pquitslund): make this work 233 token(node.rightBracket);
217 // emitToken(node.rightBracket);
218 previousToken = node.rightBracket;
219 } 234 }
220 235
221 visitBlockFunctionBody(BlockFunctionBody node) { 236 visitBlockFunctionBody(BlockFunctionBody node) {
222 visit(node.block); 237 visit(node.block);
223 } 238 }
224 239
225 visitBooleanLiteral(BooleanLiteral node) { 240 visitBooleanLiteral(BooleanLiteral node) {
226 emitToken(node.literal); 241 token(node.literal);
227 } 242 }
228 243
229 visitBreakStatement(BreakStatement node) { 244 visitBreakStatement(BreakStatement node) {
230 emitToken(node.keyword); 245 preservePrecedingNewlines = true;
246 token(node.keyword);
231 visitPrefixed(' ', node.label); 247 visitPrefixed(' ', node.label);
232 emitToken(node.semicolon); 248 token(node.semicolon);
249 needsNewline = true;
233 } 250 }
234 251
235 visitCascadeExpression(CascadeExpression node) { 252 visitCascadeExpression(CascadeExpression node) {
236 visit(node.target); 253 visit(node.target);
237 visitList(node.cascadeSections); 254 visitList(node.cascadeSections);
238 } 255 }
239 256
240 visitCatchClause(CatchClause node) { 257 visitCatchClause(CatchClause node) {
241 visitPrefixed('on ', node.exceptionType); 258 visitPrefixed('on ', node.exceptionType);
242 if (node.catchKeyword != null) { 259 if (node.catchKeyword != null) {
243 if (node.exceptionType != null) { 260 if (node.exceptionType != null) {
244 print(' '); 261 space();
245 } 262 }
246 print('catch ('); 263 token(node.catchKeyword);
264 space();
265 token(node.leftParenthesis);
247 visit(node.exceptionParameter); 266 visit(node.exceptionParameter);
248 visitPrefixed(', ', node.stackTraceParameter); 267 visitPrefixed(', ', node.stackTraceParameter);
249 print(') '); 268 token(node.rightParenthesis);
269 space();
250 } else { 270 } else {
251 print(' '); 271 space();
252 } 272 }
253 visit(node.body); 273 visit(node.body);
254 newline(); 274 needsNewline = true;
255 } 275 }
256 276
257 visitClassDeclaration(ClassDeclaration node) { 277 visitClassDeclaration(ClassDeclaration node) {
258 emitToken(node.abstractKeyword, suffix: ' '); 278 preservePrecedingNewlines = true;
259 emitToken(node.classKeyword, suffix: ' '); 279 modifier(node.abstractKeyword);
280 token(node.classKeyword);
281 space();
260 visit(node.name); 282 visit(node.name);
261 visit(node.typeParameters); 283 visit(node.typeParameters);
262 visitPrefixed(' ', node.extendsClause); 284 visitPrefixed(' ', node.extendsClause);
263 visitPrefixed(' ', node.withClause); 285 visitPrefixed(' ', node.withClause);
264 visitPrefixed(' ', node.implementsClause); 286 visitPrefixed(' ', node.implementsClause);
265 emitToken(node.leftBracket, prefix: ' '); 287 space();
288 token(node.leftBracket);
266 indent(); 289 indent();
267 290
268 for (var i = 0; i < node.members.length; i++) { 291 for (var i = 0; i < node.members.length; i++) {
269 visit(node.members[i]); 292 visit(node.members[i]);
270 } 293 }
271 294
272 unindent(); 295 unindent();
273 296
274 emitToken(node.rightBracket, minNewlines: 1); 297 emitPrecedingNewlines(node.rightBracket, min: 1);
298 token(node.rightBracket);
275 } 299 }
276 300
277 visitClassTypeAlias(ClassTypeAlias node) { 301 visitClassTypeAlias(ClassTypeAlias node) {
278 emitToken(node.keyword, suffix: ' '); 302 token(node.keyword);
303 space();
279 visit(node.name); 304 visit(node.name);
280 visit(node.typeParameters); 305 visit(node.typeParameters);
281 print(' = '); 306 space();
307 token(node.equals);
308 space();
282 if (node.abstractKeyword != null) { 309 if (node.abstractKeyword != null) {
283 print('abstract '); 310 token(node.abstractKeyword);
311 space();
284 } 312 }
285 visit(node.superclass); 313 visit(node.superclass);
286 visitPrefixed(' ', node.withClause); 314 visitPrefixed(' ', node.withClause);
287 visitPrefixed(' ', node.implementsClause); 315 visitPrefixed(' ', node.implementsClause);
288 emitToken(node.semicolon); 316 token(node.semicolon);
289 } 317 }
290 318
291 visitComment(Comment node) => null; 319 visitComment(Comment node) => null;
292 320
293 visitCommentReference(CommentReference node) => null; 321 visitCommentReference(CommentReference node) => null;
294 322
295 visitCompilationUnit(CompilationUnit node) { 323 visitCompilationUnit(CompilationUnit node) {
324
325 // Cache EOF for leading whitespace calculation
326 var start = node.beginToken.previous;
327 if (start != null && start.type is TokenType_EOF) {
328 previousToken = start;
329 }
330
296 var scriptTag = node.scriptTag; 331 var scriptTag = node.scriptTag;
297 var directives = node.directives; 332 var directives = node.directives;
298 visit(scriptTag); 333 visit(scriptTag);
299 var prefix = scriptTag == null ? '' : ' '; 334 visitList(directives);
300 visitPrefixedList(prefix, directives, ' '); 335 visitList(node.declarations);
301 //prefix = scriptTag == null && directives.isEmpty ? '' : ' ';
302 prefix = '';
303 visitPrefixedList(prefix, node.declarations);
304 336
305 //TODO(pquitslund): move this? 337 // Handle trailing whitespace
306 newline(); 338 preservePrecedingNewlines = true;
339 token(node.endToken /* EOF */);
307 } 340 }
308 341
309 visitConditionalExpression(ConditionalExpression node) { 342 visitConditionalExpression(ConditionalExpression node) {
310 visit(node.condition); 343 visit(node.condition);
311 print(' ? '); 344 space();
345 token(node.question);
346 space();
312 visit(node.thenExpression); 347 visit(node.thenExpression);
313 print(' : '); 348 space();
349 token(node.colon);
350 space();
314 visit(node.elseExpression); 351 visit(node.elseExpression);
315 } 352 }
316 353
317 visitConstructorDeclaration(ConstructorDeclaration node) { 354 visitConstructorDeclaration(ConstructorDeclaration node) {
318 emitToken(node.externalKeyword, suffix: ' '); 355 modifier(node.externalKeyword);
319 emitToken(node.constKeyword, suffix: ' '); 356 modifier(node.constKeyword);
320 emitToken(node.factoryKeyword, suffix: ' '); 357 modifier(node.factoryKeyword);
321 visit(node.returnType); 358 visit(node.returnType);
322 visitPrefixed('.', node.name); 359 visitPrefixed('.', node.name);
323 visit(node.parameters); 360 visit(node.parameters);
324 visitPrefixedList(' : ', node.initializers, ', '); 361 visitPrefixedList(' : ', node.initializers, ', ');
325 visitPrefixed(' = ', node.redirectedConstructor); 362 visitPrefixed(' = ', node.redirectedConstructor);
326 visitPrefixedBody(' ', node.body); 363 visitPrefixedBody(' ', node.body);
327 } 364 }
328 365
329 visitConstructorFieldInitializer(ConstructorFieldInitializer node) { 366 visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
330 emitToken(node.keyword, suffix: '.'); 367 token(node.keyword);
368 token(node.period);
331 visit(node.fieldName); 369 visit(node.fieldName);
332 print(' = '); 370 space();
371 token(node.equals);
372 space();
333 visit(node.expression); 373 visit(node.expression);
334 } 374 }
335 375
336 visitConstructorName(ConstructorName node) { 376 visitConstructorName(ConstructorName node) {
337 visit(node.type); 377 visit(node.type);
338 visitPrefixed('.', node.name); 378 visitPrefixed('.', node.name);
339 } 379 }
340 380
341 visitContinueStatement(ContinueStatement node) { 381 visitContinueStatement(ContinueStatement node) {
342 emitToken(node.keyword); 382 token(node.keyword);
343 visitPrefixed(' ', node.label); 383 visitPrefixed(' ', node.label);
344 emitToken(node.semicolon); 384 token(node.semicolon);
345 } 385 }
346 386
347 visitDeclaredIdentifier(DeclaredIdentifier node) { 387 visitDeclaredIdentifier(DeclaredIdentifier node) {
348 emitToken(node.keyword, suffix: ' '); 388 token(node.keyword);
389 space();
349 visitSuffixed(node.type, ' '); 390 visitSuffixed(node.type, ' ');
350 visit(node.identifier); 391 visit(node.identifier);
351 } 392 }
352 393
353 visitDefaultFormalParameter(DefaultFormalParameter node) { 394 visitDefaultFormalParameter(DefaultFormalParameter node) {
354 visit(node.parameter); 395 visit(node.parameter);
355 if (node.separator != null) { 396 if (node.separator != null) {
356 print(' '); 397 space();
357 print(node.separator.lexeme); 398 token(node.separator);
358 visitPrefixed(' ', node.defaultValue); 399 visitPrefixed(' ', node.defaultValue);
359 } 400 }
360 } 401 }
361 402
362 visitDoStatement(DoStatement node) { 403 visitDoStatement(DoStatement node) {
363 emitToken(node.doKeyword, suffix: ' '); 404 token(node.doKeyword);
405 space();
364 visit(node.body); 406 visit(node.body);
365 emitToken(node.whileKeyword, prefix: ' ', suffix: ' ('); 407 space();
408 token(node.whileKeyword);
409 space();
410 token(node.leftParenthesis);
366 visit(node.condition); 411 visit(node.condition);
367 emitToken(node.semicolon, prefix: ')'); 412 token(node.rightParenthesis);
413 token(node.semicolon);
368 } 414 }
369 415
370 visitDoubleLiteral(DoubleLiteral node) { 416 visitDoubleLiteral(DoubleLiteral node) {
371 print(node.literal.lexeme); 417 token(node.literal);
372 } 418 }
373 419
374 visitEmptyFunctionBody(EmptyFunctionBody node) { 420 visitEmptyFunctionBody(EmptyFunctionBody node) {
375 emitToken(node.semicolon); 421 token(node.semicolon);
376 } 422 }
377 423
378 visitEmptyStatement(EmptyStatement node) { 424 visitEmptyStatement(EmptyStatement node) {
379 emitToken(node.semicolon); 425 token(node.semicolon);
380 } 426 }
381 427
382 visitExportDirective(ExportDirective node) { 428 visitExportDirective(ExportDirective node) {
383 emitToken(node.keyword, suffix: ' '); 429 token(node.keyword);
430 space();
384 visit(node.uri); 431 visit(node.uri);
385 visitPrefixedList(' ', node.combinators, ' '); 432 visitPrefixedList(' ', node.combinators, ' ');
386 emitToken(node.semicolon); 433 token(node.semicolon);
387 } 434 }
388 435
389 visitExpressionFunctionBody(ExpressionFunctionBody node) { 436 visitExpressionFunctionBody(ExpressionFunctionBody node) {
390 emitToken(node.functionDefinition, suffix: ' '); 437 token(node.functionDefinition);
438 space();
391 visit(node.expression); 439 visit(node.expression);
392 emitToken(node.semicolon); 440 token(node.semicolon);
393 } 441 }
394 442
395 visitExpressionStatement(ExpressionStatement node) { 443 visitExpressionStatement(ExpressionStatement node) {
396 visit(node.expression); 444 visit(node.expression);
397 emitToken(node.semicolon); 445 token(node.semicolon);
398 } 446 }
399 447
400 visitExtendsClause(ExtendsClause node) { 448 visitExtendsClause(ExtendsClause node) {
401 emitToken(node.keyword, suffix: ' '); 449 token(node.keyword);
450 space();
402 visit(node.superclass); 451 visit(node.superclass);
403 } 452 }
404 453
405 visitFieldDeclaration(FieldDeclaration node) { 454 visitFieldDeclaration(FieldDeclaration node) {
406 emitToken(node.keyword, suffix: ' '); 455 token(node.keyword);
456 space();
407 visit(node.fields); 457 visit(node.fields);
408 emitToken(node.semicolon); 458 token(node.semicolon);
409 } 459 }
410 460
411 visitFieldFormalParameter(FieldFormalParameter node) { 461 visitFieldFormalParameter(FieldFormalParameter node) {
412 emitToken(node.keyword, suffix: ' '); 462 token(node.keyword);
463 space();
413 visitSuffixed(node.type, ' '); 464 visitSuffixed(node.type, ' ');
414 print('this.'); 465 token(node.thisToken);
466 token(node.period);
415 visit(node.identifier); 467 visit(node.identifier);
416 visit(node.parameters); 468 visit(node.parameters);
417 } 469 }
418 470
419 visitForEachStatement(ForEachStatement node) { 471 visitForEachStatement(ForEachStatement node) {
420 print('for ('); 472 token(node.forKeyword);
473 space();
474 token(node.leftParenthesis);
421 visit(node.loopVariable); 475 visit(node.loopVariable);
422 print(' in '); 476 space();
477 token(node.inKeyword);
478 space();
423 visit(node.iterator); 479 visit(node.iterator);
424 print(') '); 480 token(node.leftParenthesis);
481 space();
425 visit(node.body); 482 visit(node.body);
426 } 483 }
427 484
428 visitFormalParameterList(FormalParameterList node) { 485 visitFormalParameterList(FormalParameterList node) {
429 var groupEnd = null; 486 var groupEnd = null;
430 print('('); 487 token(node.leftParenthesis);
431 var parameters = node.parameters; 488 var parameters = node.parameters;
432 var size = parameters.length; 489 var size = parameters.length;
433 for (var i = 0; i < size; i++) { 490 for (var i = 0; i < size; i++) {
434 var parameter = parameters[i]; 491 var parameter = parameters[i];
435 if (i > 0) { 492 if (i > 0) {
436 print(', '); 493 append(', ');
437 } 494 }
438 if (groupEnd == null && parameter is DefaultFormalParameter) { 495 if (groupEnd == null && parameter is DefaultFormalParameter) {
439 if (identical(parameter.kind, ParameterKind.NAMED)) { 496 if (identical(parameter.kind, ParameterKind.NAMED)) {
440 groupEnd = '}'; 497 groupEnd = '}';
441 print('{'); 498 append('{');
442 } else { 499 } else {
443 groupEnd = ']'; 500 groupEnd = ']';
444 print('['); 501 append('[');
445 } 502 }
446 } 503 }
447 parameter.accept(this); 504 parameter.accept(this);
448 } 505 }
449 if (groupEnd != null) { 506 if (groupEnd != null) {
450 print(groupEnd); 507 append(groupEnd);
451 } 508 }
452 print(')'); 509 token(node.rightParenthesis);
453 } 510 }
454 511
455 visitForStatement(ForStatement node) { 512 visitForStatement(ForStatement node) {
513 token(node.forKeyword);
514 space();
515 token(node.leftParenthesis);
456 var initialization = node.initialization; 516 var initialization = node.initialization;
457 print('for (');
458 if (initialization != null) { 517 if (initialization != null) {
459 visit(initialization); 518 visit(initialization);
460 } else { 519 } else {
461 visit(node.variables); 520 visit(node.variables);
462 } 521 }
463 print(';'); 522 token(node.leftSeparator);
464 visitPrefixed(' ', node.condition); 523 visitPrefixed(' ', node.condition);
465 print(';'); 524 token(node.rightSeparator);
466 visitPrefixedList(' ', node.updaters, ', '); 525 visitPrefixedList(' ', node.updaters, ', ');
467 print(') '); 526 token(node.leftParenthesis);
527 space();
468 visit(node.body); 528 visit(node.body);
469 } 529 }
470 530
471 visitFunctionDeclaration(FunctionDeclaration node) { 531 visitFunctionDeclaration(FunctionDeclaration node) {
532 needsNewline = true;
533 preservePrecedingNewlines = true;
472 visitSuffixed(node.returnType, ' '); 534 visitSuffixed(node.returnType, ' ');
473 emitToken(node.propertyKeyword, suffix: ' '); 535 token(node.propertyKeyword, followedBy: space);
474 visit(node.name); 536 visit(node.name);
475 visit(node.functionExpression); 537 visit(node.functionExpression);
476 } 538 }
477 539
478 visitFunctionDeclarationStatement(FunctionDeclarationStatement node) { 540 visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
479 visit(node.functionDeclaration); 541 visit(node.functionDeclaration);
480 print(';'); 542 // TODO(pquitslund): fix and handle in function body
543 append(';');
481 } 544 }
482 545
483 visitFunctionExpression(FunctionExpression node) { 546 visitFunctionExpression(FunctionExpression node) {
484 visit(node.parameters); 547 visit(node.parameters);
485 print(' '); 548 space();
486 visit(node.body); 549 visit(node.body);
487 } 550 }
488 551
489 visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { 552 visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
490 visit(node.function); 553 visit(node.function);
491 visit(node.argumentList); 554 visit(node.argumentList);
492 } 555 }
493 556
494 visitFunctionTypeAlias(FunctionTypeAlias node) { 557 visitFunctionTypeAlias(FunctionTypeAlias node) {
495 emitToken(node.keyword, suffix: ' '); 558 token(node.keyword);
559 space();
496 visitSuffixed(node.returnType, ' '); 560 visitSuffixed(node.returnType, ' ');
497 visit(node.name); 561 visit(node.name);
498 visit(node.typeParameters); 562 visit(node.typeParameters);
499 visit(node.parameters); 563 visit(node.parameters);
500 emitToken(node.semicolon); 564 token(node.semicolon);
501 } 565 }
502 566
503 visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) { 567 visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
504 visitSuffixed(node.returnType, ' '); 568 visitSuffixed(node.returnType, ' ');
505 visit(node.identifier); 569 visit(node.identifier);
506 visit(node.parameters); 570 visit(node.parameters);
507 } 571 }
508 572
509 visitHideCombinator(HideCombinator node) { 573 visitHideCombinator(HideCombinator node) {
510 emitToken(node.keyword, suffix: ' '); 574 token(node.keyword);
575 space();
511 visitList(node.hiddenNames, ', '); 576 visitList(node.hiddenNames, ', ');
512 } 577 }
513 578
514 visitIfStatement(IfStatement node) { 579 visitIfStatement(IfStatement node) {
515 emitToken(node.ifKeyword); 580 preservePrecedingNewlines = true;
516 print(' ('); 581 token(node.ifKeyword);
582 space();
583 token(node.leftParenthesis);
517 visit(node.condition); 584 visit(node.condition);
518 print(') '); 585 token(node.rightParenthesis);
586 space();
519 visit(node.thenStatement); 587 visit(node.thenStatement);
520 visitPrefixed(' else ', node.elseStatement); 588 //visitPrefixed(' else ', node.elseStatement);
589 if (node.elseStatement != null) {
590 space();
591 token(node.elseKeyword);
592 space();
593 visit(node.elseStatement);
594 }
595 needsNewline = true;
521 } 596 }
522 597
523 visitImplementsClause(ImplementsClause node) { 598 visitImplementsClause(ImplementsClause node) {
524 emitToken(node.keyword, suffix: ' '); 599 token(node.keyword);
600 space();
525 visitList(node.interfaces, ', '); 601 visitList(node.interfaces, ', ');
526 } 602 }
527 603
528 visitImportDirective(ImportDirective node) { 604 visitImportDirective(ImportDirective node) {
529 emitToken(node.keyword, suffix: ' '); 605 preservePrecedingNewlines = true;
606 token(node.keyword);
607 space();
530 visit(node.uri); 608 visit(node.uri);
531 visitPrefixed(' as ', node.prefix); 609 visitPrefixed(' as ', node.prefix);
532 visitPrefixedList(' ', node.combinators, ' '); 610 visitPrefixedList(' ', node.combinators, ' ');
533 emitToken(node.semicolon); 611 token(node.semicolon);
612 needsNewline = true;
534 } 613 }
535 614
536 visitIndexExpression(IndexExpression node) { 615 visitIndexExpression(IndexExpression node) {
537 if (node.isCascaded) { 616 if (node.isCascaded) {
538 print('..'); 617 token(node.period);
539 } else { 618 } else {
540 visit(node.target); 619 visit(node.target);
541 } 620 }
542 print('['); 621 token(node.leftBracket);
543 visit(node.index); 622 visit(node.index);
544 print(']'); 623 token(node.rightBracket);
545 } 624 }
546 625
547 visitInstanceCreationExpression(InstanceCreationExpression node) { 626 visitInstanceCreationExpression(InstanceCreationExpression node) {
548 emitToken(node.keyword, suffix: ' '); 627 token(node.keyword);
628 space();
549 visit(node.constructorName); 629 visit(node.constructorName);
550 visit(node.argumentList); 630 visit(node.argumentList);
551 } 631 }
552 632
553 visitIntegerLiteral(IntegerLiteral node) { 633 visitIntegerLiteral(IntegerLiteral node) {
554 print(node.literal.lexeme); 634 token(node.literal);
555 } 635 }
556 636
557 visitInterpolationExpression(InterpolationExpression node) { 637 visitInterpolationExpression(InterpolationExpression node) {
558 if (node.rightBracket != null) { 638 if (node.rightBracket != null) {
559 print('\${'); 639 token(node.leftBracket);
560 visit(node.expression); 640 visit(node.expression);
561 print('}'); 641 token(node.rightBracket);
562 } else { 642 } else {
563 print('\$'); 643 token(node.leftBracket);
564 visit(node.expression); 644 visit(node.expression);
565 } 645 }
566 } 646 }
567 647
568 visitInterpolationString(InterpolationString node) { 648 visitInterpolationString(InterpolationString node) {
569 print(node.contents.lexeme); 649 token(node.contents);
570 } 650 }
571 651
572 visitIsExpression(IsExpression node) { 652 visitIsExpression(IsExpression node) {
573 visit(node.expression); 653 visit(node.expression);
574 if (node.notOperator == null) { 654 space();
575 print(' is '); 655 token(node.isOperator);
576 } else { 656 token(node.notOperator);
577 print(' is! '); 657 space();
578 }
579 visit(node.type); 658 visit(node.type);
580 } 659 }
581 660
582 visitLabel(Label node) { 661 visitLabel(Label node) {
583 visit(node.label); 662 visit(node.label);
584 print(':'); 663 token(node.colon);
585 } 664 }
586 665
587 visitLabeledStatement(LabeledStatement node) { 666 visitLabeledStatement(LabeledStatement node) {
588 visitSuffixedList(node.labels, ' ', ' '); 667 visitSuffixedList(node.labels, ' ', ' ');
589 visit(node.statement); 668 visit(node.statement);
590 } 669 }
591 670
592 visitLibraryDirective(LibraryDirective node) { 671 visitLibraryDirective(LibraryDirective node) {
593 emitToken(node.keyword, suffix: ' '); 672 token(node.keyword);
673 space();
594 visit(node.name); 674 visit(node.name);
595 emitToken(node.semicolon); 675 token(node.semicolon);
596 } 676 }
597 677
598 visitLibraryIdentifier(LibraryIdentifier node) { 678 visitLibraryIdentifier(LibraryIdentifier node) {
599 print(node.name); 679 append(node.name);
600 } 680 }
601 681
602 visitListLiteral(ListLiteral node) { 682 visitListLiteral(ListLiteral node) {
603 if (node.modifier != null) { 683 if (node.modifier != null) {
604 print(node.modifier.lexeme); 684 token(node.modifier);
605 print(' '); 685 space();
606 } 686 }
607 visit(node.typeArguments); 687 visit(node.typeArguments);
608 print('['); 688 token(node.leftBracket);
609 visitList(node.elements, ', '); 689 visitList(node.elements, ', ');
610 print(']'); 690 token(node.rightBracket);
611 } 691 }
612 692
613 visitMapLiteral(MapLiteral node) { 693 visitMapLiteral(MapLiteral node) {
614 if (node.modifier != null) { 694 modifier(node.modifier);
615 print(node.modifier.lexeme);
616 print(' ');
617 }
618 visitSuffixed(node.typeArguments, ' '); 695 visitSuffixed(node.typeArguments, ' ');
619 print('{'); 696 token(node.leftBracket);
620 visitList(node.entries, ', '); 697 visitList(node.entries, ', ');
621 print('}'); 698 token(node.rightBracket);
622 } 699 }
623 700
624 visitMapLiteralEntry(MapLiteralEntry node) { 701 visitMapLiteralEntry(MapLiteralEntry node) {
625 visit(node.key); 702 visit(node.key);
626 print(' : '); 703 space();
704 token(node.separator);
705 space();
627 visit(node.value); 706 visit(node.value);
628 } 707 }
629 708
630 visitMethodDeclaration(MethodDeclaration node) { 709 visitMethodDeclaration(MethodDeclaration node) {
631 emitToken(node.externalKeyword, suffix: ' '); 710 needsNewline = true;
632 emitToken(node.modifierKeyword, suffix: ' '); 711 preservePrecedingNewlines = true;
712 modifier(node.externalKeyword);
713 modifier(node.modifierKeyword);
633 visitSuffixed(node.returnType, ' '); 714 visitSuffixed(node.returnType, ' ');
634 emitToken(node.propertyKeyword, suffix: ' '); 715 modifier(node.propertyKeyword);
635 emitToken(node.operatorKeyword, suffix: ' '); 716 modifier(node.operatorKeyword);
636 visit(node.name); 717 visit(node.name);
637 if (!node.isGetter) { 718 if (!node.isGetter) {
638 visit(node.parameters); 719 visit(node.parameters);
639 } 720 }
640 visitPrefixedBody(' ', node.body); 721 visitPrefixedBody(' ', node.body);
641 } 722 }
642 723
643 visitMethodInvocation(MethodInvocation node) { 724 visitMethodInvocation(MethodInvocation node) {
644 if (node.isCascaded) { 725 if (node.isCascaded) {
645 print('..'); 726 token(node.period);
646 } else { 727 } else {
647 visitSuffixed(node.target, '.'); 728 visitSuffixed(node.target, '.');
648 } 729 }
649 visit(node.methodName); 730 visit(node.methodName);
650 visit(node.argumentList); 731 visit(node.argumentList);
651 } 732 }
652 733
653 visitNamedExpression(NamedExpression node) { 734 visitNamedExpression(NamedExpression node) {
654 visit(node.name); 735 visit(node.name);
655 visitPrefixed(' ', node.expression); 736 visitPrefixed(' ', node.expression);
656 } 737 }
657 738
658 visitNativeClause(NativeClause node) { 739 visitNativeClause(NativeClause node) {
659 emitToken(node.keyword, suffix: ' '); 740 token(node.keyword);
741 space();
660 visit(node.name); 742 visit(node.name);
661 } 743 }
662 744
663 visitNativeFunctionBody(NativeFunctionBody node) { 745 visitNativeFunctionBody(NativeFunctionBody node) {
664 emitToken(node.nativeToken, suffix: ' '); 746 token(node.nativeToken);
747 space();
665 visit(node.stringLiteral); 748 visit(node.stringLiteral);
666 emitToken(node.semicolon); 749 token(node.semicolon);
667 } 750 }
668 751
669 visitNullLiteral(NullLiteral node) { 752 visitNullLiteral(NullLiteral node) {
670 emitToken(node.literal); 753 token(node.literal);
671 } 754 }
672 755
673 visitParenthesizedExpression(ParenthesizedExpression node) { 756 visitParenthesizedExpression(ParenthesizedExpression node) {
674 emitToken(node.leftParenthesis); 757 token(node.leftParenthesis);
675 visit(node.expression); 758 visit(node.expression);
676 emitToken(node.rightParenthesis); 759 token(node.rightParenthesis);
677 } 760 }
678 761
679 visitPartDirective(PartDirective node) { 762 visitPartDirective(PartDirective node) {
680 emitToken(node.keyword, suffix: ' '); 763 token(node.keyword);
764 space();
681 visit(node.uri); 765 visit(node.uri);
682 emitToken(node.semicolon); 766 token(node.semicolon);
683 } 767 }
684 768
685 visitPartOfDirective(PartOfDirective node) { 769 visitPartOfDirective(PartOfDirective node) {
686 emitToken(node.keyword, suffix: ' '); 770 token(node.keyword);
771 space();
687 visit(node.libraryName); 772 visit(node.libraryName);
688 emitToken(node.semicolon); 773 token(node.semicolon);
689 } 774 }
690 775
691 visitPostfixExpression(PostfixExpression node) { 776 visitPostfixExpression(PostfixExpression node) {
692 visit(node.operand); 777 visit(node.operand);
693 print(node.operator.lexeme); 778 token(node.operator);
694 } 779 }
695 780
696 visitPrefixedIdentifier(PrefixedIdentifier node) { 781 visitPrefixedIdentifier(PrefixedIdentifier node) {
697 visit(node.prefix); 782 visit(node.prefix);
698 print('.'); 783 token(node.period);
699 visit(node.identifier); 784 visit(node.identifier);
700 } 785 }
701 786
702 visitPrefixExpression(PrefixExpression node) { 787 visitPrefixExpression(PrefixExpression node) {
703 emitToken(node.operator); 788 token(node.operator);
704 visit(node.operand); 789 visit(node.operand);
705 } 790 }
706 791
707 visitPropertyAccess(PropertyAccess node) { 792 visitPropertyAccess(PropertyAccess node) {
708 if (node.isCascaded) { 793 if (node.isCascaded) {
709 print('..'); 794 token(node.operator);
710 } else { 795 } else {
711 visit(node.target); 796 visit(node.target);
712 print('.'); 797 token(node.operator);
713 } 798 }
714 visit(node.propertyName); 799 visit(node.propertyName);
715 } 800 }
716 801
717 visitRedirectingConstructorInvocation(RedirectingConstructorInvocation node) { 802 visitRedirectingConstructorInvocation(RedirectingConstructorInvocation node) {
718 emitToken(node.keyword); 803 token(node.keyword);
719 visitPrefixed('.', node.constructorName); 804 visitPrefixed('.', node.constructorName);
720 visit(node.argumentList); 805 visit(node.argumentList);
721 } 806 }
722 807
723 visitRethrowExpression(RethrowExpression node) { 808 visitRethrowExpression(RethrowExpression node) {
724 emitToken(node.keyword); 809 token(node.keyword);
725 } 810 }
726 811
727 visitReturnStatement(ReturnStatement node) { 812 visitReturnStatement(ReturnStatement node) {
813 preservePrecedingNewlines = true;
728 var expression = node.expression; 814 var expression = node.expression;
729 if (expression == null) { 815 if (expression == null) {
730 emitToken(node.keyword, minNewlines: 1); 816 token(node.keyword);
731 emitToken(node.semicolon); 817 token(node.semicolon);
732 } else { 818 } else {
733 emitToken(node.keyword, suffix: ' ', minNewlines: 1); 819 token(node.keyword);
820 space();
734 expression.accept(this); 821 expression.accept(this);
735 emitToken(node.semicolon); 822 token(node.semicolon);
736 } 823 }
737 } 824 }
738 825
739 visitScriptTag(ScriptTag node) { 826 visitScriptTag(ScriptTag node) {
740 print(node.scriptTag.lexeme); 827 token(node.scriptTag);
741 } 828 }
742 829
743 visitShowCombinator(ShowCombinator node) { 830 visitShowCombinator(ShowCombinator node) {
744 emitToken(node.keyword, suffix: ' '); 831 token(node.keyword);
832 space();
745 visitList(node.shownNames, ', '); 833 visitList(node.shownNames, ', ');
746 } 834 }
747 835
748 visitSimpleFormalParameter(SimpleFormalParameter node) { 836 visitSimpleFormalParameter(SimpleFormalParameter node) {
749 emitToken(node.keyword, suffix: ' '); 837 token(node.keyword);
838 space();
750 visitSuffixed(node.type, ' '); 839 visitSuffixed(node.type, ' ');
751 visit(node.identifier); 840 visit(node.identifier);
752 } 841 }
753 842
754 visitSimpleIdentifier(SimpleIdentifier node) { 843 visitSimpleIdentifier(SimpleIdentifier node) {
755 emitToken(node.token); 844 token(node.token);
756 } 845 }
757 846
758 visitSimpleStringLiteral(SimpleStringLiteral node) { 847 visitSimpleStringLiteral(SimpleStringLiteral node) {
759 emitToken(node.literal); 848 token(node.literal);
760 } 849 }
761 850
762 visitStringInterpolation(StringInterpolation node) { 851 visitStringInterpolation(StringInterpolation node) {
763 visitList(node.elements); 852 visitList(node.elements);
764 } 853 }
765 854
766 visitSuperConstructorInvocation(SuperConstructorInvocation node) { 855 visitSuperConstructorInvocation(SuperConstructorInvocation node) {
767 emitToken(node.keyword); 856 token(node.keyword);
768 visitPrefixed('.', node.constructorName); 857 visitPrefixed('.', node.constructorName);
769 visit(node.argumentList); 858 visit(node.argumentList);
770 } 859 }
771 860
772 visitSuperExpression(SuperExpression node) { 861 visitSuperExpression(SuperExpression node) {
773 emitToken(node.keyword); 862 token(node.keyword);
774 } 863 }
775 864
776 visitSwitchCase(SwitchCase node) { 865 visitSwitchCase(SwitchCase node) {
866 preservePrecedingNewlines = true;
777 visitSuffixedList(node.labels, ' ', ' '); 867 visitSuffixedList(node.labels, ' ', ' ');
778 emitToken(node.keyword, suffix: ' '); 868 token(node.keyword);
869 space();
779 visit(node.expression); 870 visit(node.expression);
780 print(':'); 871 token(node.colon);
781 indent(); 872 indent();
873 needsNewline = true;
782 visitList(node.statements); 874 visitList(node.statements);
783 unindent(); 875 unindent();
784 } 876 }
785 877
786 visitSwitchDefault(SwitchDefault node) { 878 visitSwitchDefault(SwitchDefault node) {
879 preservePrecedingNewlines = true;
787 visitSuffixedList(node.labels, ' ', ' '); 880 visitSuffixedList(node.labels, ' ', ' ');
788 emitToken(node.keyword, suffix: ': '); 881 token(node.keyword);
882 token(node.colon);
883 space();
789 visitList(node.statements, ' '); 884 visitList(node.statements, ' ');
790 } 885 }
791 886
792 visitSwitchStatement(SwitchStatement node) { 887 visitSwitchStatement(SwitchStatement node) {
793 emitToken(node.keyword); 888 token(node.keyword);
794 print(' ('); 889 space();
890 token(node.leftParenthesis);
795 visit(node.expression); 891 visit(node.expression);
796 print(') '); 892 token(node.rightParenthesis);
797 emitToken(node.leftBracket); 893 space();
894 token(node.leftBracket);
798 indent(); 895 indent();
799 visitList(node.members); 896 visitList(node.members);
800 unindent(); 897 unindent();
801 emitToken(node.rightBracket); 898 token(node.rightBracket);
802 newline(); 899 needsNewline = true;
803 } 900 }
804 901
805 visitSymbolLiteral(SymbolLiteral node) { 902 visitSymbolLiteral(SymbolLiteral node) {
806 // No-op ? 903 // No-op ?
807 } 904 }
808 905
809 visitThisExpression(ThisExpression node) { 906 visitThisExpression(ThisExpression node) {
810 emitToken(node.keyword); 907 token(node.keyword);
811 } 908 }
812 909
813 visitThrowExpression(ThrowExpression node) { 910 visitThrowExpression(ThrowExpression node) {
814 emitToken(node.keyword, suffix: ' '); 911 token(node.keyword);
912 space();
815 visit(node.expression); 913 visit(node.expression);
816 } 914 }
817 915
818 visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) { 916 visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
819 visitSuffixed(node.variables, ';'); 917 visitSuffixed(node.variables, ';');
820 } 918 }
821 919
822 visitTryStatement(TryStatement node) { 920 visitTryStatement(TryStatement node) {
823 emitToken(node.tryKeyword, suffix: ' '); 921 preservePrecedingNewlines = true;
922 token(node.tryKeyword);
923 space();
824 visit(node.body); 924 visit(node.body);
825 visitPrefixedList(' ', node.catchClauses, ' '); 925 visitPrefixedList(' ', node.catchClauses, ' ');
826 visitPrefixed(' finally ', node.finallyClause); 926 visitPrefixed(' finally ', node.finallyClause);
827 } 927 }
828 928
829 visitTypeArgumentList(TypeArgumentList node) { 929 visitTypeArgumentList(TypeArgumentList node) {
830 emitToken(node.leftBracket); 930 token(node.leftBracket);
831 visitList(node.arguments, ', '); 931 visitList(node.arguments, ', ');
832 emitToken(node.rightBracket); 932 token(node.rightBracket);
833 } 933 }
834 934
835 visitTypeName(TypeName node) { 935 visitTypeName(TypeName node) {
836 visit(node.name); 936 visit(node.name);
837 visit(node.typeArguments); 937 visit(node.typeArguments);
838 } 938 }
839 939
840 visitTypeParameter(TypeParameter node) { 940 visitTypeParameter(TypeParameter node) {
841 visit(node.name); 941 visit(node.name);
842 visitPrefixed(' extends ', node.bound); 942 visitPrefixed(' extends ', node.bound);
843 } 943 }
844 944
845 visitTypeParameterList(TypeParameterList node) { 945 visitTypeParameterList(TypeParameterList node) {
846 emitToken(node.leftBracket); 946 token(node.leftBracket);
847 visitList(node.typeParameters, ', '); 947 visitList(node.typeParameters, ', ');
848 emitToken(node.rightBracket); 948 token(node.rightBracket);
849 } 949 }
850 950
851 visitVariableDeclaration(VariableDeclaration node) { 951 visitVariableDeclaration(VariableDeclaration node) {
852 visit(node.name); 952 visit(node.name);
853 visitPrefixed(' = ', node.initializer); 953 visitPrefixed(' = ', node.initializer);
854 } 954 }
855 955
856 visitVariableDeclarationList(VariableDeclarationList node) { 956 visitVariableDeclarationList(VariableDeclarationList node) {
857 emitToken(node.keyword, suffix: ' '); 957 token(node.keyword);
958 space();
858 visitSuffixed(node.type, ' '); 959 visitSuffixed(node.type, ' ');
859 visitList(node.variables, ', '); 960 visitList(node.variables, ', ');
860 } 961 }
861 962
862 visitVariableDeclarationStatement(VariableDeclarationStatement node) { 963 visitVariableDeclarationStatement(VariableDeclarationStatement node) {
863 visit(node.variables); 964 visit(node.variables);
864 emitToken(node.semicolon); 965 token(node.semicolon);
865 } 966 }
866 967
867 visitWhileStatement(WhileStatement node) { 968 visitWhileStatement(WhileStatement node) {
868 emitToken(node.keyword, suffix: ' ('); 969 token(node.keyword);
970 space();
971 token(node.leftParenthesis);
869 visit(node.condition); 972 visit(node.condition);
870 print(') '); 973 token(node.rightParenthesis);
974 space();
871 visit(node.body); 975 visit(node.body);
872 } 976 }
873 977
874 visitWithClause(WithClause node) { 978 visitWithClause(WithClause node) {
875 emitToken(node.withKeyword, suffix: ' '); 979 token(node.withKeyword);
980 space();
876 visitList(node.mixinTypes, ', '); 981 visitList(node.mixinTypes, ', ');
877 } 982 }
878 983
879 /// Safely visit the given [node]. 984 /// Safely visit the given [node].
880 visit(ASTNode node) { 985 visit(ASTNode node) {
881 if (node != null) { 986 if (node != null) {
882 node.accept(this); 987 node.accept(this);
883 } 988 }
884 } 989 }
885 990
886 /// Safely visit the given [node], printing the [suffix] after the node if it 991 /// Safely visit the given [node], printing the [suffix] after the node if it
887 /// is non-null. 992 /// is non-null.
888 visitSuffixed(ASTNode node, String suffix) { 993 visitSuffixed(ASTNode node, String suffix) {
889 if (node != null) { 994 if (node != null) {
890 node.accept(this); 995 node.accept(this);
891 print(suffix); 996 append(suffix);
892 } 997 }
893 } 998 }
894 999
895 /// Safely visit the given [node], printing the [prefix] before the node if 1000 /// Safely visit the given [node], printing the [prefix] before the node if
896 /// it is non-null. 1001 /// it is non-null.
897 visitPrefixed(String prefix, ASTNode node) { 1002 visitPrefixed(String prefix, ASTNode node) {
898 if (node != null) { 1003 if (node != null) {
899 print(prefix); 1004 append(prefix);
900 node.accept(this); 1005 node.accept(this);
901 } 1006 }
902 } 1007 }
903 1008
904 /// Visit the given function [body], printing the [prefix] before if given 1009 /// Visit the given function [body], printing the [prefix] before if given
905 /// body is not empty. 1010 /// body is not empty.
906 visitPrefixedBody(String prefix, FunctionBody body) { 1011 visitPrefixedBody(String prefix, FunctionBody body) {
907 if (body is! EmptyFunctionBody) { 1012 if (body is! EmptyFunctionBody) {
908 print(prefix); 1013 append(prefix);
909 } 1014 }
910 visit(body); 1015 visit(body);
911 } 1016 }
912 1017
913 /// Print a list of [nodes], optionally separated by the given [separator]. 1018 /// Print a list of [nodes], optionally separated by the given [separator].
914 visitList(NodeList<ASTNode> nodes, [String separator = '']) { 1019 visitList(NodeList<ASTNode> nodes, [String separator = '']) {
915 if (nodes != null) { 1020 if (nodes != null) {
916 var size = nodes.length; 1021 var size = nodes.length;
917 for (var i = 0; i < size; i++) { 1022 for (var i = 0; i < size; i++) {
918 if (i > 0) { 1023 if (i > 0) {
919 print(separator); 1024 append(separator);
920 } 1025 }
921 nodes[i].accept(this); 1026 nodes[i].accept(this);
922 } 1027 }
923 } 1028 }
924 } 1029 }
925 1030
926 /// Print a list of [nodes], separated by the given [separator]. 1031 /// Print a list of [nodes], separated by the given [separator].
927 visitSuffixedList(NodeList<ASTNode> nodes, String separator, String suffix) { 1032 visitSuffixedList(NodeList<ASTNode> nodes, String separator, String suffix) {
928 if (nodes != null) { 1033 if (nodes != null) {
929 var size = nodes.length; 1034 var size = nodes.length;
930 if (size > 0) { 1035 if (size > 0) {
931 for (var i = 0; i < size; i++) { 1036 for (var i = 0; i < size; i++) {
932 if (i > 0) { 1037 if (i > 0) {
933 print(separator); 1038 append(separator);
934 } 1039 }
935 nodes[i].accept(this); 1040 nodes[i].accept(this);
936 } 1041 }
937 print(suffix); 1042 append(suffix);
938 } 1043 }
939 } 1044 }
940 } 1045 }
941 1046
942 /// Print a list of [nodes], separated by the given [separator]. 1047 /// Print a list of [nodes], separated by the given [separator].
943 visitPrefixedList(String prefix, NodeList<ASTNode> nodes, 1048 visitPrefixedList(String prefix, NodeList<ASTNode> nodes,
944 [String separator = null]) { 1049 [String separator = null]) {
945 if (nodes != null) { 1050 if (nodes != null) {
946 var size = nodes.length; 1051 var size = nodes.length;
947 if (size > 0) { 1052 if (size > 0) {
948 print(prefix); 1053 append(prefix);
949 for (var i = 0; i < size; i++) { 1054 for (var i = 0; i < size; i++) {
950 if (i > 0 && separator != null) { 1055 if (i > 0 && separator != null) {
951 print(separator); 1056 append(separator);
952 } 1057 }
953 nodes[i].accept(this); 1058 nodes[i].accept(this);
954 } 1059 }
955 } 1060 }
956 } 1061 }
957 } 1062 }
958 1063
959 1064 /// Emit the given [modifier] if it's non null, followed by non-breaking
960 /// Emit the given [token], if it's non-null, preceded by any detected 1065 /// whitespace.
961 /// newlines or a minimum as specified by [minNewlines], printing a [prefix] 1066 modifier(Token modifier) {
962 /// before and a [suffix] after. 1067 token(modifier, followedBy: space);
963 emitToken(Token token, {String prefix, String suffix, 1068 }
964 int minNewlines: 0}) { 1069
1070 token(Token token, {followedBy(), int minNewlines: 0}) {
965 if (token != null) { 1071 if (token != null) {
966 print(prefix); 1072 if (needsNewline) {
967 emitPrecedingNewlines(token, min: minNewlines); 1073 minNewlines = max(1, minNewlines);
968 print(token.lexeme); 1074 }
969 print(suffix); 1075 if (preservePrecedingNewlines || minNewlines > 0) {
970 } 1076 var emitted = emitPrecedingNewlines(token, min: minNewlines);
1077 preservePrecedingNewlines = false;
1078 if (emitted > 0) {
1079 needsNewline = false;
1080 }
1081 }
1082 append(token.lexeme);
1083 if (followedBy != null) {
1084 followedBy();
1085 }
1086 previousToken = token;
1087 }
1088 }
1089
1090 /// Emit a non-breakable space.
1091 space() {
1092 //TODO(pquitslund): replace with a proper space token
1093 append(' ');
971 } 1094 }
972 1095
973 /// Print the given [string] to the source writer if it's non-null. 1096 /// Emit a breakable space
974 print(String string) { 1097 breakableSpace() {
1098 //Implement
1099 }
1100
1101 /// Append the given [string] to the source writer if it's non-null.
1102 append(String string) {
975 if (string != null) { 1103 if (string != null) {
976 writer.print(string); 1104 writer.print(string);
977 } 1105 }
978 } 1106 }
979 1107
980 /// Emit a newline.
981 newline() {
982 writer.newline();
983 }
984
985 /// Emit [n] newlines.
986 newlines(n) {
987 writer.newlines(n);
988 }
989
990 /// Indent. 1108 /// Indent.
991 indent() { 1109 indent() {
992 writer.indent(); 1110 writer.indent();
993 } 1111 }
994 1112
995 /// Unindent 1113 /// Unindent
996 unindent() { 1114 unindent() {
997 writer.unindent(); 1115 writer.unindent();
998 } 1116 }
999 1117
1000 /// Emit any detected newlines or a minimum as specified by [minNewlines]. 1118 /// Emit any detected newlines or a minimum as specified by [minNewlines].
1001 emitPrecedingNewlines(Token token, {min: 0}) { 1119 int emitPrecedingNewlines(Token token, {min: 0}) {
1002 var comment = token.precedingComments; 1120 var comment = token.precedingComments;
1003 var currentToken = comment != null ? comment : token; 1121 var currentToken = comment != null ? comment : token;
1004 var lines = max(min, countNewlinesBetween(previousToken, currentToken)); 1122 var lines = max(min, countNewlinesBetween(previousToken, currentToken));
1005 newlines(lines); 1123 writer.newlines(lines);
1006 while (comment != null) { 1124 while (comment != null) {
1007 print(comment.toString().trim()); 1125 append(comment.toString().trim());
1008 newline(); 1126 writer.newline();
1009 comment = comment.next; 1127 comment = comment.next;
1010 } 1128 }
1011 1129
1012 previousToken = token; 1130 previousToken = token;
1131 return lines;
1013 } 1132 }
1014 1133
1015 /// Count the blanks between these two nodes. 1134 /// Count the blanks between these two nodes.
1016 int countBlankLinesBetween(ASTNode lastNode, ASTNode currentNode) => 1135 int countBlankLinesBetween(ASTNode lastNode, ASTNode currentNode) =>
1017 countNewlinesBetween(lastNode.endToken, currentNode.beginToken); 1136 countNewlinesBetween(lastNode.endToken, currentNode.beginToken);
1018 1137
1019 /// Count newlines preceeding this [node]. 1138 /// Count newlines preceeding this [node].
1020 int countPrecedingNewlines(ASTNode node) => 1139 int countPrecedingNewlines(ASTNode node) =>
1021 countNewlinesBetween(node.beginToken.previous, node.beginToken); 1140 countNewlinesBetween(node.beginToken.previous, node.beginToken);
1022 1141
1023 /// Count newlines succeeding this [node]. 1142 /// Count newlines succeeding this [node].
1024 int countSucceedingNewlines(ASTNode node) => node == null ? 0 : 1143 int countSucceedingNewlines(ASTNode node) => node == null ? 0 :
1025 countNewlinesBetween(node.endToken, node.endToken.next); 1144 countNewlinesBetween(node.endToken, node.endToken.next);
1026 1145
1027 /// Count the blanks between these two nodes. 1146 /// Count the blanks between these two nodes.
1028 int countNewlinesBetween(Token last, Token current) { 1147 int countNewlinesBetween(Token last, Token current) {
1029 if (last == null || current == null) { 1148 if (last == null || current == null) {
1030 return 0; 1149 return 0;
1031 } 1150 }
1032 var lastLine = 1151 var lastLine =
1033 lineInfo.getLocation(last.offset).lineNumber; 1152 lineInfo.getLocation(last.offset).lineNumber;
1034 var currentLine = 1153 var currentLine =
1035 lineInfo.getLocation(current.offset).lineNumber; 1154 lineInfo.getLocation(current.offset).lineNumber;
1036 return currentLine - lastLine; 1155 return currentLine - lastLine;
1037 } 1156 }
1038 1157
1039 String toString() => writer.toString(); 1158 String toString() => writer.toString();
1040 1159
1041 } 1160 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer_experimental/test/services/formatter_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698