Chromium Code Reviews| Index: pkg/analyzer/lib/src/services/formatter_impl.dart |
| diff --git a/pkg/analyzer/lib/src/services/formatter_impl.dart b/pkg/analyzer/lib/src/services/formatter_impl.dart |
| index 588464d5e591817ff7e223f8b6db6f522467a3b9..2bf8ef98edbe3bca36ded0332a0fb65460f5cc35 100644 |
| --- a/pkg/analyzer/lib/src/services/formatter_impl.dart |
| +++ b/pkg/analyzer/lib/src/services/formatter_impl.dart |
| @@ -385,6 +385,9 @@ class SourceVisitor implements AstVisitor { |
| /// A weight for potential breakpoints. |
| int currentBreakWeight = DEFAULT_SPACE_WEIGHT; |
| + /// A weight of a potential breakpoint of the current level. |
| + int levelBreakWeight = 0; |
| + |
| /// Original pre-format selection information (may be null). |
| final Selection preSelection; |
| @@ -423,8 +426,14 @@ class SourceVisitor implements AstVisitor { |
| visitArgumentList(ArgumentList node) { |
| token(node.leftParenthesis); |
| - breakableNonSpace(); |
| - visitCommaSeparatedNodes(node.arguments); |
| + if (node.arguments.isNotEmpty) { |
| + withBreakLevel(() { |
| + levelSpace(0); |
| + visitCommaSeparatedNodes( |
| + node.arguments, |
| + followedBy: () => levelSpace()); |
| + }); |
| + } |
| token(node.rightParenthesis); |
| } |
| @@ -455,11 +464,30 @@ class SourceVisitor implements AstVisitor { |
| } |
| visitBinaryExpression(BinaryExpression node) { |
| - visit(node.leftOperand); |
| - space(); |
| - token(node.operator); |
| - space(); |
| - visit(node.rightOperand); |
| + withBreakLevel(() { |
| + Token operator = node.operator; |
| + TokenType operatorType = operator.type; |
| + int addOperands(List<Expression> operands, Expression e, int i) { |
| + if (e is BinaryExpression && e.operator.type == operatorType) { |
| + i = addOperands(operands, e.leftOperand, i); |
| + i = addOperands(operands, e.rightOperand, i); |
| + } else { |
| + operands.insert(i++, e); |
| + } |
| + return i; |
| + } |
| + List<Expression> operands = []; |
| + addOperands(operands, node.leftOperand, 0); |
| + addOperands(operands, node.rightOperand, operands.length); |
| + for (int i = 0; i < operands.length; i++) { |
| + if (i != 0) { |
| + space(); |
| + token(operator); |
| + levelSpace(); |
| + } |
| + visit(operands[i]); |
| + } |
| + }); |
| } |
| visitBlock(Block node) { |
| @@ -595,16 +623,18 @@ class SourceVisitor implements AstVisitor { |
| } |
| visitConditionalExpression(ConditionalExpression node) { |
| - visit(node.condition); |
| - space(); |
| - token(node.question); |
| - allowContinuedLines((){ |
| - space(); |
| - visit(node.thenExpression); |
| - space(); |
| - token(node.colon); |
| + withBreakLevel(() { |
| + visit(node.condition); |
| space(); |
| - visit(node.elseExpression); |
| + token(node.question); |
| + allowContinuedLines((){ |
| + levelSpace(); |
| + visit(node.thenExpression); |
| + space(); |
| + token(node.colon); |
| + levelSpace(); |
| + visit(node.elseExpression); |
| + }); |
| }); |
| } |
| @@ -748,10 +778,12 @@ class SourceVisitor implements AstVisitor { |
| } |
| visitExpressionFunctionBody(ExpressionFunctionBody node) { |
| - token(node.functionDefinition); |
| - space(); |
| - visit(node.expression); |
| - token(node.semicolon); |
| + withBreakLevel(() { |
| + token(node.functionDefinition); |
| + levelSpace(); |
| + visit(node.expression); |
| + token(node.semicolon); |
| + }); |
| } |
| visitExpressionStatement(ExpressionStatement node) { |
| @@ -1023,7 +1055,10 @@ class SourceVisitor implements AstVisitor { |
| visit(node.typeArguments); |
| token(node.leftBracket); |
| indent(); |
| - visitCommaSeparatedNodes(node.elements /*, followedBy: breakableSpace*/); |
| + withBreakLevel(() { |
| + levelSpace(0); |
| + visitCommaSeparatedNodes(node.elements, followedBy: levelSpace); |
| + }); |
| optionalTrailingComma(node.rightBracket); |
| token(node.rightBracket, precededBy: unindent); |
| } |
| @@ -1573,6 +1608,18 @@ class SourceVisitor implements AstVisitor { |
| emitEmptySpaces = true; |
| } |
| + /// Emit level spaces, even if empty (works as a break point). |
| + levelSpace([int n = 1]) { |
| + space(n: n, breakWeight: levelBreakWeight); |
| + emitEmptySpaces = true; |
| + } |
| + |
| + void withBreakLevel(process()) { |
| + levelBreakWeight++; |
| + process(); |
| + levelBreakWeight--; |
| + } |
| + |
| /// Emit a non-breakable space. |
| nonBreakingSpace() { |
| space(breakWeight: UNBREAKABLE_SPACE_WEIGHT); |
| @@ -1583,7 +1630,7 @@ class SourceVisitor implements AstVisitor { |
| /// indent-level), otherwise line-leading spaces will be ignored. |
| space({n: 1, allowLineLeading: false, breakWeight: DEFAULT_SPACE_WEIGHT}) { |
| //TODO(pquitslund): replace with a proper space token |
| - leadingSpaces+=n; |
| + leadingSpaces += n; |
|
Brian Wilkerson
2014/07/09 19:47:15
Looks like we need to format this code :-)
|
| allowLineLeadingSpaces = allowLineLeading; |
| currentBreakWeight = breakWeight; |
| } |