Allow cascades with repeated method names to be one line.
BUG=
R=rnystrom@google.com
Review URL: https://codereview.appspot.com/212600043
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 16bf414..9043ff1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,7 @@
# 0.1.8-dev
* Update to latest args.
+* Allow cascades with repeated method names to be one line.
# 0.1.7
diff --git a/lib/src/source_visitor.dart b/lib/src/source_visitor.dart
index ec9ca70..bbeeafd 100644
--- a/lib/src/source_visitor.dart
+++ b/lib/src/source_visitor.dart
@@ -368,22 +368,41 @@
_writer.indent();
- // If there are multiple cascades, they always get their own line, even if
- // they would fit.
- if (node.cascadeSections.length > 1) {
- newline();
- visitNodes(node.cascadeSections, between: newline);
- } else {
+ // If the cascade sections have consistent names they can be broken
+ // normally otherwise they always get their own line.
+ if (_allowInlineCascade(node.cascadeSections)) {
_writer.startMultisplit();
_writer.multisplit();
visitNodes(node.cascadeSections, between: _writer.multisplit);
-
_writer.endMultisplit();
+ } else {
+ newline();
+ visitNodes(node.cascadeSections, between: newline);
}
_writer.unindent();
}
+ /// Whether a cascade should be allowed to be inline as opposed to one
+ /// expression per line.
+ bool _allowInlineCascade(List<Expression> sections) {
+ if (sections.length < 2) return true;
+
+ var name;
+ // We could be more forgiving about what constitutes sections with
+ // consistent names but for now we require all sections to have the same
+ // method name.
+ for (var expression in sections) {
+ if (expression is! MethodInvocation) return false;
+ if (name == null) {
+ name = expression.methodName.name;
+ } else if (name != expression.methodName.name) {
+ return false;
+ }
+ }
+ return true;
+ }
+
visitCatchClause(CatchClause node) {
token(node.onKeyword, after: space);
visit(node.exceptionType);
diff --git a/test/whitespace/cascades.stmt b/test/whitespace/cascades.stmt
index 1088331..d8a0589 100644
--- a/test/whitespace/cascades.stmt
+++ b/test/whitespace/cascades.stmt
@@ -9,13 +9,26 @@
"foo"
..toString(
argument, argument, argument);
->>> multiple cascades get their own line
-"foo"..toString()..toString();
+>>> multiple cascades get the same line when the method names are the same
+list
+ ..add("baz")
+ ..add("bar");
<<<
-"foo"
- ..toString()
+list..add("baz")..add("bar");
+>>> cascades indent contained blocks (and force multi-line) multiple cascades get their own line when method names are different
+foo..fooBar()..toString();
+<<<
+foo
+ ..fooBar()
..toString();
+>>> cascaded setters are always multi-line even with the same name
+foo..baz = 3..baz=5;
+<<<
+foo
+ ..baz = 3
+ ..baz = 5;
>>> cascades indent contained blocks (and force multi-line)
+
"foo"..toString(() {body;});
<<<
"foo"
diff --git a/test/whitespace/functions.unit b/test/whitespace/functions.unit
index e80e5b5..b79e171 100644
--- a/test/whitespace/functions.unit
+++ b/test/whitespace/functions.unit
@@ -36,12 +36,12 @@
y() async {}
var z = () async {};
}
->>> dartbug.com/16384
-fish() => []..add(1)..add(2);
-<<<
+>>>
fish() => []
..add(1)
..add(2);
+<<<
+fish() => []..add(1)..add(2);
>>>
fish() => []..add(1);
<<<