Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,26 @@ public void close() {
add(CloseOp.make());
}

/**
* Keep the comments before the next token inside the level just opened. {@link #build} puts the comments before a
* token ahead of the {@link OpenOp}s right before it, so that a comment before a statement or an expression stays
* out of their levels. Right after an opening delimiter, such as the {@code (} of a for loop, that takes the
* comment, and the line break after it, out of the level that indents what follows the delimiter.
*/
public void fenceComments() {
add(CommentFence.FENCE);
}

/** Where {@link #build} stops looking back over {@link OpenOp}s for the place of a token's comments. */
private enum CommentFence implements Op {
FENCE;

@Override
public void add(DocBuilder builder) {
throw new IllegalStateException("build() drops comment fences");
}
}

/** Return the text of the next {@link Input.Token}, or absent if there is none. */
public Optional<String> peekToken() {
return peekToken(0);
Expand Down Expand Up @@ -523,7 +543,7 @@ public OpsOutput build() {
* when possible.
*/
Input.Token token = tokenOp.getToken();
int j = i; // Where to insert toksBefore before.
int j = i; // Where to insert toksBefore before: ahead of the OpenOps before the token, up to a fence.
while (0 < j && ops.get(j - 1) instanceof OpenOp) {
--j;
}
Expand Down Expand Up @@ -669,6 +689,9 @@ public OpsOutput build() {
}
}
Op op = ops.get(i);
if (op == CommentFence.FENCE) {
continue;
}
if (afterForcedBreak
&& (op instanceof NonBreakingSpace
|| (op instanceof Break b
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,7 @@ public Void visitAssert(AssertTree node, Void unused) {
token("assert");
builder.space();
builder.open(node.getDetail() == null ? ZERO : plusFour);
builder.fenceComments();
scan(node.getCondition(), null);
if (node.getDetail() != null) {
builder.breakOp(" ");
Expand Down Expand Up @@ -912,6 +913,7 @@ public boolean visitEnumDeclaration(ClassTree node) {
builder.close();
if (builder.peekToken().equals(Optional.of(";"))) {
builder.open(plusTwo);
builder.fenceComments();
token(";");
builder.forcedBreak();
dropEmptyDeclarations();
Expand Down Expand Up @@ -1010,6 +1012,7 @@ public Void visitForLoop(ForLoopTree node, Void unused) {
builder.space();
token("(");
builder.open(plusFour);
builder.fenceComments();
builder.open(
node.getInitializer().size() > 1 && node.getInitializer().get(0) instanceof ExpressionStatementTree
? plusFour
Expand Down Expand Up @@ -1942,6 +1945,7 @@ public Void visitTry(TryTree node, Void unused) {
if (!node.getResources().isEmpty()) {
token("(");
builder.open(node.getResources().size() > 1 ? plusFour : ZERO);
builder.fenceComments();
boolean first = true;
for (Tree resource : node.getResources()) {
if (!first) {
Expand Down Expand Up @@ -2382,6 +2386,7 @@ private void visitCatchClause(CatchTree node, AllowTrailingBlankLine allowTraili
builder.space();
token("(");
builder.open(plusFour);
builder.fenceComments();
VariableTree ex = node.getParameter();
if (ex.getType() instanceof UnionTypeTree) {
builder.open(ZERO);
Expand Down Expand Up @@ -3179,6 +3184,7 @@ void addTypeArguments(List<? extends Tree> typeArguments, Indent plusIndent) {
}
token("<");
builder.open(plusIndent);
builder.fenceComments();
boolean first = true;
for (Tree typeArgument : typeArguments) {
if (!first) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# A comment on its own line right after `assert` stays inside the condition at the continuation indent, together
# with the code after it, when the assertion has a detail message (google-java-format#1501, #171).
----------
class T {
void f(int x, int y) {
assert
// comment
x > 0 : "positive";
assert
// comment
x > 0 : "positive";
assert
/* why */
x <
y :
"x below " + "y";
}
}
----------
class T {
void f(int x, int y) {
assert
// comment
x > 0
: "positive";
assert
// comment
x > 0
: "positive";
assert
/* why */
x < y
: "x below " + "y";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# A comment on its own line before the `;` that ends the constants of an enum stays at the indent of the constants,
# and so does the `;` (google-java-format#1501, #171).
----------
enum E1 {
A,
// comment
;
}

enum E2 {
A, B
// comment
;
void f() {}
}

enum E3 { A
/* comment */
;
}
----------
enum E1 {
A,
// comment
;
}

enum E2 {
A,
B
// comment
;

void f() {}
}

enum E3 {
A
/* comment */
;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# A comment on its own line right after the `(` of a for loop stays inside the header at the continuation indent,
# which breaks the header, so the condition and the update get a line each (google-java-format#1501, #171). A block
# comment that shares its line with the initializer stays with it, on the line of the header when that fits.
----------
class T {
void f(int n) {
for (
// comment
int i = 0; i < n; i++) {}
for (
/* comment */
int i = 0; i < n; i++) {}
for (
/* c */ int i = 0;
i < n;
i++) {}
}
}
----------
class T {
void f(int n) {
for (
// comment
int i = 0;
i < n;
i++) {}
for (
/* comment */
int i = 0;
i < n;
i++) {}
for (/* c */ int i = 0; i < n; i++) {}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# A comment on its own line right after the `(` of a multi-catch clause stays inside the clause at the continuation
# indent, with the caught types after it (google-java-format#1501, #171).
----------
class T {
void f() {
try {
g();
} catch (
// comment
IllegalArgumentException | IllegalStateException e) {
}
try { g(); } catch (
/* comment */
IllegalArgumentException
| IllegalStateException e) { h(e); }
}
}
----------
class T {
void f() {
try {
g();
} catch (
// comment
IllegalArgumentException | IllegalStateException e) {
}
try {
g();
} catch (
/* comment */
IllegalArgumentException | IllegalStateException e) {
h(e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# A comment on its own line right after the `(` of a try with several resources stays inside the resources at the
# continuation indent, with the first resource after it (google-java-format#1501, #171).
----------
class T {
void f(AutoCloseable a, AutoCloseable b) throws Exception {
try (
// comment
AutoCloseable r1 = a; AutoCloseable r2 = b) {}
try (
/* comment */
AutoCloseable r1 = a;
AutoCloseable r2 = b) {
use(r1, r2);
}
}
}
----------
class T {
void f(AutoCloseable a, AutoCloseable b) throws Exception {
try (
// comment
AutoCloseable r1 = a;
AutoCloseable r2 = b) {}
try (
/* comment */
AutoCloseable r1 = a;
AutoCloseable r2 = b) {
use(r1, r2);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# A comment on its own line right after the `<` of explicit type arguments stays inside them at the continuation
# indent, with the type after it, in a constructor call and in a method reference (google-java-format#1501, #171).
----------
class T {
<U> T() {}

static <U> void g() {}

void f() {
new <
// comment
String>T();
Runnable r =
T
::<
// comment
String>g;
new <
/* comment */
String> T();
}
}
----------
class T {
<U> T() {}

static <U> void g() {}

void f() {
new <
// comment
String>T();
Runnable r = T
::<
// comment
String>g;
new <
/* comment */
String>T();
}
}
Loading