Allow splitting between adjacent strings.

Fixes #201

BUG= https://github.com/dart-lang/dart_style/issues/201
R=kevmoo@google.com

Review URL: https://chromiumcodereview.appspot.com//1246413003 .
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e8a2ed1..51480cc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,6 @@
 # 0.2.0-rc.2
 
+* Allow splitting between adjacent strings (#201).
 * Force multi-line comments to the next line (#241).
 * Better splitting in metadata annotations in parameter lists (#247).
 * New optimized line splitter (#360, #380).
diff --git a/lib/src/chunk_builder.dart b/lib/src/chunk_builder.dart
index f23be5b..25d36cb 100644
--- a/lib/src/chunk_builder.dart
+++ b/lib/src/chunk_builder.dart
@@ -101,7 +101,8 @@
   /// token pair.
   bool get needsToPreserveNewlines =>
       _pendingWhitespace == Whitespace.oneOrTwoNewlines ||
-          _pendingWhitespace == Whitespace.spaceOrNewline;
+          _pendingWhitespace == Whitespace.spaceOrNewline ||
+          _pendingWhitespace == Whitespace.splitOrNewline;
 
   /// The number of characters of code that can fit in a single line.
   int get pageWidth => _formatter.pageWidth;
@@ -317,6 +318,15 @@
         }
         break;
 
+      case Whitespace.splitOrNewline:
+        if (numLines > 0) {
+          _pendingWhitespace = Whitespace.nestedNewline;
+        } else {
+          _pendingWhitespace = Whitespace.none;
+          split(space: true);
+        }
+        break;
+
       case Whitespace.oneOrTwoNewlines:
         if (numLines > 1) {
           _pendingWhitespace = Whitespace.twoNewlines;
@@ -582,6 +592,7 @@
         break;
 
       case Whitespace.spaceOrNewline:
+      case Whitespace.splitOrNewline:
       case Whitespace.oneOrTwoNewlines:
         // We should have pinned these down before getting here.
         assert(false);
diff --git a/lib/src/source_visitor.dart b/lib/src/source_visitor.dart
index 42897b8..3e7c3dc 100644
--- a/lib/src/source_visitor.dart
+++ b/lib/src/source_visitor.dart
@@ -92,7 +92,11 @@
   }
 
   visitAdjacentStrings(AdjacentStrings node) {
-    visitNodes(node.strings, between: spaceOrNewline);
+    builder.startSpan();
+    builder.startRule();
+    visitNodes(node.strings, between: splitOrNewline);
+    builder.endRule();
+    builder.endSpan();
   }
 
   visitAnnotation(Annotation node) {
@@ -1913,6 +1917,13 @@
     builder.writeWhitespace(Whitespace.spaceOrNewline);
   }
 
+  /// Allow either a single split or newline to be emitted before the next
+  /// non-whitespace token based on whether a newline exists in the source
+  /// between the last token and the next one.
+  void splitOrNewline() {
+    builder.writeWhitespace(Whitespace.splitOrNewline);
+  }
+
   /// Allow either one or two newlines to be emitted before the next
   /// non-whitespace token based on whether more than one newline exists in the
   /// source between the last token and the next one.
diff --git a/lib/src/whitespace.dart b/lib/src/whitespace.dart
index 384b28e..481f498 100644
--- a/lib/src/whitespace.dart
+++ b/lib/src/whitespace.dart
@@ -66,6 +66,13 @@
   /// less prescriptive over the user's whitespace.
   static const spaceOrNewline = const Whitespace._("spaceOrNewline");
 
+  /// A split or newline should be output based on whether the current token is
+  /// on the same line as the previous one or not.
+  ///
+  /// In general, we like to avoid using this because it makes the formatter
+  /// less prescriptive over the user's whitespace.
+  static const splitOrNewline = const Whitespace._("splitOrNewline");
+
   /// One or two newlines should be output based on how many newlines are
   /// present between the next token and the previous one.
   ///
diff --git a/test/regression/0200/0201.stmt b/test/regression/0200/0201.stmt
new file mode 100644
index 0000000..8ee7024
--- /dev/null
+++ b/test/regression/0200/0201.stmt
@@ -0,0 +1,11 @@
+>>>
+main() {
+  var s =
+      'qsmdlfkjqlsdf mlqdskf mlqkds flq fdmlqk mqlfk ' 'mlfqks dflq sdmlfkjqmlsdkjf mlqks mfdlq smlf ' 'mqlskdjf mlqksd jfmlqkj dmflkq mdslk jfmqds kf';
+}
+<<<
+main() {
+  var s = 'qsmdlfkjqlsdf mlqdskf mlqkds flq fdmlqk mqlfk '
+      'mlfqks dflq sdmlfkjqmlsdkjf mlqks mfdlq smlf '
+      'mqlskdjf mlqksd jfmlqkj dmflkq mdslk jfmqds kf';
+}
\ No newline at end of file
diff --git a/test/splitting/expressions.stmt b/test/splitting/expressions.stmt
index 76c9b62..8ac19ef 100644
--- a/test/splitting/expressions.stmt
+++ b/test/splitting/expressions.stmt
@@ -1,9 +1,23 @@
 40 columns                              |
->>> space-separated adjacent strings are not split
-var name = new Symbol("the first string" "the second string");
+>>> space-separated adjacent strings are not split if they fit
+var name = new Symbol("the first string" "the second");
 <<<
 var name = new Symbol(
-    "the first string" "the second string");
+    "the first string" "the second");
+>>> space-separated adjacent strings are split if they don't fit
+var name = new Symbol("the first very long string" "the second very longstring");
+<<<
+var name = new Symbol(
+    "the first very long string"
+    "the second very longstring");
+>>> adjacent string lines all split together;
+var text = "first" "second" "third" "fourth" "fifth";
+<<<
+var text = "first"
+    "second"
+    "third"
+    "fourth"
+    "fifth";
 >>> preserve one newline between adjacent strings
 var name = "the first string"
 "the second string"