Merge pull request #945 from dart-lang/split-nested-conditionals

Split conditional expressions when nested.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index bab5b30..a865194 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,7 @@
 
 * Split help into verbose and non-verbose lists (#938).
 * Don't crash when non-ASCII whitespace is trimmed (#901).
+* Split all conditional expressions (`?:`) when they are nested (#927).
 
 # 1.3.6
 
diff --git a/lib/src/source_visitor.dart b/lib/src/source_visitor.dart
index 46c0bf7..04a2bee 100644
--- a/lib/src/source_visitor.dart
+++ b/lib/src/source_visitor.dart
@@ -848,6 +848,11 @@
     space();
     visit(node.elseExpression);
 
+    // If conditional expressions are directly nested, force them all to split.
+    // This line here forces the child, which implicitly forces the surrounding
+    // parent rules to split too.
+    if (node.parent is ConditionalExpression) builder.forceRules();
+
     builder.endRule();
     builder.endSpan();
     builder.endBlockArgumentNesting();
@@ -1721,19 +1726,6 @@
     var oldConstNesting = _constNesting;
     _constNesting = 0;
 
-    // TODO(rnystrom): This is working but not tested. As of 2016/11/29, the
-    // latest version of analyzer on pub does not parse generic lambdas. When
-    // a version of it that does is published, upgrade dart_style to use it and
-    // then test it:
-    //
-    //     >>> generic function expression
-    //         main() {
-    //           var generic = < T,S >(){};
-    //     }
-    //     <<<
-    //     main() {
-    //       var generic = <T, S>() {};
-    //     }
     _visitBody(node.typeParameters, node.parameters, node.body);
 
     _constNesting = oldConstNesting;
diff --git a/test/regression/0900/0927.unit b/test/regression/0900/0927.unit
new file mode 100644
index 0000000..517df4f
--- /dev/null
+++ b/test/regression/0900/0927.unit
@@ -0,0 +1,12 @@
+>>>
+class C {
+  int get currentAngleDigits => _currentSunAngleDeg < 0 ? 1 : _currentSunAngleDeg < 10 ? 2 : 3;
+}
+<<<
+class C {
+  int get currentAngleDigits => _currentSunAngleDeg < 0
+      ? 1
+      : _currentSunAngleDeg < 10
+          ? 2
+          : 3;
+}
\ No newline at end of file
diff --git a/test/splitting/expressions.stmt b/test/splitting/expressions.stmt
index 3911eb1..f6a666c 100644
--- a/test/splitting/expressions.stmt
+++ b/test/splitting/expressions.stmt
@@ -70,6 +70,26 @@
 var kind = element != null
     ? argument
     : secondArgumentThatIsReallyLong;
+>>> split all conditionals when nested
+var kind = a ? b ? c : d : e;
+<<<
+var kind = a
+    ? b
+        ? c
+        : d
+    : e;
+>>> split all conditionals when nested
+var kind = a ? b : c ? d : e;
+<<<
+var kind = a
+    ? b
+    : c
+        ? d
+        : e;
+>>> don't split conditionals when indirectly nested
+var kind = a ? b : (c ? d : e);
+<<<
+var kind = a ? b : (c ? d : e);
 >>> split operator chain around block
 first + second + () {body;} + third + fourth;
 <<<
diff --git a/test/whitespace/expressions.stmt b/test/whitespace/expressions.stmt
index daff76b..0d300e9 100644
--- a/test/whitespace/expressions.stmt
+++ b/test/whitespace/expressions.stmt
@@ -162,4 +162,8 @@
 >>> null-aware index expressions
 obj   ?[  foo];
 <<<
-obj?[foo];
\ No newline at end of file
+obj?[foo];
+>>> generic function expression
+var generic = < T,S >(){};
+<<<
+var generic = <T, S>() {};
\ No newline at end of file