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

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

Issue 25609002: Formatting constructor initializers a la the Style Guide. (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
« 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 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 316 matching lines...) Expand 10 before | Expand all | Expand 10 after
327 final SourceWriter writer; 327 final SourceWriter writer;
328 328
329 /// Cached line info for calculating blank lines. 329 /// Cached line info for calculating blank lines.
330 LineInfo lineInfo; 330 LineInfo lineInfo;
331 331
332 /// Cached previous token for calculating preceding whitespace. 332 /// Cached previous token for calculating preceding whitespace.
333 Token previousToken; 333 Token previousToken;
334 334
335 /// A flag to indicate that a newline should be emitted before the next token. 335 /// A flag to indicate that a newline should be emitted before the next token.
336 bool needsNewline = false; 336 bool needsNewline = false;
337
338 /// A counter for spaces that should be emitted preceding the next token.
339 int leadingSpaces = 0;
337 340
338 /// Used for matching EOL comments 341 /// Used for matching EOL comments
339 final twoSlashes = new RegExp(r'//[^/]'); 342 final twoSlashes = new RegExp(r'//[^/]');
340 343
341 /// Original pre-format selection information (may be null). 344 /// Original pre-format selection information (may be null).
342 final Selection preSelection; 345 final Selection preSelection;
343 346
344 /// Post format selection information. 347 /// Post format selection information.
345 Selection selection; 348 Selection selection;
346 349
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
533 } 536 }
534 537
535 visitConstructorDeclaration(ConstructorDeclaration node) { 538 visitConstructorDeclaration(ConstructorDeclaration node) {
536 modifier(node.externalKeyword); 539 modifier(node.externalKeyword);
537 modifier(node.constKeyword); 540 modifier(node.constKeyword);
538 modifier(node.factoryKeyword); 541 modifier(node.factoryKeyword);
539 visit(node.returnType); 542 visit(node.returnType);
540 token(node.period); 543 token(node.period);
541 visit(node.name); 544 visit(node.name);
542 visit(node.parameters); 545 visit(node.parameters);
543 token(node.separator /* = or : */, precededBy: space, followedBy: space); 546
544 visitNodes(node.initializers, separatedBy: commaSeperator); 547 // Check for redirects or initializer lists
545 visit(node.redirectedConstructor); 548 if (node.separator != null) {
549 if (node.redirectedConstructor != null) {
550 visitConstructorRedirects(node);
551 } else {
552 visitConstructorInitializers(node);
553 }
554 }
546 555
547 visitPrefixedBody(space, node.body); 556 visitPrefixedBody(space, node.body);
548 } 557 }
549 558
559 visitConstructorInitializers(ConstructorDeclaration node) {
560 newlines();
561 indent(2);
562 token(node.separator /* : */);
563 space();
564 for (var i = 0; i < node.initializers.length; i++) {
565 if (i > 0) {
566 comma();
567 newlines();
568 space(2);
569 }
570 node.initializers[i].accept(this);
571 }
572 unindent(2);
573 }
574
575 visitConstructorRedirects(ConstructorDeclaration node) {
576 token(node.separator /* = */, precededBy: space, followedBy: space);
577 visitNodes(node.initializers, separatedBy: commaSeperator);
578 visit(node.redirectedConstructor);
579 }
580
550 visitConstructorFieldInitializer(ConstructorFieldInitializer node) { 581 visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
551 token(node.keyword); 582 token(node.keyword);
552 token(node.period); 583 token(node.period);
553 visit(node.fieldName); 584 visit(node.fieldName);
554 space(); 585 space();
555 token(node.equals); 586 token(node.equals);
556 space(); 587 space();
557 visit(node.expression); 588 visit(node.expression);
558 } 589 }
559 590
(...skipping 687 matching lines...) Expand 10 before | Expand all | Expand 10 after
1247 } 1278 }
1248 checkForSelectionUpdate(token); 1279 checkForSelectionUpdate(token);
1249 append(token.lexeme); 1280 append(token.lexeme);
1250 if (followedBy != null) { 1281 if (followedBy != null) {
1251 followedBy(); 1282 followedBy();
1252 } 1283 }
1253 previousToken = token; 1284 previousToken = token;
1254 } 1285 }
1255 } 1286 }
1256 1287
1288 emitSpaces() {
1289 while (leadingSpaces > 0) {
1290 writer.print(' ');
1291 leadingSpaces--;
1292 }
1293 }
1294
1257 checkForSelectionUpdate(Token token) { 1295 checkForSelectionUpdate(Token token) {
1258 // Cache the first token on or AFTER the selection offset 1296 // Cache the first token on or AFTER the selection offset
1259 if (preSelection != null && selection == null) { 1297 if (preSelection != null && selection == null) {
1260 // Check for overshots 1298 // Check for overshots
1261 var overshot = token.offset - preSelection.offset; 1299 var overshot = token.offset - preSelection.offset;
1262 if (overshot >= 0) { 1300 if (overshot >= 0) {
1263 //TODO(pquitslund): update length (may need truncating) 1301 //TODO(pquitslund): update length (may need truncating)
1264 selection = new Selection(writer.toString().length - overshot, 1302 selection = new Selection(
1303 writer.toString().length + leadingSpaces - overshot,
1265 preSelection.length); 1304 preSelection.length);
1266 } 1305 }
1267 } 1306 }
1268 } 1307 }
1269 1308
1270 commaSeperator() { 1309 commaSeperator() {
1271 comma(); 1310 comma();
1272 space(); 1311 space();
1273 } 1312 }
1274 1313
1275 comma() { 1314 comma() {
1276 append(','); 1315 writer.print(',');
1277 } 1316 }
1278 1317
1318
1279 /// Emit a non-breakable space. 1319 /// Emit a non-breakable space.
1280 space() { 1320 space([n = 1]) {
1281 //TODO(pquitslund): replace with a proper space token 1321 //TODO(pquitslund): replace with a proper space token
1282 append(' '); 1322 leadingSpaces+=n;
1283 } 1323 }
1284 1324
1285 /// Emit a breakable space 1325 /// Emit a breakable space
1286 breakableSpace() { 1326 breakableSpace() {
1287 //Implement 1327 //Implement
1288 } 1328 }
1289 1329
1290 /// Append the given [string] to the source writer if it's non-null. 1330 /// Append the given [string] to the source writer if it's non-null.
1291 append(String string) { 1331 append(String string) {
1292 if (string != null && !string.isEmpty) { 1332 if (string != null && !string.isEmpty) {
1333 emitSpaces();
1293 writer.print(string); 1334 writer.print(string);
1294 } 1335 }
1295 } 1336 }
1296 1337
1297 /// Indent. 1338 /// Indent.
1298 indent() { 1339 indent([n = 1]) {
1299 writer.indent(); 1340 while (n-- > 0) {
1341 writer.indent();
1342 }
1300 } 1343 }
1301 1344
1302 /// Unindent 1345 /// Unindent
1303 unindent() { 1346 unindent([n = 1]) {
1304 writer.unindent(); 1347 while (n-- > 0) {
1348 writer.unindent();
1349 }
1305 } 1350 }
1306 1351
1307 /// Print this statement as if it were a block (e.g., surrounded by braces). 1352 /// Print this statement as if it were a block (e.g., surrounded by braces).
1308 printAsBlock(Statement statement) { 1353 printAsBlock(Statement statement) {
1309 if (statement is! Block) { 1354 if (statement is! Block) {
1310 token(OPEN_CURLY); 1355 token(OPEN_CURLY);
1311 indent(); 1356 indent();
1312 newlines(); 1357 newlines();
1313 visit(statement); 1358 visit(statement);
1314 newlines(); 1359 newlines();
(...skipping 26 matching lines...) Expand all
1341 while (comment != null) { 1386 while (comment != null) {
1342 1387
1343 emitComment(comment, previousToken); 1388 emitComment(comment, previousToken);
1344 1389
1345 var nextToken = comment.next != null ? comment.next : token; 1390 var nextToken = comment.next != null ? comment.next : token;
1346 var newlines = calculateNewlinesBetweenComments(comment, nextToken); 1391 var newlines = calculateNewlinesBetweenComments(comment, nextToken);
1347 if (newlines > 0) { 1392 if (newlines > 0) {
1348 writer.newlines(newlines); 1393 writer.newlines(newlines);
1349 lines += newlines; 1394 lines += newlines;
1350 } else if (!isEOF(token)) { 1395 } else if (!isEOF(token)) {
1351 space(); 1396 append(' ');
1352 } 1397 }
1353 1398
1354 previousToken = comment; 1399 previousToken = comment;
1355 comment = comment.next; 1400 comment = comment.next;
1356 } 1401 }
1357 1402
1358 previousToken = token; 1403 previousToken = token;
1359 return lines; 1404 return lines;
1360 } 1405 }
1361 1406
1362 1407
1363 ensureTrailingNewline() { 1408 ensureTrailingNewline() {
1364 if (writer.lastToken is! NewlineToken) { 1409 if (writer.lastToken is! NewlineToken) {
1365 writer.newline(); 1410 writer.newline();
1366 } 1411 }
1367 } 1412 }
1368 1413
1369 1414
1370 /// Test if this [comment] is at the end of a line. 1415 /// Test if this [comment] is at the end of a line.
1371 bool isAtEOL(Token comment) => 1416 bool isAtEOL(Token comment) =>
1372 comment != null && comment.toString().trim().startsWith(twoSlashes) && 1417 comment != null && comment.toString().trim().startsWith(twoSlashes) &&
1373 sameLine(comment, previousToken); 1418 sameLine(comment, previousToken);
1374 1419
1375 /// Emit this [comment], inserting leading whitespace if appropriate. 1420 /// Emit this [comment], inserting leading whitespace if appropriate.
1376 emitComment(Token comment, Token previousToken) { 1421 emitComment(Token comment, Token previousToken) {
1377 if (!writer.currentLine.isWhitespace() && !isBlock(comment)) { 1422 if (!writer.currentLine.isWhitespace() && !isBlock(comment)) {
1378 var ws = countSpacesBetween(previousToken, comment); 1423 var ws = countSpacesBetween(previousToken, comment);
1379 // Preserve one space but no more 1424 // Preserve one space but no more
1380 if (ws > 0) { 1425 if (ws > 0) {
1381 space(); 1426 append(' ');
1382 } 1427 }
1383 } 1428 }
1384 1429
1385 append(comment.toString().trim()); 1430 append(comment.toString().trim());
1386 } 1431 }
1387 1432
1388 /// Count spaces between these tokens. Tokens on different lines return 0. 1433 /// Count spaces between these tokens. Tokens on different lines return 0.
1389 int countSpacesBetween(Token last, Token current) => isEOF(last) || 1434 int countSpacesBetween(Token last, Token current) => isEOF(last) ||
1390 countNewlinesBetween(last, current) > 0 ? 0 : current.offset - last.end; 1435 countNewlinesBetween(last, current) > 0 ? 0 : current.offset - last.end;
1391 1436
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1449 var lastLine = 1494 var lastLine =
1450 lineInfo.getLocation(lastOffset).lineNumber; 1495 lineInfo.getLocation(lastOffset).lineNumber;
1451 var currentLine = 1496 var currentLine =
1452 lineInfo.getLocation(currentOffset).lineNumber; 1497 lineInfo.getLocation(currentOffset).lineNumber;
1453 return currentLine - lastLine; 1498 return currentLine - lastLine;
1454 } 1499 }
1455 1500
1456 String toString() => writer.toString(); 1501 String toString() => writer.toString();
1457 1502
1458 } 1503 }
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