google-java-format
google-java-format copied to clipboard
multiline strings poorly formatted
We use multiline strings to write queries using the @Query annotation. The formatter does a poor job of formatting these strings and in some cases does not attempt to format strings that are poorly formatted (to my eyes).
The formatter considers the following examples to be correctly formatted.

Well, technically, they are: Google Java Format won't change the content of the string, it cannot know whether the spaces and line ends are meaningful or not. Your IDE highlights the SQL syntax inside the string, but from a Java perspective they are just string and without that special knowledge from the IDE that they contain SQL, they'd be all green like quotes that delimit them.
Note that in the first picture, the indentation is known to be irrelevant. The horizontal placement of the opening delimiter has no effect on the string content, and both other lines (SELECT and closing delimiter) have the same amount of indentation, so all indentation is removed. The value of that string is just the SELECT statement with a trailing line break.
I would also find it great if google-java-format would adjust and fix indentation of text blocks. In this particular example, all lines of the text block should get the same indentation as the opening delimiter.
For the second picture, it seems that the SELECT has no indentation at all. In this case, everything about the text block except the placement of the opening delimiter is relevant for the string content, so google-java-format can indeed do nothing.
I would also find it great if google-java-format would adjust and fix indentation of text blocks.
I want my text blocks to be formatted and stay exactly formatted like I formatted them.
@sormuras Note that google-java-format is an opinionated code formatter and deliberately ignores almost all existing formatting in the input. I don't think indentation of text blocks meets these criteria so it is expected that google-java-format will change it.
String s = "a\n\nb\n";
String t = """
a
b
""";
Any change any formatter, opinionated or not, does to any String literal I wrote in a Java source file that results in a different String instance at run-time ... is broken. If formatter moves a String or text block around, the String instance must stay as-is.
Or in other words: formatter, style my code, but don't alter it.
As explained above (https://github.com/google/google-java-format/issues/883#issuecomment-1398005211), common indentation of a text block is not relevant for its content.
Then we are on the same page. 👍
String s = "a\n\n" + "b\n";
String t = """
a
b
""";
I would also find it great if google-java-format would adjust and fix indentation of text blocks.
I want my text blocks to be formatted and stay exactly formatted like I formatted them.
This would be better than what it does now
Hello. It happens I was part of the group that designed text blocks for Java (though all credit goes to Jim Laskey and others). First here's some possibly-unnecessary clarity on exactly how the feature works:
Ignore the line containing the opening """, but don't ignore the closing """. Now visualize the smallest bounding rectangle around all visible (non-whitespace) characters (again, including the closing """). Lastly chop off that """, trim trailing whitespace from every line, and don't add a final newline (in most cases you already had that).
The result is the exact contents of the string. The lines in that rectangle will never be shifted relative to each other. (Yeah, did I coin two different "rectangle rules"? I think I did.)
The effect is that a rectangle of spaces, shown here as dots, is ignored as if they were not present:

(from https://docs.oracle.com/en/java/javase/15/text-blocks/index.html)
That means that the formatter is every bit as justified in adding or removing columns to that rectangle-shown-as-dots as it is in changing any other indentation. And I agree that leaving the indentation as it was doesn't meet the criteria @PhilippWendler linked to.
I think it should be indented to the level at which the line containing the """ is, plus either a regular or a continuation indent. First thought would be regular, since it doesn't fit the definition of a continuation line (which IIRC is: when no style rule would have forced you to break except for the column limit, then all lines but the first are continuation lines; this holds whether the column limit did force the break or it was elective).
Then we are on the same page. 👍
String s = "a\n\n" + "b\n"; String t = """ a b """;
(To be clear, it wouldn't do that specifically, since it would be vulnerable to simple refactorings.)