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

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

Issue 113693003: dartfmt gets opinionated about 'gratuitous' linebreaks. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | pkg/analyzer/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/analyzer.dart'; 9 import 'package:analyzer/analyzer.dart';
10 import 'package:analyzer/src/generated/java_core.dart' show CharSequence; 10 import 'package:analyzer/src/generated/java_core.dart' show CharSequence;
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 345
346 /// Cached line info for calculating blank lines. 346 /// Cached line info for calculating blank lines.
347 LineInfo lineInfo; 347 LineInfo lineInfo;
348 348
349 /// Cached previous token for calculating preceding whitespace. 349 /// Cached previous token for calculating preceding whitespace.
350 Token previousToken; 350 Token previousToken;
351 351
352 /// A flag to indicate that a newline should be emitted before the next token. 352 /// A flag to indicate that a newline should be emitted before the next token.
353 bool needsNewline = false; 353 bool needsNewline = false;
354 354
355 /// A flag to indicate that user introduced newlines should be emitted before
356 /// the next token.
357 bool preserveNewlines = false;
358
355 /// A counter for spaces that should be emitted preceding the next token. 359 /// A counter for spaces that should be emitted preceding the next token.
356 int leadingSpaces = 0; 360 int leadingSpaces = 0;
357 361
358 /// A flag to specify whether line-leading spaces should be preserved (and 362 /// A flag to specify whether line-leading spaces should be preserved (and
359 /// addded to the indent level). 363 /// addded to the indent level).
360 bool allowLineLeadingSpaces; 364 bool allowLineLeadingSpaces;
361 365
362 /// Used for matching EOL comments 366 /// Used for matching EOL comments
363 final twoSlashes = new RegExp(r'//[^/]'); 367 final twoSlashes = new RegExp(r'//[^/]');
364 368
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
455 459
456 visitBreakStatement(BreakStatement node) { 460 visitBreakStatement(BreakStatement node) {
457 token(node.keyword); 461 token(node.keyword);
458 visitNode(node.label, precededBy: space); 462 visitNode(node.label, precededBy: space);
459 token(node.semicolon); 463 token(node.semicolon);
460 } 464 }
461 465
462 visitCascadeExpression(CascadeExpression node) { 466 visitCascadeExpression(CascadeExpression node) {
463 visit(node.target); 467 visit(node.target);
464 indent(2); 468 indent(2);
465 visitNodes(node.cascadeSections); 469 newlines();
470 visitNodes(node.cascadeSections, separatedBy: newlines);
466 unindent(2); 471 unindent(2);
467 } 472 }
468 473
469 visitCatchClause(CatchClause node) { 474 visitCatchClause(CatchClause node) {
470 475
471 token(node.onKeyword, followedBy: space); 476 token(node.onKeyword, followedBy: space);
472 visit(node.exceptionType); 477 visit(node.exceptionType);
473 478
474 if (node.catchKeyword != null) { 479 if (node.catchKeyword != null) {
475 if (node.exceptionType != null) { 480 if (node.exceptionType != null) {
476 space(); 481 space();
477 } 482 }
478 token(node.catchKeyword); 483 token(node.catchKeyword);
479 space(); 484 space();
480 token(node.leftParenthesis); 485 token(node.leftParenthesis);
481 visit(node.exceptionParameter); 486 visit(node.exceptionParameter);
482 token(node.comma, followedBy: space); 487 token(node.comma, followedBy: space);
483 visit(node.stackTraceParameter); 488 visit(node.stackTraceParameter);
484 token(node.rightParenthesis); 489 token(node.rightParenthesis);
485 space(); 490 space();
486 } else { 491 } else {
487 space(); 492 space();
488 } 493 }
489 visit(node.body); 494 visit(node.body);
490 } 495 }
491 496
492 visitClassDeclaration(ClassDeclaration node) { 497 visitClassDeclaration(ClassDeclaration node) {
498 preserveLeadingNewlines();
493 modifier(node.abstractKeyword); 499 modifier(node.abstractKeyword);
494 token(node.classKeyword); 500 token(node.classKeyword);
495 space(); 501 space();
496 visit(node.name); 502 visit(node.name);
497 allowContinuedLines((){ 503 allowContinuedLines((){
498 visit(node.typeParameters); 504 visit(node.typeParameters);
499 visitNode(node.extendsClause, precededBy: space); 505 visitNode(node.extendsClause, precededBy: space);
500 visitNode(node.withClause, precededBy: space); 506 visitNode(node.withClause, precededBy: space);
501 visitNode(node.implementsClause, precededBy: space); 507 visitNode(node.implementsClause, precededBy: space);
502 space(); 508 space();
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
540 } 546 }
541 547
542 var scriptTag = node.scriptTag; 548 var scriptTag = node.scriptTag;
543 var directives = node.directives; 549 var directives = node.directives;
544 visit(scriptTag); 550 visit(scriptTag);
545 551
546 visitNodes(directives, separatedBy: newlines, followedBy: newlines); 552 visitNodes(directives, separatedBy: newlines, followedBy: newlines);
547 553
548 visitNodes(node.declarations, separatedBy: newlines); 554 visitNodes(node.declarations, separatedBy: newlines);
549 555
556 preserveLeadingNewlines();
557
550 // Handle trailing whitespace 558 // Handle trailing whitespace
551 token(node.endToken /* EOF */); 559 token(node.endToken /* EOF */);
552 560
553 // Be a good citizen, end with a NL 561 // Be a good citizen, end with a NL
554 ensureTrailingNewline(); 562 ensureTrailingNewline();
555 } 563 }
556 564
557 visitConditionalExpression(ConditionalExpression node) { 565 visitConditionalExpression(ConditionalExpression node) {
558 visit(node.condition); 566 visit(node.condition);
559 space(); 567 space();
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
794 visitCommaSeparatedNodes(node.updaters); 802 visitCommaSeparatedNodes(node.updaters);
795 } 803 }
796 token(node.rightParenthesis); 804 token(node.rightParenthesis);
797 if (node.body is! EmptyStatement) { 805 if (node.body is! EmptyStatement) {
798 space(); 806 space();
799 } 807 }
800 visit(node.body); 808 visit(node.body);
801 } 809 }
802 810
803 visitFunctionDeclaration(FunctionDeclaration node) { 811 visitFunctionDeclaration(FunctionDeclaration node) {
812 preserveLeadingNewlines();
804 visitNode(node.returnType, followedBy: space); 813 visitNode(node.returnType, followedBy: space);
805 token(node.propertyKeyword, followedBy: space); 814 token(node.propertyKeyword, followedBy: space);
806 visit(node.name); 815 visit(node.name);
807 visit(node.functionExpression); 816 visit(node.functionExpression);
808 } 817 }
809 818
810 visitFunctionDeclarationStatement(FunctionDeclarationStatement node) { 819 visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
811 visit(node.functionDeclaration); 820 visit(node.functionDeclaration);
812 } 821 }
813 822
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
958 visitCommaSeparatedNodes(node.elements); 967 visitCommaSeparatedNodes(node.elements);
959 optionalTrailingComma(node.rightBracket); 968 optionalTrailingComma(node.rightBracket);
960 unindent(); 969 unindent();
961 token(node.rightBracket); 970 token(node.rightBracket);
962 } 971 }
963 972
964 visitMapLiteral(MapLiteral node) { 973 visitMapLiteral(MapLiteral node) {
965 modifier(node.constKeyword); 974 modifier(node.constKeyword);
966 visitNode(node.typeArguments, followedBy: space); 975 visitNode(node.typeArguments, followedBy: space);
967 token(node.leftBracket); 976 token(node.leftBracket);
977 newlines();
968 indent(); 978 indent();
969 visitCommaSeparatedNodes(node.entries); 979 visitCommaSeparatedNodes(node.entries, followedBy: newlines);
970 optionalTrailingComma(node.rightBracket); 980 optionalTrailingComma(node.rightBracket);
971 unindent(); 981 unindent();
982 newlines();
972 token(node.rightBracket); 983 token(node.rightBracket);
973 } 984 }
974 985
975 visitMapLiteralEntry(MapLiteralEntry node) { 986 visitMapLiteralEntry(MapLiteralEntry node) {
976 visit(node.key); 987 visit(node.key);
977 token(node.separator); 988 token(node.separator);
978 space(); 989 space();
979 visit(node.value); 990 visit(node.value);
980 } 991 }
981 992
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after
1302 nodes[i].accept(this); 1313 nodes[i].accept(this);
1303 } 1314 }
1304 if (followedBy != null) { 1315 if (followedBy != null) {
1305 followedBy(); 1316 followedBy();
1306 } 1317 }
1307 } 1318 }
1308 } 1319 }
1309 } 1320 }
1310 1321
1311 /// Visit a comma-separated list of [nodes] if not null. 1322 /// Visit a comma-separated list of [nodes] if not null.
1312 visitCommaSeparatedNodes(NodeList<ASTNode> nodes) { 1323 visitCommaSeparatedNodes(NodeList<ASTNode> nodes, {followedBy(): null}) {
1324 //TODO(pquitslund): handle this more neatly
pquitslund 2013/12/18 17:16:47 EG: by introducing a const pointer to the space fu
Brian Wilkerson 2013/12/18 17:53:07 In order to do that, the space function will have
1325 if (followedBy == null) {
1326 followedBy = space;
1327 }
1313 if (nodes != null) { 1328 if (nodes != null) {
1314 var size = nodes.length; 1329 var size = nodes.length;
1315 if (size > 0) { 1330 if (size > 0) {
1316 var node; 1331 var node;
1317 for (var i = 0; i < size; i++) { 1332 for (var i = 0; i < size; i++) {
1318 node = nodes[i]; 1333 node = nodes[i];
1319 if (i > 0) { 1334 if (i > 0) {
1320 var comma = node.beginToken.previous; 1335 var comma = node.beginToken.previous;
1321 token(comma); 1336 token(comma);
1322 space(); 1337 followedBy();
1323 } 1338 }
1324 node.accept(this); 1339 node.accept(this);
1325 } 1340 }
1326 } 1341 }
1327 } 1342 }
1328 } 1343 }
1329 1344
1330 1345
1331 /// Visit a [node], and if not null, optionally preceded or followed by the 1346 /// Visit a [node], and if not null, optionally preceded or followed by the
1332 /// specified functions. 1347 /// specified functions.
(...skipping 28 matching lines...) Expand all
1361 needsNewline = true; 1376 needsNewline = true;
1362 } 1377 }
1363 1378
1364 /// Optionally emit a trailing comma. 1379 /// Optionally emit a trailing comma.
1365 optionalTrailingComma(Token rightBracket) { 1380 optionalTrailingComma(Token rightBracket) {
1366 if (rightBracket.previous.lexeme == ',') { 1381 if (rightBracket.previous.lexeme == ',') {
1367 token(rightBracket.previous); 1382 token(rightBracket.previous);
1368 } 1383 }
1369 } 1384 }
1370 1385
1386 /// Indicate that user introduced newlines should be emitted before the next
1387 /// token.
1388 preserveLeadingNewlines() {
1389 preserveNewlines = true;
1390 }
1391
1371 token(Token token, {precededBy(), followedBy(), int minNewlines: 0}) { 1392 token(Token token, {precededBy(), followedBy(), int minNewlines: 0}) {
1372 if (token != null) { 1393 if (token != null) {
1373 if (needsNewline) { 1394 if (needsNewline) {
1374 minNewlines = max(1, minNewlines); 1395 minNewlines = max(1, minNewlines);
1375 } 1396 }
1376 var emitted = emitPrecedingCommentsAndNewlines(token, min: minNewlines); 1397 var emitted = emitPrecedingCommentsAndNewlines(token, min: minNewlines);
1377 if (emitted > 0) { 1398 if (emitted > 0) {
1378 needsNewline = false; 1399 needsNewline = false;
1379 } 1400 }
1380 if (precededBy != null) { 1401 if (precededBy != null) {
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1471 var comment = token.precedingComments; 1492 var comment = token.precedingComments;
1472 var currentToken = comment != null ? comment : token; 1493 var currentToken = comment != null ? comment : token;
1473 1494
1474 //Handle EOLs before newlines 1495 //Handle EOLs before newlines
1475 if (isAtEOL(comment)) { 1496 if (isAtEOL(comment)) {
1476 emitComment(comment, previousToken); 1497 emitComment(comment, previousToken);
1477 comment = comment.next; 1498 comment = comment.next;
1478 currentToken = comment != null ? comment : token; 1499 currentToken = comment != null ? comment : token;
1479 } 1500 }
1480 1501
1481 var lines = max(min, countNewlinesBetween(previousToken, currentToken)); 1502 var lines = 0;
1503 if (needsNewline || preserveNewlines) {
1504 lines = max(min, countNewlinesBetween(previousToken, currentToken));
1505 preserveNewlines = false;
1506 }
1482 emitNewlines(lines); 1507 emitNewlines(lines);
1483 1508
1484 previousToken = 1509 previousToken =
1485 currentToken.previous != null ? currentToken.previous : token.previous; 1510 currentToken.previous != null ? currentToken.previous : token.previous;
1486 1511
1487 while (comment != null) { 1512 while (comment != null) {
1488 1513
1489 emitComment(comment, previousToken); 1514 emitComment(comment, previousToken);
1490 1515
1491 var nextToken = comment.next != null ? comment.next : token; 1516 var nextToken = comment.next != null ? comment.next : token;
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
1601 var lastLine = 1626 var lastLine =
1602 lineInfo.getLocation(lastOffset).lineNumber; 1627 lineInfo.getLocation(lastOffset).lineNumber;
1603 var currentLine = 1628 var currentLine =
1604 lineInfo.getLocation(currentOffset).lineNumber; 1629 lineInfo.getLocation(currentOffset).lineNumber;
1605 return currentLine - lastLine; 1630 return currentLine - lastLine;
1606 } 1631 }
1607 1632
1608 String toString() => writer.toString(); 1633 String toString() => writer.toString();
1609 1634
1610 } 1635 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/test/services/formatter_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698