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"