Code Generation Formatting
Purpose
Java code generators that build source code via string concatenation must use // @formatter:off / // @formatter:on guards. Without these, IntelliJ's auto-formatter breaks concatenation chains across multiple lines, destroying the correspondence between Java source lines and generated output lines.
The Rule
Each line of generated output (terminated by \n) must occupy a single Java source line. A new line in the Java source should only occur where there is a \n in the template string.
Bad (auto-formatted)
setterBody = ""
+ " domainObject.get"
+ propNameUpper
+ "().clear();\n"
+ " return;\n";
Good (one output line per Java line)
// @formatter:off
setterBody = ""
+ " domainObject.get" + propNameUpper + "().clear();\n"
+ " return;\n";
// @formatter:on
How to Identify Violations
Search for string concatenation blocks that contain \n literals but are NOT wrapped in // @formatter:off. Common patterns:
- Multi-line
+chains where each+is on its own line and template variables are separated from their surrounding string literals .collect()lambdas producing single-line templates that got broken across multiple lines- Return statements wrapped in parentheses
return ( "" + ... )instead of directreturn "" + ...
Fix Procedure
- Search generator files for string concatenation containing
\nthat lacks@formatter:offguards - For each violation:
- Add
// @formatter:offbefore the block - Collapse string concatenation so each
\n-terminated segment is on one Java source line - Add
// @formatter:onafter the block
- Add
- For
.collect()lambdas that produce single-line templates (one\n), collapse the entire template string onto one line - For multi-line templates, each
\n-terminated segment gets its own line with+continuation - Use the same indentation style as existing
@formatter:offblocks in the file
Indentation Style
Match the existing convention in each file. The typical pattern uses tabs with + aligned:
// @formatter:off
// language=JAVA
return ""
+ "package " + packageName + ";\n"
+ "\n"
+ "public class " + className + "\n"
+ "{\n"
+ "}\n";
// @formatter:on
For .collect() lambdas with single-line output, keep it all on one line:
// @formatter:off
String fields = properties
.collect((p) -> " public final " + this.getType(p) + " " + p.getName() + ";\n")
.makeString("");
// @formatter:on
Additional Markers
When the string block contains valid Java source, add // language=JAVA after // @formatter:off to enable IntelliJ language injection for syntax highlighting inside the strings.