Fix method argument indentation bug
For methods in builder chains, indent the arguments an extra +4 if the
qualified method name is broken.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=103105218
diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java
index 9f193f5..5a32b93 100644
--- a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java
+++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java
@@ -2579,8 +2579,11 @@
builder.breakOp(FillMode.UNIFIED, "", ZERO);
token(".");
}
- dotExpressionUpToArgs(e);
- dotExpressionArgsAndParen(e, (trailingDereferences || needDot) ? plusFour : ZERO);
+ BreakTag tyargTag = genSym();
+ dotExpressionUpToArgs(e, Optional.of(tyargTag));
+ Indent tyargIndent = Indent.If.make(tyargTag, plusFour, ZERO);
+ dotExpressionArgsAndParen(
+ e, tyargIndent, (trailingDereferences || needDot) ? plusFour : ZERO);
needDot = true;
}
if (!needDot0) {
@@ -2600,10 +2603,11 @@
private void visitDotWithPrefix(List<Expression> items, boolean needDot, int prefixIndex) {
// Are there method invocations or field accesses after the prefix?
boolean trailingDereferences = prefixIndex >= 0 && prefixIndex < items.size() - 1;
-
+
builder.open(plusFour, MAX_LINES_FOR_CHAINED_ACCESSES);
builder.open(trailingDereferences ? ZERO : ZERO);
+ BreakTag nameTag = genSym();
for (int i = 0; i < items.size(); i++) {
Expression e = items.get(i);
if (needDot) {
@@ -2614,14 +2618,19 @@
fillMode = FillMode.UNIFIED;
}
- builder.breakOp(fillMode, "", ZERO);
+ builder.breakOp(fillMode, "", ZERO, Optional.of(nameTag));
token(".");
}
- dotExpressionUpToArgs(e);
+ BreakTag tyargTag = genSym();
+ dotExpressionUpToArgs(e, Optional.of(tyargTag));
if (prefixIndex >= 0 && i == prefixIndex) {
builder.close();
}
- dotExpressionArgsAndParen(e, trailingDereferences ? plusFour : ZERO);
+
+ Indent tyargIndent = Indent.If.make(tyargTag, plusFour, ZERO);
+ Indent argsIndent = Indent.If.make(nameTag, plusFour, trailingDereferences ? plusFour : ZERO);
+ dotExpressionArgsAndParen(e, tyargIndent, argsIndent);
+
needDot = true;
}
@@ -2653,7 +2662,7 @@
return simpleNames.build();
}
- private void dotExpressionUpToArgs(Expression expression) {
+ private void dotExpressionUpToArgs(Expression expression, Optional<BreakTag> tyargTag) {
switch (expression.getNodeType()) {
case ASTNode.FIELD_ACCESS:
FieldAccess fieldAccess = (FieldAccess) expression;
@@ -2665,7 +2674,7 @@
builder.open(plusFour);
addTypeArguments(methodInvocation.typeArguments(), ZERO);
// TODO(jdd): Should indent the name -4.
- builder.breakOp(ZERO);
+ builder.breakOp(Doc.FillMode.UNIFIED, "", ZERO, tyargTag);
builder.close();
}
visit(methodInvocation.getName());
@@ -2682,18 +2691,18 @@
}
}
- private void dotExpressionArgsAndParen(Expression expression, Indent indent) {
+ private void dotExpressionArgsAndParen(Expression expression, Indent tyargIndent, Indent indent) {
switch (expression.getNodeType()) {
- case ASTNode.FIELD_ACCESS:
- break;
case ASTNode.METHOD_INVOCATION:
+ builder.open(tyargIndent);
MethodInvocation methodInvocation = (MethodInvocation) expression;
addArguments(methodInvocation.arguments(), indent);
+ builder.close();
token(")");
break;
+ case ASTNode.FIELD_ACCESS:
case ASTNode.SIMPLE_NAME:
case ASTNode.QUALIFIED_NAME:
- break;
default:
break;
}
diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B23749160.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B23749160.input
new file mode 100644
index 0000000..d94ffdf
--- /dev/null
+++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B23749160.input
@@ -0,0 +1,46 @@
+class B23749160 {
+ {
+ mockDailySummaryModuleListFiller
+ .buildDailySummaryModulesWithHeadersOnlyAndOneExpandedDayxxxxxxxxxxx(
+ anyInt(), anyInt(), anyInt());
+
+ mockDailySummaryModuleListFiller
+ .<XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,
+ YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY>
+ buildDailySummaryModulesWithHeadersOnlyAndOneExpandedDayxxxxxxxxxxx(
+ anyInt(), anyInt(), anyInt());
+
+ foo
+ .<XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,
+ YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY>
+ buildDailySummaryModulesWithHeadersOnlyAndOneExpandedDayxxxxxxxxxxx(
+ anyInt(), anyInt(), anyInt())
+ .bar();
+
+ // `.build`... and `anotherThing`... are technically at different syntactic
+ // levels, but the indentation required to express that starts to get out
+ // of hand
+ MockDailySummaryModuleListFiller
+ .buildDailySummaryModulesWithHeadersOnlyAndOneExpandedDayxxxxxxxxxxx(
+ anyInt(), anyInt(), anyInt())
+ .anotherThing();
+
+ when(
+ mockDailySummaryModuleListFiller
+ .buildDailySummaryModulesWithHeadersOnlyAndOneExpandedDay(
+ anyInt(), anyInt(), anyInt()))
+ .then();
+
+ private static final List<Integer> SERVICE_LIST =
+ ImmutableList.of(
+ INSServiceID.CARIBOU, // Mail
+ INSServiceID.WRITELY, // Drive
+ INSServiceID.CALENDAR, // Calendar
+ INSServiceID.BUZZ, // Talk
+ INSServiceID.CONTACTS, // Contacts
+ INSServiceID.GROUPS_RELOADED, // Groups
+ INSServiceID.JOTSPOT, // Sites
+ INSServiceID.GEO_DISPATCH // Coordinate
+ );
+ }
+}
diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B23749160.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B23749160.output
new file mode 100644
index 0000000..a963027
--- /dev/null
+++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B23749160.output
@@ -0,0 +1,46 @@
+class B23749160 {
+ {
+ mockDailySummaryModuleListFiller
+ .buildDailySummaryModulesWithHeadersOnlyAndOneExpandedDayxxxxxxxxxxx(
+ anyInt(), anyInt(), anyInt());
+
+ mockDailySummaryModuleListFiller
+ .<XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,
+ YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY>
+ buildDailySummaryModulesWithHeadersOnlyAndOneExpandedDayxxxxxxxxxxx(
+ anyInt(), anyInt(), anyInt());
+
+ foo
+ .<XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,
+ YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY>
+ buildDailySummaryModulesWithHeadersOnlyAndOneExpandedDayxxxxxxxxxxx(
+ anyInt(), anyInt(), anyInt())
+ .bar();
+
+ // `.build`... and `anotherThing`... are technically at different syntactic
+ // levels, but the indentation required to express that starts to get out
+ // of hand
+ MockDailySummaryModuleListFiller
+ .buildDailySummaryModulesWithHeadersOnlyAndOneExpandedDayxxxxxxxxxxx(
+ anyInt(), anyInt(), anyInt())
+ .anotherThing();
+
+ when(
+ mockDailySummaryModuleListFiller
+ .buildDailySummaryModulesWithHeadersOnlyAndOneExpandedDay(
+ anyInt(), anyInt(), anyInt()))
+ .then();
+
+ private static final List<Integer> SERVICE_LIST =
+ ImmutableList.of(
+ INSServiceID.CARIBOU, // Mail
+ INSServiceID.WRITELY, // Drive
+ INSServiceID.CALENDAR, // Calendar
+ INSServiceID.BUZZ, // Talk
+ INSServiceID.CONTACTS, // Contacts
+ INSServiceID.GROUPS_RELOADED, // Groups
+ INSServiceID.JOTSPOT, // Sites
+ INSServiceID.GEO_DISPATCH // Coordinate
+ );
+ }
+}