| 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/parser.dart'; | 10 import 'package:analyzer/src/generated/parser.dart'; |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 130 checkForErrors(); | 130 checkForErrors(); |
| 131 | 131 |
| 132 var node = parse(kind, startToken); | 132 var node = parse(kind, startToken); |
| 133 checkForErrors(); | 133 checkForErrors(); |
| 134 | 134 |
| 135 var formatter = new SourceVisitor(options, lineInfo, source, selection); | 135 var formatter = new SourceVisitor(options, lineInfo, source, selection); |
| 136 node.accept(formatter); | 136 node.accept(formatter); |
| 137 | 137 |
| 138 var formattedSource = formatter.writer.toString(); | 138 var formattedSource = formatter.writer.toString(); |
| 139 | 139 |
| 140 checkTokenStreams(startToken, tokenize(formattedSource)); | 140 checkTokenStreams(startToken, tokenize(formattedSource), |
| 141 allowTransforms: options.codeTransforms); |
| 141 | 142 |
| 142 return new FormattedSource(formattedSource, formatter.selection); | 143 return new FormattedSource(formattedSource, formatter.selection); |
| 143 } | 144 } |
| 144 | 145 |
| 145 checkTokenStreams(Token t1, Token t2) => | 146 checkTokenStreams(Token t1, Token t2, {allowTransforms: false}) => |
| 146 new TokenStreamComparator(lineInfo, t1, t2).verifyEquals(); | 147 new TokenStreamComparator(lineInfo, t1, t2, transforms: allowTransforms). |
| 148 verifyEquals(); |
| 147 | 149 |
| 148 ASTNode parse(CodeKind kind, Token start) { | 150 ASTNode parse(CodeKind kind, Token start) { |
| 149 | 151 |
| 150 var parser = new Parser(null, this); | 152 var parser = new Parser(null, this); |
| 151 | 153 |
| 152 switch (kind) { | 154 switch (kind) { |
| 153 case CodeKind.COMPILATION_UNIT: | 155 case CodeKind.COMPILATION_UNIT: |
| 154 return parser.parseCompilationUnit(start); | 156 return parser.parseCompilationUnit(start); |
| 155 case CodeKind.STATEMENT: | 157 case CodeKind.STATEMENT: |
| 156 return parser.parseStatement(start); | 158 return parser.parseStatement(start); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 178 } | 180 } |
| 179 | 181 |
| 180 } | 182 } |
| 181 | 183 |
| 182 | 184 |
| 183 // Compares two token streams. Used for sanity checking formatted results. | 185 // Compares two token streams. Used for sanity checking formatted results. |
| 184 class TokenStreamComparator { | 186 class TokenStreamComparator { |
| 185 | 187 |
| 186 final LineInfo lineInfo; | 188 final LineInfo lineInfo; |
| 187 Token token1, token2; | 189 Token token1, token2; |
| 190 bool allowTransforms; |
| 188 | 191 |
| 189 TokenStreamComparator(this.lineInfo, this.token1, this.token2); | 192 TokenStreamComparator(this.lineInfo, this.token1, this.token2, |
| 193 {transforms: false}) : this.allowTransforms = transforms; |
| 190 | 194 |
| 191 /// Verify that these two token streams are equal. | 195 /// Verify that these two token streams are equal. |
| 192 verifyEquals() { | 196 verifyEquals() { |
| 193 while (!isEOF(token1)) { | 197 while (!isEOF(token1)) { |
| 194 checkPrecedingComments(); | 198 checkPrecedingComments(); |
| 195 if (!checkTokens()) { | 199 if (!checkTokens()) { |
| 196 throwNotEqualException(token1, token2); | 200 throwNotEqualException(token1, token2); |
| 197 } | 201 } |
| 198 advance(); | 202 advance(); |
| 199 | 203 |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 267 } | 271 } |
| 268 } | 272 } |
| 269 // Cons(){} => Cons(); | 273 // Cons(){} => Cons(); |
| 270 if (isOPEN_CURLY_BRACKET(token1) && isCLOSE_CURLY_BRACKET(token1.next)) { | 274 if (isOPEN_CURLY_BRACKET(token1) && isCLOSE_CURLY_BRACKET(token1.next)) { |
| 271 if (isSEMICOLON(token2)) { | 275 if (isSEMICOLON(token2)) { |
| 272 token1 = token1.next; | 276 token1 = token1.next; |
| 273 advance(); | 277 advance(); |
| 274 return true; | 278 return true; |
| 275 } | 279 } |
| 276 } | 280 } |
| 277 // Advance past synthetic { } tokens | 281 |
| 278 if (isOPEN_CURLY_BRACKET(token2) || isCLOSE_CURLY_BRACKET(token2)) { | 282 // Transform-related special casing |
| 279 token2 = token2.next; | 283 if (allowTransforms) { |
| 280 return checkTokens(); | 284 |
| 285 // Advance past empty statements |
| 286 if (isSEMICOLON(token1)) { |
| 287 // TODO whitelist |
| 288 token1 = token1.next; |
| 289 return checkTokens(); |
| 290 } |
| 291 |
| 292 // Advance past synthetic { } tokens |
| 293 if (isOPEN_CURLY_BRACKET(token2) || isCLOSE_CURLY_BRACKET(token2)) { |
| 294 token2 = token2.next; |
| 295 return checkTokens(); |
| 296 } |
| 297 |
| 281 } | 298 } |
| 282 | 299 |
| 283 return false; | 300 return false; |
| 284 } | 301 } |
| 285 | 302 |
| 286 } | 303 } |
| 287 | 304 |
| 288 // Cached parser for testing token types. | 305 // Cached parser for testing token types. |
| 289 final tokenTester = new Parser(null,null); | 306 final tokenTester = new Parser(null,null); |
| 290 | 307 |
| (...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 715 | 732 |
| 716 visitDoubleLiteral(DoubleLiteral node) { | 733 visitDoubleLiteral(DoubleLiteral node) { |
| 717 token(node.literal); | 734 token(node.literal); |
| 718 } | 735 } |
| 719 | 736 |
| 720 visitEmptyFunctionBody(EmptyFunctionBody node) { | 737 visitEmptyFunctionBody(EmptyFunctionBody node) { |
| 721 token(node.semicolon); | 738 token(node.semicolon); |
| 722 } | 739 } |
| 723 | 740 |
| 724 visitEmptyStatement(EmptyStatement node) { | 741 visitEmptyStatement(EmptyStatement node) { |
| 725 token(node.semicolon); | 742 if (!codeTransforms || node.parent is! Block) { |
| 743 token(node.semicolon); |
| 744 } |
| 726 } | 745 } |
| 727 | 746 |
| 728 visitExportDirective(ExportDirective node) { | 747 visitExportDirective(ExportDirective node) { |
| 729 visitNodes(node.metadata, followedBy: newlines); | 748 visitNodes(node.metadata, followedBy: newlines); |
| 730 token(node.keyword); | 749 token(node.keyword); |
| 731 space(); | 750 space(); |
| 732 visit(node.uri); | 751 visit(node.uri); |
| 733 allowContinuedLines((){ | 752 allowContinuedLines((){ |
| 734 visitNodes(node.combinators, precededBy: space, separatedBy: space); | 753 visitNodes(node.combinators, precededBy: space, separatedBy: space); |
| 735 }); | 754 }); |
| (...skipping 997 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1733 var lastLine = | 1752 var lastLine = |
| 1734 lineInfo.getLocation(lastOffset).lineNumber; | 1753 lineInfo.getLocation(lastOffset).lineNumber; |
| 1735 var currentLine = | 1754 var currentLine = |
| 1736 lineInfo.getLocation(currentOffset).lineNumber; | 1755 lineInfo.getLocation(currentOffset).lineNumber; |
| 1737 return currentLine - lastLine; | 1756 return currentLine - lastLine; |
| 1738 } | 1757 } |
| 1739 | 1758 |
| 1740 String toString() => writer.toString(); | 1759 String toString() => writer.toString(); |
| 1741 | 1760 |
| 1742 } | 1761 } |
| OLD | NEW |