From 3af3679f76e8c4675212f75aae0433506311c609 Mon Sep 17 00:00:00 2001 From: sijun-yang Date: Tue, 15 Sep 2026 19:32:23 +0900 Subject: [PATCH] Support null arguments in CodeBlock See gh-1842 Signed-off-by: sijun-yang --- .../generator/language/CodeBlock.java | 17 +++++++++-------- .../generator/language/CodeBlockTests.java | 12 ++++++++++++ 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/initializr-generator/src/main/java/io/spring/initializr/generator/language/CodeBlock.java b/initializr-generator/src/main/java/io/spring/initializr/generator/language/CodeBlock.java index 060330e76f..d3aa7950ce 100644 --- a/initializr-generator/src/main/java/io/spring/initializr/generator/language/CodeBlock.java +++ b/initializr-generator/src/main/java/io/spring/initializr/generator/language/CodeBlock.java @@ -18,6 +18,7 @@ import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.stream.Collector; import java.util.stream.StreamSupport; @@ -70,7 +71,7 @@ public final class CodeBlock { private CodeBlock(Builder builder) { this.parts = List.copyOf(builder.parts); - this.args = List.copyOf(builder.args); + this.args = Collections.unmodifiableList(new ArrayList<>(builder.args)); this.imports = List.copyOf(builder.imports); } @@ -143,7 +144,7 @@ private static String quote(String value) { * @return a new instance * @see #builder() */ - public static CodeBlock of(String format, Object... args) { + public static CodeBlock of(String format, @Nullable Object... args) { return new Builder().add(format, args).build(); } @@ -155,7 +156,7 @@ public static CodeBlock of(String format, Object... args) { * @return a new instance * @see #builder() */ - public static CodeBlock ofStatement(String format, Object... args) { + public static CodeBlock ofStatement(String format, @Nullable Object... args) { return new Builder().addStatement(format, args).build(); } @@ -222,7 +223,7 @@ public Builder add(CodeBlock codeBlock) { * @param args the arguments, if any * @return this for method chaining */ - public Builder add(String format, Object... args) { + public Builder add(String format, @Nullable Object... args) { int relativeParameterCount = 0; for (int p = 0; p < format.length();) { @@ -263,7 +264,7 @@ private boolean isNoArgPlaceholder(char c) { return c == '$' || c == ']'; } - private void addArgument(String format, char c, Object arg) { + private void addArgument(String format, char c, @Nullable Object arg) { switch (c) { case 'L' -> this.args.add(arg(arg)); case 'S' -> this.args.add(argToString(arg)); @@ -273,7 +274,7 @@ private void addArgument(String format, char c, Object arg) { } } - private Object arg(Object arg) { + private @Nullable Object arg(@Nullable Object arg) { if (arg instanceof CodeBlock code) { this.imports.addAll(code.getImports()); } @@ -284,7 +285,7 @@ private Object arg(Object arg) { return (arg != null) ? String.valueOf(arg) : null; } - private String argToType(Object arg) { + private String argToType(@Nullable Object arg) { if (arg instanceof Class type) { this.imports.add(type.getName()); return type.getSimpleName(); @@ -318,7 +319,7 @@ public Builder addStatement(CodeBlock codeBlock) { * @param args the arguments, if any * @return this for method chaining */ - public Builder addStatement(String format, Object... args) { + public Builder addStatement(String format, @Nullable Object... args) { add(format, args); this.parts.add("$]"); return this; diff --git a/initializr-generator/src/test/java/io/spring/initializr/generator/language/CodeBlockTests.java b/initializr-generator/src/test/java/io/spring/initializr/generator/language/CodeBlockTests.java index 8ec5438552..ef5f21efe4 100644 --- a/initializr-generator/src/test/java/io/spring/initializr/generator/language/CodeBlockTests.java +++ b/initializr-generator/src/test/java/io/spring/initializr/generator/language/CodeBlockTests.java @@ -68,6 +68,12 @@ void codeBlockWithStringPlaceholder() { assertThat(writeJava(code)).isEqualTo("return myUtil.truncate(\"value\")"); } + @Test + void codeBlockWithNullStringPlaceholder() { + CodeBlock code = CodeBlock.of("return $S", (Object) null); + assertThat(writeJava(code)).isEqualTo("return null"); + } + @Test void codeBlockWithStringPlaceholderAndDoubleQuote() { CodeBlock code = CodeBlock.of("return myUtil.truncate($S)", "va\"lue"); @@ -86,6 +92,12 @@ void codeBlockWithLiteralPlaceholder() { assertThat(writeJava(code)).isEqualTo("return myUtil.truncate(myString)"); } + @Test + void codeBlockWithNullLiteralPlaceholder() { + CodeBlock code = CodeBlock.of("return $L", (Object) null); + assertThat(writeJava(code)).isEqualTo("return null"); + } + @Test void codeBlockWithLiteralPlaceHolderUsingCodeBlock() { CodeBlock code = CodeBlock.of("return myUtil.add($L, $L)", CodeBlock.of("1"), CodeBlock.of("2"));