diff --git a/src/main/java/com/squareup/javapoet/CodeBlock.java b/src/main/java/com/squareup/javapoet/CodeBlock.java index 02542f58b..e39c1a177 100644 --- a/src/main/java/com/squareup/javapoet/CodeBlock.java +++ b/src/main/java/com/squareup/javapoet/CodeBlock.java @@ -18,6 +18,7 @@ import java.io.IOException; import java.lang.reflect.Type; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.regex.Matcher; @@ -126,6 +127,26 @@ public static CodeBlock join(Iterable codeBlocks, String separator) { CodeBlockJoiner::merge, CodeBlockJoiner::join); } + /** + * Joins {@code codeBlocks} into a single {@link CodeBlock}, each separated by {@code separators}. + * For example, joining {@code String s}, {@code Object o} and {@code int i} using {@code "[, ,\] "} + * would produce {@code String s, Object o\ int i}. + */ + public static CodeBlock join(Iterable codeBlocks, String[] separators) { + List list = new ArrayList<>(); + Iterator iter = codeBlocks.iterator(); + list.add((CodeBlock) iter.next()); + + for (String separator : separators) { + list.add((CodeBlock) iter.next()); + list.add(join(list, separator)); + list.remove(0); + list.remove(0); + } + return list.get(0); + } + + /** * A {@link Collector} implementation that joins {@link CodeBlock} instances together into one diff --git a/src/main/java/com/squareup/javapoet/CodeWriter.java b/src/main/java/com/squareup/javapoet/CodeWriter.java index da6d3c8e5..840ec1c53 100644 --- a/src/main/java/com/squareup/javapoet/CodeWriter.java +++ b/src/main/java/com/squareup/javapoet/CodeWriter.java @@ -362,6 +362,11 @@ private void emitLiteral(Object o) throws IOException { annotationSpec.emit(this, true); } else if (o instanceof CodeBlock) { CodeBlock codeBlock = (CodeBlock) o; + CodeBlock.Builder builder = CodeBlock.builder(); + builder.formatParts.addAll(codeBlock.formatParts); + builder.args.addAll(codeBlock.args); + builder.formatParts.remove("$["); + builder.formatParts.remove("$]"); emit(codeBlock); } else { emitAndIndent(String.valueOf(o)); diff --git a/src/test/java/com/squareup/javapoet/CodeBlockTest.java b/src/test/java/com/squareup/javapoet/CodeBlockTest.java index 11b75fa4f..56c01d5eb 100644 --- a/src/test/java/com/squareup/javapoet/CodeBlockTest.java +++ b/src/test/java/com/squareup/javapoet/CodeBlockTest.java @@ -340,6 +340,36 @@ public final class CodeBlockTest { assertThat(joined.toString()).isEqualTo("start {\"hello\" || world.World || need tacos} end"); } + @Test public void NestCodeBlock(){ + CodeBlock inner = CodeBlock.builder() + .beginControlFlow("() ->") + .addStatement("return 42") + .endControlFlow() + .build(); + + CodeBlock outer = + CodeBlock.builder() + .add( + "$T lambda = $L;", + ParameterizedTypeName.get( + ClassName.get(ArrayList.class), ClassName.get(Integer.class)), + inner) + .build(); + assertThat(outer.toString()).isEqualTo("java.util.ArrayList lambda = () -> {\n" + + " return 42;\n" + + "}\n" + + ";"); + + } + @Test public void joiningWithDifferentSeparator() { + List codeBlocks = new ArrayList<>(); + codeBlocks.add(CodeBlock.of("$S", "hello")); + codeBlocks.add(CodeBlock.of("$T", ClassName.get("world", "World"))); + codeBlocks.add(CodeBlock.of("need tacos")); + CodeBlock info = CodeBlock.join(codeBlocks, new String[]{" || "," | "}); + + assertThat(info.toString()).isEqualTo("\"hello\" || world.World | need tacos"); + } @Test public void clear() { CodeBlock block = CodeBlock.builder() .addStatement("$S", "Test string")