diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/generator/BeanRegistrationBeanFactoryContribution.java b/spring-beans/src/main/java/org/springframework/beans/factory/generator/BeanRegistrationBeanFactoryContribution.java index 7caf9214289..265b6eb429b 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/generator/BeanRegistrationBeanFactoryContribution.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/generator/BeanRegistrationBeanFactoryContribution.java @@ -345,7 +345,7 @@ public class BeanRegistrationBeanFactoryContribution implements BeanFactoryContr } code.add("\n").indent().indent(); code.add(".instanceSupplier("); - code.add(instanceStatements.toCodeBlock()); + code.add(instanceStatements.toLambdaBody()); code.add(")").unindent().unindent(); handleBeanDefinitionMetadata(code); } @@ -421,7 +421,7 @@ public class BeanRegistrationBeanFactoryContribution implements BeanFactoryContr if (statements.isEmpty()) { return; } - code.add(statements.toCodeBlock(".customize((" + bdVariable + ") ->")); + code.add(statements.toLambdaBody(".customize((" + bdVariable + ") ->")); code.add(")"); } diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanInstantiationContributorTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanInstantiationContributorTests.java index c43e1dd5243..d48d5a71c61 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanInstantiationContributorTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanInstantiationContributorTests.java @@ -43,7 +43,7 @@ class AutowiredAnnotationBeanInstantiationContributionTests { @Test void contributeWithPackageProtectedFieldInjection() { CodeContribution contribution = contribute(PackageProtectedFieldInjectionSample.class); - assertThat(CodeSnippet.process(contribution.statements().toCodeBlock())).isEqualTo(""" + assertThat(CodeSnippet.process(contribution.statements().toLambdaBody())).isEqualTo(""" instanceContext.field("environment") .invoke(beanFactory, (attributes) -> bean.environment = attributes.get(0))"""); assertThat(contribution.runtimeHints().reflection().typeHints()).singleElement().satisfies(typeHint -> { @@ -61,7 +61,7 @@ class AutowiredAnnotationBeanInstantiationContributionTests { @Test void contributeWithPrivateFieldInjection() { CodeContribution contribution = contribute(PrivateFieldInjectionSample.class); - assertThat(CodeSnippet.process(contribution.statements().toCodeBlock())).isEqualTo(""" + assertThat(CodeSnippet.process(contribution.statements().toLambdaBody())).isEqualTo(""" instanceContext.field("environment") .invoke(beanFactory, (attributes) -> { Field environmentField = ReflectionUtils.findField(AutowiredAnnotationBeanInstantiationContributionTests.PrivateFieldInjectionSample.class, "environment"); @@ -82,7 +82,7 @@ class AutowiredAnnotationBeanInstantiationContributionTests { @Test void contributeWithPublicMethodInjection() { CodeContribution contribution = contribute(PublicMethodInjectionSample.class); - assertThat(CodeSnippet.process(contribution.statements().toCodeBlock())).isEqualTo(""" + assertThat(CodeSnippet.process(contribution.statements().toLambdaBody())).isEqualTo(""" instanceContext.method("setTestBean", TestBean.class) .invoke(beanFactory, (attributes) -> bean.setTestBean(attributes.get(0)))"""); assertThat(contribution.runtimeHints().reflection().typeHints()).singleElement().satisfies(typeHint -> { @@ -98,7 +98,7 @@ class AutowiredAnnotationBeanInstantiationContributionTests { @Test void contributeWithInjectionPoints() { CodeContribution contribution = contribute(ResourceInjectionBean.class); - assertThat(CodeSnippet.process(contribution.statements().toCodeBlock())).isEqualTo(""" + assertThat(CodeSnippet.process(contribution.statements().toLambdaBody())).isEqualTo(""" instanceContext.field("testBean") .resolve(beanFactory, false).ifResolved((attributes) -> { Field testBeanField = ReflectionUtils.findField(AutowiredAnnotationBeanPostProcessorTests.ResourceInjectionBean.class, "testBean"); diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/generator/DefaultBeanInstantiationGeneratorTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/generator/DefaultBeanInstantiationGeneratorTests.java index 11d9481654f..2b2a28f0941 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/generator/DefaultBeanInstantiationGeneratorTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/generator/DefaultBeanInstantiationGeneratorTests.java @@ -209,7 +209,7 @@ class DefaultBeanInstantiationGeneratorTests { } private String code(CodeContribution contribution) { - return CodeSnippet.process(contribution.statements().toCodeBlock()); + return CodeSnippet.process(contribution.statements().toLambdaBody()); } @Nullable diff --git a/spring-core/src/main/java/org/springframework/javapoet/support/MultiStatement.java b/spring-core/src/main/java/org/springframework/javapoet/support/MultiStatement.java index 2442b858500..2fbf56df1c6 100644 --- a/spring-core/src/main/java/org/springframework/javapoet/support/MultiStatement.java +++ b/spring-core/src/main/java/org/springframework/javapoet/support/MultiStatement.java @@ -116,13 +116,24 @@ public final class MultiStatement { return this; } + /** + * Return a {@link CodeBlock} that applies all the {@code statements} of + * this instance. + * @return the code block + */ + public CodeBlock toCodeBlock() { + Builder code = CodeBlock.builder(); + this.statements.forEach(statement -> statement.add(code)); + return code.build(); + } + /** * Return a {@link CodeBlock} that applies all the {@code statements} of this * instance. If only one statement is available, it is not completed using the * {@code ;} termination so that it can be used in the context of a lambda. * @return the statement(s) */ - public CodeBlock toCodeBlock() { + public CodeBlock toLambdaBody() { Builder code = CodeBlock.builder(); for (int i = 0; i < this.statements.size(); i++) { Statement statement = this.statements.get(i); @@ -137,7 +148,7 @@ public final class MultiStatement { * @param lambda the context of the lambda, must end with {@code ->} * @return the lambda body */ - public CodeBlock toCodeBlock(CodeBlock lambda) { + public CodeBlock toLambdaBody(CodeBlock lambda) { Builder code = CodeBlock.builder(); code.add(lambda); if (isMulti()) { @@ -146,7 +157,7 @@ public final class MultiStatement { else { code.add(" "); } - code.add(toCodeBlock()); + code.add(toLambdaBody()); if (isMulti()) { code.add("\n").unindent().add("}"); } @@ -159,8 +170,8 @@ public final class MultiStatement { * @param lambda the context of the lambda, must end with {@code ->} * @return the lambda body */ - public CodeBlock toCodeBlock(String lambda) { - return toCodeBlock(CodeBlock.of(lambda)); + public CodeBlock toLambdaBody(String lambda) { + return toLambdaBody(CodeBlock.of(lambda)); } private boolean isMulti() { @@ -179,6 +190,13 @@ public final class MultiStatement { this.addStatementTermination = addStatementTermination; } + void add(CodeBlock.Builder code) { + code.add(this.codeBlock); + if (this.addStatementTermination) { + code.add(";\n"); + } + } + void contribute(CodeBlock.Builder code, boolean multi, boolean isLastStatement) { code.add(this.codeBlock); if (this.addStatementTermination) { diff --git a/spring-core/src/test/java/org/springframework/javapoet/support/MultiStatementTests.java b/spring-core/src/test/java/org/springframework/javapoet/support/MultiStatementTests.java index da766c523cc..fdbd0503461 100644 --- a/spring-core/src/test/java/org/springframework/javapoet/support/MultiStatementTests.java +++ b/spring-core/src/test/java/org/springframework/javapoet/support/MultiStatementTests.java @@ -44,48 +44,70 @@ class MultiStatementTests { } @Test - void singleStatement() { + void singleStatementCodeBlock() { MultiStatement statements = new MultiStatement(); statements.addStatement("field.method($S)", "hello"); CodeBlock codeBlock = statements.toCodeBlock(); + assertThat(codeBlock.toString()).isEqualTo(""" + field.method("hello"); + """); + } + + @Test + void multiStatementsCodeBlock() { + MultiStatement statements = new MultiStatement(); + statements.addStatement("field.method($S)", "hello"); + statements.addStatement("field.another($S)", "test"); + CodeBlock codeBlock = statements.toCodeBlock(); + assertThat(codeBlock.toString()).isEqualTo(""" + field.method("hello"); + field.another("test"); + """); + } + + @Test + void singleStatementLambdaBody() { + MultiStatement statements = new MultiStatement(); + statements.addStatement("field.method($S)", "hello"); + CodeBlock codeBlock = statements.toLambdaBody(); assertThat(codeBlock.toString()).isEqualTo("field.method(\"hello\")"); } @Test - void singleStatementWithCallback() { + void singleStatementWithCallbackLambdaBody() { MultiStatement statements = new MultiStatement(); statements.addStatement(code -> code.add("field.method($S)", "hello")); - CodeBlock codeBlock = statements.toCodeBlock(); + CodeBlock codeBlock = statements.toLambdaBody(); assertThat(codeBlock.toString()).isEqualTo("field.method(\"hello\")"); } @Test - void singleStatementWithCodeBlock() { + void singleStatementWithCodeBlockLambdaBody() { MultiStatement statements = new MultiStatement(); statements.addStatement(CodeBlock.of("field.method($S)", "hello")); - CodeBlock codeBlock = statements.toCodeBlock(); + CodeBlock codeBlock = statements.toLambdaBody(); assertThat(codeBlock.toString()).isEqualTo("field.method(\"hello\")"); } @Test - void multiStatements() { + void multiStatementsLambdaBody() { MultiStatement statements = new MultiStatement(); statements.addStatement("field.method($S)", "hello"); statements.addStatement("field.anotherMethod($S)", "hello"); - CodeBlock codeBlock = statements.toCodeBlock(); + CodeBlock codeBlock = statements.toLambdaBody(); assertThat(codeBlock.toString()).isEqualTo(""" field.method("hello"); field.anotherMethod("hello");"""); } @Test - void multiStatementsWithCodeBlockRenderedAsIs() { + void multiStatementsWithCodeBlockRenderedAsIsLambdaBody() { MultiStatement statements = new MultiStatement(); statements.addStatement("field.method($S)", "hello"); statements.add(CodeBlock.of(("// Hello\n"))); statements.add(code -> code.add("// World\n")); statements.addStatement("field.anotherMethod($S)", "hello"); - CodeBlock codeBlock = statements.toCodeBlock(); + CodeBlock codeBlock = statements.toLambdaBody(); assertThat(codeBlock.toString()).isEqualTo(""" field.method("hello"); // Hello @@ -97,7 +119,7 @@ class MultiStatementTests { void singleStatementWithLambda() { MultiStatement statements = new MultiStatement(); statements.addStatement("field.method($S)", "hello"); - CodeBlock codeBlock = statements.toCodeBlock(CodeBlock.of("() ->")); + CodeBlock codeBlock = statements.toLambdaBody(CodeBlock.of("() ->")); assertThat(codeBlock.toString()).isEqualTo("() -> field.method(\"hello\")"); } @@ -106,7 +128,7 @@ class MultiStatementTests { MultiStatement statements = new MultiStatement(); statements.addStatement("field.method($S)", "hello"); statements.addStatement("field.anotherMethod($S)", "hello"); - CodeBlock codeBlock = statements.toCodeBlock(CodeBlock.of("() ->")); + CodeBlock codeBlock = statements.toLambdaBody(CodeBlock.of("() ->")); assertThat(codeBlock.toString().lines()).containsExactly( "() -> {", " field.method(\"hello\");", @@ -115,11 +137,11 @@ class MultiStatementTests { } @Test - void multiStatementsWithAddAll() { + void multiStatementsWithAddAllAndLambda() { MultiStatement statements = new MultiStatement(); statements.addAll(List.of(0, 1, 2), index -> CodeBlock.of("field[$L] = $S", index, "hello")); - CodeBlock codeBlock = statements.toCodeBlock("() ->"); + CodeBlock codeBlock = statements.toLambdaBody("() ->"); assertThat(codeBlock.toString().lines()).containsExactly( "() -> {", " field[0] = \"hello\";",