| OLD | NEW |
| 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 404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 415 token(node.leftParenthesis); | 415 token(node.leftParenthesis); |
| 416 visit(node.condition); | 416 visit(node.condition); |
| 417 token(node.rightParenthesis); | 417 token(node.rightParenthesis); |
| 418 token(node.semicolon); | 418 token(node.semicolon); |
| 419 } | 419 } |
| 420 | 420 |
| 421 visitAssignmentExpression(AssignmentExpression node) { | 421 visitAssignmentExpression(AssignmentExpression node) { |
| 422 visit(node.leftHandSide); | 422 visit(node.leftHandSide); |
| 423 space(); | 423 space(); |
| 424 token(node.operator); | 424 token(node.operator); |
| 425 space(); | 425 allowContinuedLines((){ |
| 426 visit(node.rightHandSide); | 426 space(); |
| 427 visit(node.rightHandSide); |
| 428 }); |
| 427 } | 429 } |
| 428 | 430 |
| 429 visitBinaryExpression(BinaryExpression node) { | 431 visitBinaryExpression(BinaryExpression node) { |
| 430 visit(node.leftOperand); | 432 visit(node.leftOperand); |
| 431 space(); | 433 space(); |
| 432 token(node.operator); | 434 token(node.operator); |
| 433 space(); | 435 space(); |
| 434 visit(node.rightOperand); | 436 visit(node.rightOperand); |
| 435 } | 437 } |
| 436 | 438 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 485 space(); | 487 space(); |
| 486 } | 488 } |
| 487 visit(node.body); | 489 visit(node.body); |
| 488 } | 490 } |
| 489 | 491 |
| 490 visitClassDeclaration(ClassDeclaration node) { | 492 visitClassDeclaration(ClassDeclaration node) { |
| 491 modifier(node.abstractKeyword); | 493 modifier(node.abstractKeyword); |
| 492 token(node.classKeyword); | 494 token(node.classKeyword); |
| 493 space(); | 495 space(); |
| 494 visit(node.name); | 496 visit(node.name); |
| 495 visit(node.typeParameters); | 497 allowContinuedLines((){ |
| 496 visitNode(node.extendsClause, precededBy: space); | 498 visit(node.typeParameters); |
| 497 visitNode(node.withClause, precededBy: space); | 499 visitNode(node.extendsClause, precededBy: space); |
| 498 visitNode(node.implementsClause, precededBy: space); | 500 visitNode(node.withClause, precededBy: space); |
| 499 space(); | 501 visitNode(node.implementsClause, precededBy: space); |
| 502 space(); |
| 503 }); |
| 500 token(node.leftBracket); | 504 token(node.leftBracket); |
| 501 indent(); | 505 indent(); |
| 502 visitNodes(node.members, precededBy: newlines, separatedBy: newlines); | 506 visitNodes(node.members, precededBy: newlines, separatedBy: newlines); |
| 503 unindent(); | 507 unindent(); |
| 504 newlines(); | 508 newlines(); |
| 505 token(node.rightBracket); | 509 token(node.rightBracket); |
| 506 } | 510 } |
| 507 | 511 |
| 508 visitClassTypeAlias(ClassTypeAlias node) { | 512 visitClassTypeAlias(ClassTypeAlias node) { |
| 509 token(node.keyword); | 513 token(node.keyword); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 547 token(node.endToken /* EOF */); | 551 token(node.endToken /* EOF */); |
| 548 | 552 |
| 549 // Be a good citizen, end with a NL | 553 // Be a good citizen, end with a NL |
| 550 ensureTrailingNewline(); | 554 ensureTrailingNewline(); |
| 551 } | 555 } |
| 552 | 556 |
| 553 visitConditionalExpression(ConditionalExpression node) { | 557 visitConditionalExpression(ConditionalExpression node) { |
| 554 visit(node.condition); | 558 visit(node.condition); |
| 555 space(); | 559 space(); |
| 556 token(node.question); | 560 token(node.question); |
| 557 space(); | 561 allowContinuedLines((){ |
| 558 visit(node.thenExpression); | 562 space(); |
| 559 space(); | 563 visit(node.thenExpression); |
| 560 token(node.colon); | 564 space(); |
| 561 space(); | 565 token(node.colon); |
| 562 visit(node.elseExpression); | 566 space(); |
| 567 visit(node.elseExpression); |
| 568 }); |
| 563 } | 569 } |
| 564 | 570 |
| 565 visitConstructorDeclaration(ConstructorDeclaration node) { | 571 visitConstructorDeclaration(ConstructorDeclaration node) { |
| 566 modifier(node.externalKeyword); | 572 modifier(node.externalKeyword); |
| 567 modifier(node.constKeyword); | 573 modifier(node.constKeyword); |
| 568 modifier(node.factoryKeyword); | 574 modifier(node.factoryKeyword); |
| 569 visit(node.returnType); | 575 visit(node.returnType); |
| 570 token(node.period); | 576 token(node.period); |
| 571 visit(node.name); | 577 visit(node.name); |
| 572 visit(node.parameters); | 578 visit(node.parameters); |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 656 } | 662 } |
| 657 | 663 |
| 658 visitDoStatement(DoStatement node) { | 664 visitDoStatement(DoStatement node) { |
| 659 token(node.doKeyword); | 665 token(node.doKeyword); |
| 660 space(); | 666 space(); |
| 661 visit(node.body); | 667 visit(node.body); |
| 662 space(); | 668 space(); |
| 663 token(node.whileKeyword); | 669 token(node.whileKeyword); |
| 664 space(); | 670 space(); |
| 665 token(node.leftParenthesis); | 671 token(node.leftParenthesis); |
| 666 visit(node.condition); | 672 allowContinuedLines((){ |
| 667 token(node.rightParenthesis); | 673 visit(node.condition); |
| 674 token(node.rightParenthesis); |
| 675 }); |
| 668 token(node.semicolon); | 676 token(node.semicolon); |
| 669 } | 677 } |
| 670 | 678 |
| 671 visitDoubleLiteral(DoubleLiteral node) { | 679 visitDoubleLiteral(DoubleLiteral node) { |
| 672 token(node.literal); | 680 token(node.literal); |
| 673 } | 681 } |
| 674 | 682 |
| 675 visitEmptyFunctionBody(EmptyFunctionBody node) { | 683 visitEmptyFunctionBody(EmptyFunctionBody node) { |
| 676 token(node.semicolon); | 684 token(node.semicolon); |
| 677 } | 685 } |
| 678 | 686 |
| 679 visitEmptyStatement(EmptyStatement node) { | 687 visitEmptyStatement(EmptyStatement node) { |
| 680 token(node.semicolon); | 688 token(node.semicolon); |
| 681 } | 689 } |
| 682 | 690 |
| 683 visitExportDirective(ExportDirective node) { | 691 visitExportDirective(ExportDirective node) { |
| 684 token(node.keyword); | 692 token(node.keyword); |
| 685 space(); | 693 space(); |
| 686 visit(node.uri); | 694 visit(node.uri); |
| 687 visitNodes(node.combinators, precededBy: space, separatedBy: space); | 695 allowContinuedLines((){ |
| 696 visitNodes(node.combinators, precededBy: space, separatedBy: space); |
| 697 }); |
| 688 token(node.semicolon); | 698 token(node.semicolon); |
| 689 } | 699 } |
| 690 | 700 |
| 691 visitExpressionFunctionBody(ExpressionFunctionBody node) { | 701 visitExpressionFunctionBody(ExpressionFunctionBody node) { |
| 692 token(node.functionDefinition); | 702 token(node.functionDefinition); |
| 693 space(); | 703 space(); |
| 694 visit(node.expression); | 704 visit(node.expression); |
| 695 token(node.semicolon); | 705 token(node.semicolon); |
| 696 } | 706 } |
| 697 | 707 |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 830 | 840 |
| 831 visitHideCombinator(HideCombinator node) { | 841 visitHideCombinator(HideCombinator node) { |
| 832 token(node.keyword); | 842 token(node.keyword); |
| 833 space(); | 843 space(); |
| 834 visitCommaSeparatedNodes(node.hiddenNames); | 844 visitCommaSeparatedNodes(node.hiddenNames); |
| 835 } | 845 } |
| 836 | 846 |
| 837 visitIfStatement(IfStatement node) { | 847 visitIfStatement(IfStatement node) { |
| 838 var hasElse = node.elseStatement != null; | 848 var hasElse = node.elseStatement != null; |
| 839 token(node.ifKeyword); | 849 token(node.ifKeyword); |
| 840 space(); | 850 allowContinuedLines((){ |
| 841 token(node.leftParenthesis); | 851 space(); |
| 842 visit(node.condition); | 852 token(node.leftParenthesis); |
| 843 token(node.rightParenthesis); | 853 visit(node.condition); |
| 854 token(node.rightParenthesis); |
| 855 }); |
| 844 space(); | 856 space(); |
| 845 if (hasElse) { | 857 if (hasElse) { |
| 846 printAsBlock(node.thenStatement); | 858 printAsBlock(node.thenStatement); |
| 847 space(); | 859 space(); |
| 848 token(node.elseKeyword); | 860 token(node.elseKeyword); |
| 849 space(); | 861 space(); |
| 850 printAsBlock(node.elseStatement); | 862 printAsBlock(node.elseStatement); |
| 851 } else { | 863 } else { |
| 852 visit(node.thenStatement); | 864 visit(node.thenStatement); |
| 853 } | 865 } |
| 854 } | 866 } |
| 855 | 867 |
| 856 visitImplementsClause(ImplementsClause node) { | 868 visitImplementsClause(ImplementsClause node) { |
| 857 token(node.keyword); | 869 token(node.keyword); |
| 858 space(); | 870 space(); |
| 859 visitCommaSeparatedNodes(node.interfaces); | 871 visitCommaSeparatedNodes(node.interfaces); |
| 860 } | 872 } |
| 861 | 873 |
| 862 visitImportDirective(ImportDirective node) { | 874 visitImportDirective(ImportDirective node) { |
| 863 token(node.keyword); | 875 token(node.keyword); |
| 864 space(); | 876 space(); |
| 865 visit(node.uri); | 877 visit(node.uri); |
| 866 token(node.asToken, precededBy: space, followedBy: space); | 878 token(node.asToken, precededBy: space, followedBy: space); |
| 867 visit(node.prefix); | 879 allowContinuedLines((){ |
| 868 visitNodes(node.combinators, precededBy: space, separatedBy: space); | 880 visit(node.prefix); |
| 881 visitNodes(node.combinators, precededBy: space, separatedBy: space); |
| 882 }); |
| 869 token(node.semicolon); | 883 token(node.semicolon); |
| 870 } | 884 } |
| 871 | 885 |
| 872 visitIndexExpression(IndexExpression node) { | 886 visitIndexExpression(IndexExpression node) { |
| 873 if (node.isCascaded) { | 887 if (node.isCascaded) { |
| 874 token(node.period); | 888 token(node.period); |
| 875 } else { | 889 } else { |
| 876 visit(node.target); | 890 visit(node.target); |
| 877 } | 891 } |
| 878 token(node.leftBracket); | 892 token(node.leftBracket); |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1066 token(node.keyword); | 1080 token(node.keyword); |
| 1067 } | 1081 } |
| 1068 | 1082 |
| 1069 visitReturnStatement(ReturnStatement node) { | 1083 visitReturnStatement(ReturnStatement node) { |
| 1070 var expression = node.expression; | 1084 var expression = node.expression; |
| 1071 if (expression == null) { | 1085 if (expression == null) { |
| 1072 token(node.keyword); | 1086 token(node.keyword); |
| 1073 token(node.semicolon); | 1087 token(node.semicolon); |
| 1074 } else { | 1088 } else { |
| 1075 token(node.keyword); | 1089 token(node.keyword); |
| 1076 space(); | 1090 allowContinuedLines((){ |
| 1077 expression.accept(this); | 1091 space(); |
| 1078 token(node.semicolon); | 1092 expression.accept(this); |
| 1093 token(node.semicolon); |
| 1094 }); |
| 1079 } | 1095 } |
| 1080 } | 1096 } |
| 1081 | 1097 |
| 1082 visitScriptTag(ScriptTag node) { | 1098 visitScriptTag(ScriptTag node) { |
| 1083 token(node.scriptTag); | 1099 token(node.scriptTag); |
| 1084 } | 1100 } |
| 1085 | 1101 |
| 1086 visitShowCombinator(ShowCombinator node) { | 1102 visitShowCombinator(ShowCombinator node) { |
| 1087 token(node.keyword); | 1103 token(node.keyword); |
| 1088 space(); | 1104 space(); |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1202 token(node.leftBracket); | 1218 token(node.leftBracket); |
| 1203 visitCommaSeparatedNodes(node.typeParameters); | 1219 visitCommaSeparatedNodes(node.typeParameters); |
| 1204 token(node.rightBracket); | 1220 token(node.rightBracket); |
| 1205 } | 1221 } |
| 1206 | 1222 |
| 1207 visitVariableDeclaration(VariableDeclaration node) { | 1223 visitVariableDeclaration(VariableDeclaration node) { |
| 1208 visit(node.name); | 1224 visit(node.name); |
| 1209 if (node.initializer != null) { | 1225 if (node.initializer != null) { |
| 1210 space(); | 1226 space(); |
| 1211 token(node.equals); | 1227 token(node.equals); |
| 1212 space(); | 1228 var initializer = node.initializer; |
| 1213 visit(node.initializer); | 1229 if (initializer is! ListLiteral && initializer is! MapLiteral) { |
| 1230 allowContinuedLines((){ |
| 1231 space(); |
| 1232 visit(initializer); |
| 1233 }); |
| 1234 } else { |
| 1235 space(); |
| 1236 visit(initializer); |
| 1237 } |
| 1214 } | 1238 } |
| 1215 } | 1239 } |
| 1216 | 1240 |
| 1217 visitVariableDeclarationList(VariableDeclarationList node) { | 1241 visitVariableDeclarationList(VariableDeclarationList node) { |
| 1218 modifier(node.keyword); | 1242 modifier(node.keyword); |
| 1219 visitNode(node.type, followedBy: space); | 1243 visitNode(node.type, followedBy: space); |
| 1220 visitCommaSeparatedNodes(node.variables); | 1244 visitCommaSeparatedNodes(node.variables); |
| 1221 } | 1245 } |
| 1222 | 1246 |
| 1223 visitVariableDeclarationStatement(VariableDeclarationStatement node) { | 1247 visitVariableDeclarationStatement(VariableDeclarationStatement node) { |
| 1224 visit(node.variables); | 1248 visit(node.variables); |
| 1225 token(node.semicolon); | 1249 token(node.semicolon); |
| 1226 } | 1250 } |
| 1227 | 1251 |
| 1228 visitWhileStatement(WhileStatement node) { | 1252 visitWhileStatement(WhileStatement node) { |
| 1229 token(node.keyword); | 1253 token(node.keyword); |
| 1230 space(); | 1254 space(); |
| 1231 token(node.leftParenthesis); | 1255 token(node.leftParenthesis); |
| 1232 visit(node.condition); | 1256 allowContinuedLines((){ |
| 1233 token(node.rightParenthesis); | 1257 visit(node.condition); |
| 1258 token(node.rightParenthesis); |
| 1259 }); |
| 1234 if (node.body is! EmptyStatement) { | 1260 if (node.body is! EmptyStatement) { |
| 1235 space(); | 1261 space(); |
| 1236 } | 1262 } |
| 1237 visit(node.body); | 1263 visit(node.body); |
| 1238 } | 1264 } |
| 1239 | 1265 |
| 1240 visitWithClause(WithClause node) { | 1266 visitWithClause(WithClause node) { |
| 1241 token(node.withKeyword); | 1267 token(node.withKeyword); |
| 1242 space(); | 1268 space(); |
| 1243 visitCommaSeparatedNodes(node.mixinTypes); | 1269 visitCommaSeparatedNodes(node.mixinTypes); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1309 if (precededBy != null) { | 1335 if (precededBy != null) { |
| 1310 precededBy(); | 1336 precededBy(); |
| 1311 } | 1337 } |
| 1312 node.accept(this); | 1338 node.accept(this); |
| 1313 if (followedBy != null) { | 1339 if (followedBy != null) { |
| 1314 followedBy(); | 1340 followedBy(); |
| 1315 } | 1341 } |
| 1316 } | 1342 } |
| 1317 } | 1343 } |
| 1318 | 1344 |
| 1345 /// Allow [code] to be continued across lines. |
| 1346 allowContinuedLines(code()) { |
| 1347 //TODO(pquitslund): add before |
| 1348 code(); |
| 1349 //TODO(pquitslund): add after |
| 1350 } |
| 1319 | 1351 |
| 1320 /// Emit the given [modifier] if it's non null, followed by non-breaking | 1352 /// Emit the given [modifier] if it's non null, followed by non-breaking |
| 1321 /// whitespace. | 1353 /// whitespace. |
| 1322 modifier(Token modifier) { | 1354 modifier(Token modifier) { |
| 1323 token(modifier, followedBy: space); | 1355 token(modifier, followedBy: space); |
| 1324 } | 1356 } |
| 1325 | 1357 |
| 1326 /// Indicate that at least one newline should be emitted and possibly more | 1358 /// Indicate that at least one newline should be emitted and possibly more |
| 1327 /// if the source has them. | 1359 /// if the source has them. |
| 1328 newlines() { | 1360 newlines() { |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1440 var currentToken = comment != null ? comment : token; | 1472 var currentToken = comment != null ? comment : token; |
| 1441 | 1473 |
| 1442 //Handle EOLs before newlines | 1474 //Handle EOLs before newlines |
| 1443 if (isAtEOL(comment)) { | 1475 if (isAtEOL(comment)) { |
| 1444 emitComment(comment, previousToken); | 1476 emitComment(comment, previousToken); |
| 1445 comment = comment.next; | 1477 comment = comment.next; |
| 1446 currentToken = comment != null ? comment : token; | 1478 currentToken = comment != null ? comment : token; |
| 1447 } | 1479 } |
| 1448 | 1480 |
| 1449 var lines = max(min, countNewlinesBetween(previousToken, currentToken)); | 1481 var lines = max(min, countNewlinesBetween(previousToken, currentToken)); |
| 1450 writer.newlines(lines); | 1482 emitNewlines(lines); |
| 1451 | 1483 |
| 1452 previousToken = | 1484 previousToken = |
| 1453 currentToken.previous != null ? currentToken.previous : token.previous; | 1485 currentToken.previous != null ? currentToken.previous : token.previous; |
| 1454 | 1486 |
| 1455 while (comment != null) { | 1487 while (comment != null) { |
| 1456 | 1488 |
| 1457 emitComment(comment, previousToken); | 1489 emitComment(comment, previousToken); |
| 1458 | 1490 |
| 1459 var nextToken = comment.next != null ? comment.next : token; | 1491 var nextToken = comment.next != null ? comment.next : token; |
| 1460 var newlines = calculateNewlinesBetweenComments(comment, nextToken); | 1492 var newlines = calculateNewlinesBetweenComments(comment, nextToken); |
| 1461 if (newlines > 0) { | 1493 if (newlines > 0) { |
| 1462 writer.newlines(newlines); | 1494 emitNewlines(newlines); |
| 1463 lines += newlines; | 1495 lines += newlines; |
| 1464 } else { | 1496 } else { |
| 1465 var spaces = countSpacesBetween(comment, nextToken); | 1497 var spaces = countSpacesBetween(comment, nextToken); |
| 1466 if (spaces > 0) { | 1498 if (spaces > 0) { |
| 1467 space(); | 1499 space(); |
| 1468 } | 1500 } |
| 1469 } | 1501 } |
| 1470 | 1502 |
| 1471 previousToken = comment; | 1503 previousToken = comment; |
| 1472 comment = comment.next; | 1504 comment = comment.next; |
| 1473 } | 1505 } |
| 1474 | 1506 |
| 1475 previousToken = token; | 1507 previousToken = token; |
| 1476 return lines; | 1508 return lines; |
| 1477 } | 1509 } |
| 1478 | 1510 |
| 1511 void emitNewlines(lines) { |
| 1512 writer.newlines(lines); |
| 1513 } |
| 1514 |
| 1479 ensureTrailingNewline() { | 1515 ensureTrailingNewline() { |
| 1480 if (writer.lastToken is! NewlineToken) { | 1516 if (writer.lastToken is! NewlineToken) { |
| 1481 writer.newline(); | 1517 writer.newline(); |
| 1482 } | 1518 } |
| 1483 } | 1519 } |
| 1484 | 1520 |
| 1485 | 1521 |
| 1486 /// Test if this [comment] is at the end of a line. | 1522 /// Test if this [comment] is at the end of a line. |
| 1487 bool isAtEOL(Token comment) => | 1523 bool isAtEOL(Token comment) => |
| 1488 comment != null && comment.toString().trim().startsWith(twoSlashes) && | 1524 comment != null && comment.toString().trim().startsWith(twoSlashes) && |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1565 var lastLine = | 1601 var lastLine = |
| 1566 lineInfo.getLocation(lastOffset).lineNumber; | 1602 lineInfo.getLocation(lastOffset).lineNumber; |
| 1567 var currentLine = | 1603 var currentLine = |
| 1568 lineInfo.getLocation(currentOffset).lineNumber; | 1604 lineInfo.getLocation(currentOffset).lineNumber; |
| 1569 return currentLine - lastLine; | 1605 return currentLine - lastLine; |
| 1570 } | 1606 } |
| 1571 | 1607 |
| 1572 String toString() => writer.toString(); | 1608 String toString() => writer.toString(); |
| 1573 | 1609 |
| 1574 } | 1610 } |
| OLD | NEW |