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

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

Issue 24371003: Formatter selection preservation support. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 2 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
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 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 /// Source selection state information. 86 /// Source selection state information.
87 class Selection { 87 class Selection {
88 88
89 /// The offset of the source selection. 89 /// The offset of the source selection.
90 final int offset; 90 final int offset;
91 91
92 /// The length of the selection. 92 /// The length of the selection.
93 final int length; 93 final int length;
94 94
95 Selection(this.offset, this.length); 95 Selection(this.offset, this.length);
96
97 String toString() => 'Selection (offset: $offset, length: $length)';
96 } 98 }
97 99
98 /// Formatted source. 100 /// Formatted source.
99 class FormattedSource { 101 class FormattedSource {
100 102
101 /// Selection state or null if unspecified. 103 /// Selection state or null if unspecified.
102 final Selection selection; 104 final Selection selection;
103 105
104 /// Formatted source string. 106 /// Formatted source string.
105 final String source; 107 final String source;
(...skipping 15 matching lines...) Expand all
121 123
122 FormattedSource format(CodeKind kind, String source, {int offset, int end, 124 FormattedSource format(CodeKind kind, String source, {int offset, int end,
123 int indentationLevel: 0, Selection selection: null}) { 125 int indentationLevel: 0, Selection selection: null}) {
124 126
125 var startToken = tokenize(source); 127 var startToken = tokenize(source);
126 checkForErrors(); 128 checkForErrors();
127 129
128 var node = parse(kind, startToken); 130 var node = parse(kind, startToken);
129 checkForErrors(); 131 checkForErrors();
130 132
131 var formatter = new SourceVisitor(options, lineInfo); 133 var formatter = new SourceVisitor(options, lineInfo, selection);
132 node.accept(formatter); 134 node.accept(formatter);
133 135
134 var formattedSource = formatter.writer.toString(); 136 var formattedSource = formatter.writer.toString();
135 137
136 checkTokenStreams(startToken, tokenize(formattedSource)); 138 checkTokenStreams(startToken, tokenize(formattedSource));
137 139
138 return new FormattedSource(formattedSource); 140 return new FormattedSource(formattedSource, formatter.selection);
139 } 141 }
140 142
141 checkTokenStreams(Token t1, Token t2) => 143 checkTokenStreams(Token t1, Token t2) =>
142 new TokenStreamComparator(lineInfo, t1, t2).verifyEquals(); 144 new TokenStreamComparator(lineInfo, t1, t2).verifyEquals();
143 145
144 ASTNode parse(CodeKind kind, Token start) { 146 ASTNode parse(CodeKind kind, Token start) {
145 147
146 var parser = new Parser(null, this); 148 var parser = new Parser(null, this);
147 149
148 switch (kind) { 150 switch (kind) {
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 LineInfo lineInfo; 304 LineInfo lineInfo;
303 305
304 /// Cached previous token for calculating preceding whitespace. 306 /// Cached previous token for calculating preceding whitespace.
305 Token previousToken; 307 Token previousToken;
306 308
307 /// A flag to indicate that a newline should be emitted before the next token. 309 /// A flag to indicate that a newline should be emitted before the next token.
308 bool needsNewline = false; 310 bool needsNewline = false;
309 311
310 /// Used for matching EOL comments 312 /// Used for matching EOL comments
311 final twoSlashes = new RegExp(r'//[^/]'); 313 final twoSlashes = new RegExp(r'//[^/]');
314
315 /// Original pre-format selection information (may be null).
316 final Selection preSelection;
317
318 /// Post format selection information.
319 Selection selection;
312 320
313 /// Initialize a newly created visitor to write source code representing 321 /// Initialize a newly created visitor to write source code representing
314 /// the visited nodes to the given [writer]. 322 /// the visited nodes to the given [writer].
315 SourceVisitor(FormatterOptions options, this.lineInfo) : 323 SourceVisitor(FormatterOptions options, this.lineInfo, this.preSelection) :
316 writer = new SourceWriter(indentCount: options.initialIndentationLevel, 324 writer = new SourceWriter(indentCount: options.initialIndentationLevel,
317 lineSeparator: options.lineSeparator); 325 lineSeparator: options.lineSeparator);
318 326
319 visitAdjacentStrings(AdjacentStrings node) { 327 visitAdjacentStrings(AdjacentStrings node) {
320 visitNodes(node.strings, separatedBy: space); 328 visitNodes(node.strings, separatedBy: space);
321 } 329 }
322 330
323 visitAnnotation(Annotation node) { 331 visitAnnotation(Annotation node) {
324 token(node.atSign); 332 token(node.atSign);
325 visit(node.name); 333 visit(node.name);
(...skipping 876 matching lines...) Expand 10 before | Expand all | Expand 10 after
1202 if (needsNewline) { 1210 if (needsNewline) {
1203 minNewlines = max(1, minNewlines); 1211 minNewlines = max(1, minNewlines);
1204 } 1212 }
1205 var emitted = emitPrecedingCommentsAndNewlines(token, min: minNewlines); 1213 var emitted = emitPrecedingCommentsAndNewlines(token, min: minNewlines);
1206 if (emitted > 0) { 1214 if (emitted > 0) {
1207 needsNewline = false; 1215 needsNewline = false;
1208 } 1216 }
1209 if (precededBy != null) { 1217 if (precededBy != null) {
1210 precededBy(); 1218 precededBy();
1211 } 1219 }
1220 checkForSelectionUpdate(token);
1212 append(token.lexeme); 1221 append(token.lexeme);
1213 if (followedBy != null) { 1222 if (followedBy != null) {
1214 followedBy(); 1223 followedBy();
1215 } 1224 }
1216 previousToken = token; 1225 previousToken = token;
1217 } 1226 }
1218 } 1227 }
1228
1229 checkForSelectionUpdate(Token token) {
1230 // Cache the first token on or AFTER the selection offset
1231 if (preSelection != null && selection == null) {
1232 // Check for overshots
1233 var overshot = token.offset - preSelection.offset;
1234 if (overshot >= 0) {
1235 //TODO(pquitslund): update length (may need truncating)
1236 selection = new Selection(writer.toString().length - overshot,
1237 preSelection.length);
1238 }
1239 }
1240 }
1219 1241
1220 commaSeperator() { 1242 commaSeperator() {
1221 comma(); 1243 comma();
1222 space(); 1244 space();
1223 } 1245 }
1224 1246
1225 comma() { 1247 comma() {
1226 append(','); 1248 append(',');
1227 } 1249 }
1228 1250
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
1385 var lastLine = 1407 var lastLine =
1386 lineInfo.getLocation(lastOffset).lineNumber; 1408 lineInfo.getLocation(lastOffset).lineNumber;
1387 var currentLine = 1409 var currentLine =
1388 lineInfo.getLocation(currentOffset).lineNumber; 1410 lineInfo.getLocation(currentOffset).lineNumber;
1389 return currentLine - lastLine; 1411 return currentLine - lastLine;
1390 } 1412 }
1391 1413
1392 String toString() => writer.toString(); 1414 String toString() => writer.toString();
1393 1415
1394 } 1416 }
OLDNEW
« no previous file with comments | « pkg/analyzer_experimental/bin/formatter.dart ('k') | pkg/analyzer_experimental/test/services/formatter_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698