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

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

Issue 19668003: Formatter check-point (blank-space preservation experiment). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 5 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 7
8 import 'dart:io'; 8 import 'dart:io';
9 9
10 import 'package:analyzer_experimental/analyzer.dart'; 10 import 'package:analyzer_experimental/analyzer.dart';
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 final message; 44 final message;
45 45
46 /// Creates a new FormatterException with an optional error [message]. 46 /// Creates a new FormatterException with an optional error [message].
47 const FormatterException([this.message = '']); 47 const FormatterException([this.message = '']);
48 48
49 FormatterException.forError(List<AnalysisError> errors) : 49 FormatterException.forError(List<AnalysisError> errors) :
50 // TODO(pquitslund): add descriptive message based on errors 50 // TODO(pquitslund): add descriptive message based on errors
51 message = 'an analysis error occured during format'; 51 message = 'an analysis error occured during format';
52 52
53 String toString() => 'FormatterException: $message'; 53 String toString() => 'FormatterException: $message';
54
55 } 54 }
56 55
57 /// Specifies the kind of code snippet to format. 56 /// Specifies the kind of code snippet to format.
58 class CodeKind { 57 class CodeKind {
59 58
60 final index; 59 final index;
61 60
62 const CodeKind(this.index); 61 const CodeKind(this.index);
63 62
64 /// A compilation unit snippet. 63 /// A compilation unit snippet.
(...skipping 15 matching lines...) Expand all
80 String format(CodeKind kind, String source, {int offset, int end, 79 String format(CodeKind kind, String source, {int offset, int end,
81 int indentationLevel:0}); 80 int indentationLevel:0});
82 81
83 } 82 }
84 83
85 class CodeFormatterImpl implements CodeFormatter, AnalysisErrorListener { 84 class CodeFormatterImpl implements CodeFormatter, AnalysisErrorListener {
86 85
87 final FormatterOptions options; 86 final FormatterOptions options;
88 final errors = <AnalysisError>[]; 87 final errors = <AnalysisError>[];
89 88
89 LineInfo lineInfo;
90
90 CodeFormatterImpl(this.options); 91 CodeFormatterImpl(this.options);
91 92
92 String format(CodeKind kind, String source, {int offset, int end, 93 String format(CodeKind kind, String source, {int offset, int end,
93 int indentationLevel:0}) { 94 int indentationLevel:0}) {
94 95
95 var start = tokenize(source); 96 var start = tokenize(source);
96 checkForErrors(); 97 checkForErrors();
97 98
98 var node = parse(kind, start); 99 var node = parse(kind, start);
99 checkForErrors(); 100 checkForErrors();
100 101
101 var formatter = new SourceVisitor(options); 102 var formatter = new SourceVisitor(options, lineInfo);
102 node.accept(formatter); 103 node.accept(formatter);
103 104
104 return formatter.writer.toString(); 105 return formatter.writer.toString();
105 } 106 }
106 107
107 ASTNode parse(CodeKind kind, Token start) { 108 ASTNode parse(CodeKind kind, Token start) {
108 109
109 var parser = new Parser(null, this); 110 var parser = new Parser(null, this);
110 111
111 switch (kind) { 112 switch (kind) {
(...skipping 11 matching lines...) Expand all
123 throw new FormatterException.forError(errors); 124 throw new FormatterException.forError(errors);
124 } 125 }
125 } 126 }
126 127
127 void onError(AnalysisError error) { 128 void onError(AnalysisError error) {
128 errors.add(error); 129 errors.add(error);
129 } 130 }
130 131
131 Token tokenize(String source) { 132 Token tokenize(String source) {
132 var scanner = new StringScanner(null, source, this); 133 var scanner = new StringScanner(null, source, this);
133 return scanner.tokenize(); 134 var token = scanner.tokenize();
135 lineInfo = new LineInfo(scanner.lineStarts);
136 return token;
134 } 137 }
135 138
136 } 139 }
137 140
138 141
139 142
140 /// An AST visitor that drives formatting heuristics. 143 /// An AST visitor that drives formatting heuristics.
141 class SourceVisitor implements ASTVisitor { 144 class SourceVisitor implements ASTVisitor {
142 145
143 /// The writer to which the source is to be written. 146 /// The writer to which the source is to be written.
144 SourceWriter writer; 147 SourceWriter writer;
145 148
149 LineInfo lineInfo;
150
146 /// Initialize a newly created visitor to write source code representing 151 /// Initialize a newly created visitor to write source code representing
147 /// the visited nodes to the given [writer]. 152 /// the visited nodes to the given [writer].
148 SourceVisitor(FormatterOptions options) : 153 SourceVisitor(FormatterOptions options, this.lineInfo) :
149 writer = new SourceWriter(indentCount: options.initialIndentationLevel, 154 writer = new SourceWriter(indentCount: options.initialIndentationLevel,
150 lineSeparator: options.lineSeparator); 155 lineSeparator: options.lineSeparator);
151 156
152 visitAdjacentStrings(AdjacentStrings node) { 157 visitAdjacentStrings(AdjacentStrings node) {
153 visitList(node.strings, ' '); 158 visitList(node.strings, ' ');
154 } 159 }
155 160
156 visitAnnotation(Annotation node) { 161 visitAnnotation(Annotation node) {
157 writer.print('@'); 162 writer.print('@');
158 visit(node.name); 163 visit(node.name);
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 291
287 visitCommentReference(CommentReference node) => null; 292 visitCommentReference(CommentReference node) => null;
288 293
289 visitCompilationUnit(CompilationUnit node) { 294 visitCompilationUnit(CompilationUnit node) {
290 var scriptTag = node.scriptTag; 295 var scriptTag = node.scriptTag;
291 var directives = node.directives; 296 var directives = node.directives;
292 visit(scriptTag); 297 visit(scriptTag);
293 var prefix = scriptTag == null ? '' : ' '; 298 var prefix = scriptTag == null ? '' : ' ';
294 visitPrefixedList(prefix, directives, ' '); 299 visitPrefixedList(prefix, directives, ' ');
295 prefix = scriptTag == null && directives.isEmpty ? '' : ' '; 300 prefix = scriptTag == null && directives.isEmpty ? '' : ' ';
296 visitPrefixedList(prefix, node.declarations, ' '); 301 visitPrefixedListWithBlanks(prefix, node.declarations);
302
303 //TODO(pquitslund): move this?
304 writer.newline();
297 } 305 }
298 306
299 visitConditionalExpression(ConditionalExpression node) { 307 visitConditionalExpression(ConditionalExpression node) {
300 visit(node.condition); 308 visit(node.condition);
301 writer.print(' ? '); 309 writer.print(' ? ');
302 visit(node.thenExpression); 310 visit(node.thenExpression);
303 writer.print(' : '); 311 writer.print(' : ');
304 visit(node.elseExpression); 312 visit(node.elseExpression);
305 } 313 }
306 314
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
639 } 647 }
640 visit(node.methodName); 648 visit(node.methodName);
641 visit(node.argumentList); 649 visit(node.argumentList);
642 } 650 }
643 651
644 visitNamedExpression(NamedExpression node) { 652 visitNamedExpression(NamedExpression node) {
645 visit(node.name); 653 visit(node.name);
646 visitPrefixed(' ', node.expression); 654 visitPrefixed(' ', node.expression);
647 } 655 }
648 656
657 visitNativeClause(NativeClause node) {
658 writer.print("native ");
659 visit(node.name);
660 }
661
649 visitNativeFunctionBody(NativeFunctionBody node) { 662 visitNativeFunctionBody(NativeFunctionBody node) {
650 writer.print('native '); 663 writer.print('native ');
651 visit(node.stringLiteral); 664 visit(node.stringLiteral);
652 writer.print(';'); 665 writer.print(';');
653 } 666 }
654 667
655 visitNullLiteral(NullLiteral node) { 668 visitNullLiteral(NullLiteral node) {
656 writer.print('null'); 669 writer.print('null');
657 } 670 }
658 671
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
935 for (var i = 0; i < size; i++) { 948 for (var i = 0; i < size; i++) {
936 if (i > 0) { 949 if (i > 0) {
937 writer.print(separator); 950 writer.print(separator);
938 } 951 }
939 nodes[i].accept(this); 952 nodes[i].accept(this);
940 } 953 }
941 } 954 }
942 } 955 }
943 } 956 }
944 957
958 /// Print a list of [nodes], preserving blanklines between nodes.
Brian Wilkerson 2013/07/17 21:25:09 nit: "blanklines" --> "blank lines"
pquitslund 2013/07/17 21:44:13 Fixed!
959 visitPrefixedListWithBlanks(String prefix,
960 NodeList<ASTNode> nodes) {
961 if (nodes != null) {
962 var size = nodes.length;
963 if (size > 0) {
964 writer.print(prefix);
965 for (var i = 0; i < size; i++) {
966 if (i > 0) {
967 // Emit blanks lines
968 var lastLine =
969 lineInfo.getLocation(nodes[i-1].endToken.offset).lineNumber;
970 var currentLine =
971 lineInfo.getLocation(nodes[i].beginToken.offset).lineNumber;
972 var blanks = currentLine - lastLine;
973 for (var i = 0; i < blanks; i++) {
974 writer.newline();
975 }
976 }
977 nodes[i].accept(this);
978 }
979 }
980 }
981 }
982
945 } 983 }
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