Skip to content

Commit 98c6bbd

Browse files
cushongoogle-java-format Team
authored andcommitted
If a text block is outdented, outdent the opening """ too
PiperOrigin-RevId: 694533649
1 parent 666fe33 commit 98c6bbd

6 files changed

Lines changed: 32 additions & 8 deletions

File tree

core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
import com.google.googlejavaformat.FormattingError;
7171
import com.google.googlejavaformat.Indent;
7272
import com.google.googlejavaformat.Input;
73+
import com.google.googlejavaformat.Newlines;
7374
import com.google.googlejavaformat.Op;
7475
import com.google.googlejavaformat.OpenOp;
7576
import com.google.googlejavaformat.OpsBuilder;
@@ -1667,6 +1668,15 @@ public Void visitMemberSelect(MemberSelectTree node, Void unused) {
16671668
public Void visitLiteral(LiteralTree node, Void unused) {
16681669
sync(node);
16691670
String sourceForNode = getSourceForNode(node, getCurrentPath());
1671+
if (sourceForNode.endsWith("\"\"\"")
1672+
&& (Newlines.hasNewlineAt(sourceForNode, sourceForNode.length() - 4) != -1)) {
1673+
// If the closing delimiter of a text block starts at the margin, outdent the opening
1674+
// delimiter as well by adding a break with negative indentation. Outdenting for text blocks
1675+
// with wide contents is also handled by StringWrapper, but this means the behaviour for
1676+
// the opening delimiter is consistent if string wrapping is disabled, and also effectively
1677+
// preserves user choice about which text blocks stay de-indented.
1678+
builder.breakOp(Indent.Const.make(Integer.MIN_VALUE / indentMultiplier, indentMultiplier));
1679+
}
16701680
if (isUnaryMinusLiteral(sourceForNode)) {
16711681
token("-");
16721682
sourceForNode = sourceForNode.substring(1).trim();

core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -190,9 +190,10 @@ public Void visitLiteral(LiteralTree literalTree, Void aVoid) {
190190
private void indentTextBlocks(
191191
TreeRangeMap<Integer, String> replacements, List<Tree> textBlocks) {
192192
for (Tree tree : textBlocks) {
193-
int startPosition = getStartPosition(tree);
193+
int startPosition = lineMap.getStartPosition(lineMap.getLineNumber(getStartPosition(tree)));
194194
int endPosition = getEndPosition(unit, tree);
195195
String text = input.substring(startPosition, endPosition);
196+
int startColumn = CharMatcher.whitespace().negate().indexIn(text) + 1;
196197

197198
// Find the source code of the text block with incidental whitespace removed.
198199
// The first line of the text block is always """, and it does not affect incidental
@@ -203,13 +204,12 @@ private void indentTextBlocks(
203204
int deindent =
204205
initialLines.get(1).stripTrailing().length() - lines.get(0).stripTrailing().length();
205206

206-
int startColumn = lineMap.getColumnNumber(startPosition);
207207
String prefix =
208208
(deindent == 0 || lines.stream().anyMatch(x -> x.length() + startColumn > columnLimit))
209209
? ""
210210
: " ".repeat(startColumn - 1);
211211

212-
StringBuilder output = new StringBuilder(TEXT_BLOCK_DELIMITER);
212+
StringBuilder output = new StringBuilder(prefix).append(initialLines.get(0).stripLeading());
213213
for (int i = 0; i < lines.size(); i++) {
214214
String line = lines.get(i);
215215
String trimmed = line.stripLeading().stripTrailing();

core/src/test/java/com/google/googlejavaformat/java/StringWrapperTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ public void textBlock() throws Exception {
6363
" private String myString;",
6464
" private ReproBug() {",
6565
" String str =",
66-
" \"\"\"",
66+
"\"\"\"",
6767
"{\"sourceEndpoint\":\"ri.something.1-1.object-internal.1\",\"targetEndpoint"
6868
+ "\":\"ri.something.1-1.object-internal.2\",\"typeId\":\"typeId\"}\\",
6969
"\"\"\";",

core/src/test/resources/com/google/googlejavaformat/java/testdata/B377585941.output

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ class T {
22
{
33
f(
44
/* foo */ """
5-
hello
6-
""");
5+
hello
6+
""");
77
}
88
}

core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.input

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,5 +50,12 @@ ipsum
5050
hello %s
5151
"""
5252
.formatted("world");
53+
f(
54+
/* foo= */ """
55+
foo
56+
""",
57+
/* bar= */ """
58+
bar
59+
""");
5360
}
5461
}

core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.output

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,13 @@ class RSLs {
4242
ipsum
4343
""";
4444
String j =
45-
"""
45+
"""
4646
lorem
4747
one long incredibly unbroken sentence moving from topic to topic so that no one had a chance to interrupt
4848
ipsum
4949
""";
5050
String k =
51-
"""
51+
"""
5252
lorem
5353
ipsum
5454
""";
@@ -65,5 +65,12 @@ ipsum
6565
hello %s
6666
"""
6767
.formatted("world");
68+
f(
69+
/* foo= */ """
70+
foo
71+
""",
72+
/* bar= */ """
73+
bar
74+
""");
6875
}
6976
}

0 commit comments

Comments
 (0)