diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanDefinitionMethodGenerator.java b/spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanDefinitionMethodGenerator.java index 13756a8fc6e..01c2ab71a7c 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanDefinitionMethodGenerator.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanDefinitionMethodGenerator.java @@ -164,11 +164,14 @@ class BeanDefinitionMethodGenerator { this.aotContributions.forEach(aotContribution -> aotContribution.applyTo(generationContext, codeGenerator)); + CodeWarnings codeWarnings = new CodeWarnings(); + codeWarnings.detectDeprecation(this.registeredBean.getBeanClass()); return generatedMethods.add("getBeanDefinition", method -> { method.addJavadoc("Get the $L definition for '$L'.", (this.registeredBean.isInnerBean() ? "inner-bean" : "bean"), getName()); method.addModifiers(modifier, Modifier.STATIC); + codeWarnings.suppress(method); method.returns(BeanDefinition.class); method.addCode(codeGenerator.generateCode(generationContext)); }); diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/aot/CodeWarnings.java b/spring-beans/src/main/java/org/springframework/beans/factory/aot/CodeWarnings.java new file mode 100644 index 00000000000..9912f445195 --- /dev/null +++ b/spring-beans/src/main/java/org/springframework/beans/factory/aot/CodeWarnings.java @@ -0,0 +1,125 @@ +/* + * Copyright 2002-2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.factory.aot; + +import java.lang.reflect.AnnotatedElement; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.Set; +import java.util.StringJoiner; +import java.util.stream.Stream; + +import org.springframework.javapoet.AnnotationSpec; +import org.springframework.javapoet.CodeBlock; +import org.springframework.javapoet.MethodSpec; +import org.springframework.lang.Nullable; + +/** + * Helper class to register warnings that the compiler may trigger on + * generated code. + * + * @author Stephane Nicoll + * @see SuppressWarnings + */ +class CodeWarnings { + + private final Set warnings = new LinkedHashSet<>(); + + /** + * Register a warning to be included for this block. Does nothing if + * the warning is already registered. + * @param warning the warning to register, if it hasn't been already + */ + public void register(String warning) { + this.warnings.add(warning); + } + + /** + * Detect the presence of {@link Deprecated} on the specified elements. + * @param elements the elements to check + * @return {@code this} instance + */ + public CodeWarnings detectDeprecation(AnnotatedElement... elements) { + for (AnnotatedElement element : elements) { + register(element.getAnnotation(Deprecated.class)); + } + return this; + } + + /** + * Detect the presence of {@link Deprecated} on the specified elements. + * @param elements the elements to check + * @return {@code this} instance + */ + public CodeWarnings detectDeprecation(Stream elements) { + elements.forEach(element -> register(element.getAnnotation(Deprecated.class))); + return this; + } + + /** + * Include a {@link SuppressWarnings} on the specified method if necessary. + * @param method the method to update + */ + public void suppress(MethodSpec.Builder method) { + if (this.warnings.isEmpty()) { + return; + } + method.addAnnotation(buildAnnotationSpec()); + } + + /** + * Return the currently registered warnings. + * @return the warnings + */ + protected Set getWarnings() { + return Collections.unmodifiableSet(this.warnings); + } + + private void register(@Nullable Deprecated annotation) { + if (annotation != null) { + if (annotation.forRemoval()) { + register("removal"); + } + else { + register("deprecation"); + } + } + } + + private AnnotationSpec buildAnnotationSpec() { + return AnnotationSpec.builder(SuppressWarnings.class) + .addMember("value", generateValueCode()).build(); + } + + private CodeBlock generateValueCode() { + if (this.warnings.size() == 1) { + return CodeBlock.of("$S", this.warnings.iterator().next()); + } + CodeBlock values = CodeBlock.join(this.warnings.stream() + .map(warning -> CodeBlock.of("$S", warning)).toList(), ", "); + return CodeBlock.of("{ $L }", values); + } + + @Override + public String toString() { + return new StringJoiner(", ", CodeWarnings.class.getSimpleName(), "") + .add(this.warnings.toString()) + .toString(); + } + +} + diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/aot/InstanceSupplierCodeGenerator.java b/spring-beans/src/main/java/org/springframework/beans/factory/aot/InstanceSupplierCodeGenerator.java index 87de98852ec..3087d8b481a 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/aot/InstanceSupplierCodeGenerator.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/aot/InstanceSupplierCodeGenerator.java @@ -21,6 +21,7 @@ import java.lang.reflect.Executable; import java.lang.reflect.Member; import java.lang.reflect.Method; import java.lang.reflect.Modifier; +import java.lang.reflect.Parameter; import java.lang.reflect.Proxy; import java.util.Arrays; import java.util.function.Consumer; @@ -189,11 +190,15 @@ public class InstanceSupplierCodeGenerator { private CodeBlock generateCodeForInaccessibleConstructor(String beanName, Class beanClass, Constructor constructor, boolean dependsOnBean, Consumer hints) { + CodeWarnings codeWarnings = new CodeWarnings(); + codeWarnings.detectDeprecation(beanClass, constructor) + .detectDeprecation(Arrays.stream(constructor.getParameters()).map(Parameter::getType)); hints.accept(this.generationContext.getRuntimeHints().reflection()); GeneratedMethod generatedMethod = generateGetInstanceSupplierMethod(method -> { method.addJavadoc("Get the bean instance supplier for '$L'.", beanName); method.addModifiers(PRIVATE_STATIC); + codeWarnings.suppress(method); method.returns(ParameterizedTypeName.get(BeanInstanceSupplier.class, beanClass)); int parameterOffset = (!dependsOnBean) ? 0 : 1; method.addStatement(generateResolverForConstructor(beanClass, constructor, parameterOffset)); @@ -206,8 +211,12 @@ public class InstanceSupplierCodeGenerator { String beanName, Class beanClass, Constructor constructor, Class declaringClass, boolean dependsOnBean, javax.lang.model.element.Modifier... modifiers) { + CodeWarnings codeWarnings = new CodeWarnings(); + codeWarnings.detectDeprecation(beanClass, constructor, declaringClass) + .detectDeprecation(Arrays.stream(constructor.getParameters()).map(Parameter::getType)); method.addJavadoc("Get the bean instance supplier for '$L'.", beanName); method.addModifiers(modifiers); + codeWarnings.suppress(method); method.returns(ParameterizedTypeName.get(BeanInstanceSupplier.class, beanClass)); int parameterOffset = (!dependsOnBean) ? 0 : 1; @@ -300,9 +309,13 @@ public class InstanceSupplierCodeGenerator { String factoryMethodName = factoryMethod.getName(); Class suppliedType = ClassUtils.resolvePrimitiveIfNecessary(factoryMethod.getReturnType()); + CodeWarnings codeWarnings = new CodeWarnings(); + codeWarnings.detectDeprecation(declaringClass, factoryMethod, suppliedType) + .detectDeprecation(Arrays.stream(factoryMethod.getParameters()).map(Parameter::getType)); method.addJavadoc("Get the bean instance supplier for '$L'.", beanName); method.addModifiers(modifiers); + codeWarnings.suppress(method); method.returns(ParameterizedTypeName.get(BeanInstanceSupplier.class, suppliedType)); CodeBlock.Builder code = CodeBlock.builder(); diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/aot/BeanDefinitionMethodGeneratorTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/aot/BeanDefinitionMethodGeneratorTests.java index 19a9b5fd07c..3dbcad3e149 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/aot/BeanDefinitionMethodGeneratorTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/aot/BeanDefinitionMethodGeneratorTests.java @@ -26,6 +26,7 @@ import java.util.function.Supplier; import javax.lang.model.element.Modifier; import javax.xml.parsers.DocumentBuilderFactory; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.aot.generate.GeneratedMethod; @@ -52,6 +53,7 @@ import org.springframework.beans.testfixture.beans.factory.aot.TestHierarchy; import org.springframework.beans.testfixture.beans.factory.aot.TestHierarchy.Implementation; import org.springframework.beans.testfixture.beans.factory.aot.TestHierarchy.One; import org.springframework.beans.testfixture.beans.factory.aot.TestHierarchy.Two; +import org.springframework.beans.testfixture.beans.factory.generator.deprecation.DeprecatedBean; import org.springframework.core.ResolvableType; import org.springframework.core.test.io.support.MockSpringFactoriesLoader; import org.springframework.core.test.tools.CompileWithForkedClassLoader; @@ -66,6 +68,7 @@ import org.springframework.util.ReflectionUtils; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalStateException; +import static org.assertj.core.api.Assertions.assertThatNoException; /** * Tests for {@link BeanDefinitionMethodGenerator} and @@ -740,6 +743,32 @@ class BeanDefinitionMethodGeneratorTests { }); } + @Nested + @SuppressWarnings("deprecation") + class DeprecationTests { + + private static final TestCompiler TEST_COMPILER = TestCompiler.forSystem() + .withCompilerOptions("-Xlint:all", "-Xlint:-rawtypes", "-Werror"); + + @Test + void generateBeanDefinitionMethodWithDeprecatedTargetClass() { + RootBeanDefinition beanDefinition = new RootBeanDefinition(DeprecatedBean.class); + RegisteredBean registeredBean = registerBean(beanDefinition); + BeanDefinitionMethodGenerator generator = new BeanDefinitionMethodGenerator( + methodGeneratorFactory, registeredBean, null, + Collections.emptyList()); + MethodReference method = generator.generateBeanDefinitionMethod( + generationContext, beanRegistrationsCode); + compileAndCheckWarnings(method); + } + + private void compileAndCheckWarnings(MethodReference methodReference) { + assertThatNoException().isThrownBy(() -> compile(TEST_COMPILER, methodReference, + ((instanceSupplier, compiled) -> {}))); + } + + } + private void testBeanDefinitionMethodInCurrentFile(Class targetType, RootBeanDefinition beanDefinition) { RegisteredBean registeredBean = registerBean(new RootBeanDefinition(beanDefinition)); BeanDefinitionMethodGenerator generator = new BeanDefinitionMethodGenerator( @@ -764,6 +793,10 @@ class BeanDefinitionMethodGeneratorTests { } private void compile(MethodReference method, BiConsumer result) { + compile(TestCompiler.forSystem(), method, result); + } + + private void compile(TestCompiler testCompiler, MethodReference method, BiConsumer result) { this.beanRegistrationsCode.getTypeBuilder().set(type -> { CodeBlock methodInvocation = method.toInvokeCodeBlock(ArgumentCodeGenerator.none(), this.beanRegistrationsCode.getClassName()); @@ -775,7 +808,7 @@ class BeanDefinitionMethodGeneratorTests { .addCode("return $L;", methodInvocation).build()); }); this.generationContext.writeGeneratedContent(); - TestCompiler.forSystem().with(this.generationContext).compile(compiled -> + testCompiler.with(this.generationContext).compile(compiled -> result.accept((RootBeanDefinition) compiled.getInstance(Supplier.class).get(), compiled)); } diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/aot/CodeWarningsTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/aot/CodeWarningsTests.java new file mode 100644 index 00000000000..365ae5ced2b --- /dev/null +++ b/spring-beans/src/test/java/org/springframework/beans/factory/aot/CodeWarningsTests.java @@ -0,0 +1,123 @@ +/* + * Copyright 2002-2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.factory.aot; + +import java.util.function.Consumer; + +import javax.lang.model.element.Modifier; + +import org.junit.jupiter.api.Test; + +import org.springframework.aot.test.generate.TestGenerationContext; +import org.springframework.beans.testfixture.beans.factory.aot.DeferredTypeBuilder; +import org.springframework.beans.testfixture.beans.factory.generator.deprecation.DeprecatedBean; +import org.springframework.beans.testfixture.beans.factory.generator.deprecation.DeprecatedForRemovalBean; +import org.springframework.core.test.tools.Compiled; +import org.springframework.core.test.tools.TestCompiler; +import org.springframework.javapoet.MethodSpec; +import org.springframework.javapoet.MethodSpec.Builder; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link CodeWarnings}. + * + * @author Stephane Nicoll + */ +class CodeWarningsTests { + + private static final TestCompiler TEST_COMPILER = TestCompiler.forSystem() + .withCompilerOptions("-Xlint:all", "-Werror"); + + private final CodeWarnings codeWarnings; + + private final TestGenerationContext generationContext; + + CodeWarningsTests() { + this.codeWarnings = new CodeWarnings(); + this.generationContext = new TestGenerationContext(); + } + + @Test + void registerNoWarningDoesNotIncludeAnnotation() { + compile(method -> { + this.codeWarnings.suppress(method); + method.addStatement("$T bean = $S", String.class, "Hello"); + }, compiled -> assertThat(compiled.getSourceFile()).doesNotContain("@SuppressWarnings")); + } + + @Test + @SuppressWarnings("deprecation") + void registerWarningSuppressesIt() { + this.codeWarnings.register("deprecation"); + compile(method -> { + this.codeWarnings.suppress(method); + method.addStatement("$T bean = new $T()", DeprecatedBean.class, DeprecatedBean.class); + }, compiled -> assertThat(compiled.getSourceFile()) + .contains("@SuppressWarnings(\"deprecation\")")); + } + + @Test + @SuppressWarnings({ "deprecation", "removal" }) + void registerSeveralWarningsSuppressesThem() { + this.codeWarnings.register("deprecation"); + this.codeWarnings.register("removal"); + compile(method -> { + this.codeWarnings.suppress(method); + method.addStatement("$T bean = new $T()", DeprecatedBean.class, DeprecatedBean.class); + method.addStatement("$T another = new $T()", DeprecatedForRemovalBean.class, DeprecatedForRemovalBean.class); + }, compiled -> assertThat(compiled.getSourceFile()) + .contains("@SuppressWarnings({ \"deprecation\", \"removal\" })")); + } + + @Test + @SuppressWarnings("deprecation") + void detectDeprecationOnAnnotatedElementWithDeprecated() { + this.codeWarnings.detectDeprecation(DeprecatedBean.class); + assertThat(this.codeWarnings.getWarnings()).containsExactly("deprecation"); + } + + @Test + @SuppressWarnings("removal") + void detectDeprecationOnAnnotatedElementWithDeprecatedForRemoval() { + this.codeWarnings.detectDeprecation(DeprecatedForRemovalBean.class); + assertThat(this.codeWarnings.getWarnings()).containsExactly("removal"); + } + + @Test + void toStringIncludeWarnings() { + this.codeWarnings.register("deprecation"); + this.codeWarnings.register("rawtypes"); + assertThat(this.codeWarnings).hasToString("CodeWarnings[deprecation, rawtypes]"); + } + + private void compile(Consumer method, + Consumer result) { + DeferredTypeBuilder typeBuilder = new DeferredTypeBuilder(); + this.generationContext.getGeneratedClasses().addForFeature("TestCode", typeBuilder); + typeBuilder.set(type -> { + type.addModifiers(Modifier.PUBLIC); + Builder methodBuilder = MethodSpec.methodBuilder("apply") + .addModifiers(Modifier.PUBLIC); + method.accept(methodBuilder); + type.addMethod(methodBuilder.build()); + }); + this.generationContext.writeGeneratedContent(); + TEST_COMPILER.with(this.generationContext).compile(result); + } + +} diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/aot/InstanceSupplierCodeGeneratorTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/aot/InstanceSupplierCodeGeneratorTests.java index 370e318bc44..5e166745de6 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/aot/InstanceSupplierCodeGeneratorTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/aot/InstanceSupplierCodeGeneratorTests.java @@ -23,6 +23,8 @@ import java.util.function.Supplier; import javax.lang.model.element.Modifier; import org.assertj.core.api.ThrowingConsumer; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.aot.generate.GeneratedClass; @@ -44,6 +46,12 @@ import org.springframework.beans.testfixture.beans.factory.generator.InnerCompon import org.springframework.beans.testfixture.beans.factory.generator.InnerComponentConfiguration.EnvironmentAwareComponent; import org.springframework.beans.testfixture.beans.factory.generator.InnerComponentConfiguration.NoDependencyComponent; import org.springframework.beans.testfixture.beans.factory.generator.SimpleConfiguration; +import org.springframework.beans.testfixture.beans.factory.generator.deprecation.DeprecatedBean; +import org.springframework.beans.testfixture.beans.factory.generator.deprecation.DeprecatedConstructor; +import org.springframework.beans.testfixture.beans.factory.generator.deprecation.DeprecatedForRemovalBean; +import org.springframework.beans.testfixture.beans.factory.generator.deprecation.DeprecatedForRemovalConstructor; +import org.springframework.beans.testfixture.beans.factory.generator.deprecation.DeprecatedForRemovalMemberConfiguration; +import org.springframework.beans.testfixture.beans.factory.generator.deprecation.DeprecatedMemberConfiguration; import org.springframework.beans.testfixture.beans.factory.generator.factory.NumberHolder; import org.springframework.beans.testfixture.beans.factory.generator.factory.NumberHolderFactoryBean; import org.springframework.beans.testfixture.beans.factory.generator.factory.SampleFactory; @@ -57,6 +65,7 @@ import org.springframework.javapoet.ParameterizedTypeName; import org.springframework.util.ReflectionUtils; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatNoException; /** * Tests for {@link InstanceSupplierCodeGenerator}. @@ -261,6 +270,108 @@ class InstanceSupplierCodeGeneratorTests { .satisfies(hasMethodWithMode(ExecutableMode.INTROSPECT)); } + @Nested + @SuppressWarnings("deprecation") + class DeprecationTests { + + private static final TestCompiler TEST_COMPILER = TestCompiler.forSystem() + .withCompilerOptions("-Xlint:all", "-Xlint:-rawtypes", "-Werror"); + + @Test + @Disabled("Need to move to a separate method so that the warning can be suppressed") + void generateWhenTargetClassIsDeprecated() { + compileAndCheckWarnings(new RootBeanDefinition(DeprecatedBean.class)); + } + + @Test + void generateWhenTargetConstructorIsDeprecated() { + compileAndCheckWarnings(new RootBeanDefinition(DeprecatedConstructor.class)); + } + + @Test + void generateWhenTargetFactoryMethodIsDeprecated() { + BeanDefinition beanDefinition = BeanDefinitionBuilder + .rootBeanDefinition(String.class) + .setFactoryMethodOnBean("deprecatedString", "config").getBeanDefinition(); + beanFactory.registerBeanDefinition("config", BeanDefinitionBuilder + .genericBeanDefinition(DeprecatedMemberConfiguration.class).getBeanDefinition()); + compileAndCheckWarnings(beanDefinition); + } + + @Test + void generateWhenTargetFactoryMethodParameterIsDeprecated() { + BeanDefinition beanDefinition = BeanDefinitionBuilder + .rootBeanDefinition(String.class) + .setFactoryMethodOnBean("deprecatedParameter", "config").getBeanDefinition(); + beanFactory.registerBeanDefinition("config", BeanDefinitionBuilder + .genericBeanDefinition(DeprecatedMemberConfiguration.class).getBeanDefinition()); + beanFactory.registerBeanDefinition("parameter", new RootBeanDefinition(DeprecatedBean.class)); + compileAndCheckWarnings(beanDefinition); + } + + @Test + void generateWhenTargetFactoryMethodReturnTypeIsDeprecated() { + BeanDefinition beanDefinition = BeanDefinitionBuilder + .rootBeanDefinition(DeprecatedBean.class) + .setFactoryMethodOnBean("deprecatedReturnType", "config").getBeanDefinition(); + beanFactory.registerBeanDefinition("config", BeanDefinitionBuilder + .genericBeanDefinition(DeprecatedMemberConfiguration.class).getBeanDefinition()); + compileAndCheckWarnings(beanDefinition); + } + + private void compileAndCheckWarnings(BeanDefinition beanDefinition) { + assertThatNoException().isThrownBy(() -> compile(TEST_COMPILER, beanDefinition, + ((instanceSupplier, compiled) -> {}))); + } + + } + + @Nested + @SuppressWarnings("removal") + class DeprecationForRemovalTests { + + private static final TestCompiler TEST_COMPILER = TestCompiler.forSystem() + .withCompilerOptions("-Xlint:all", "-Xlint:-rawtypes", "-Werror"); + + @Test + @Disabled("Need to move to a separate method so that the warning can be suppressed") + void generateWhenTargetClassIsDeprecatedForRemoval() { + compileAndCheckWarnings(new RootBeanDefinition(DeprecatedForRemovalBean.class)); + } + + @Test + void generateWhenTargetConstructorIsDeprecatedForRemoval() { + compileAndCheckWarnings(new RootBeanDefinition(DeprecatedForRemovalConstructor.class)); + } + + @Test + void generateWhenTargetFactoryMethodIsDeprecatedForRemoval() { + BeanDefinition beanDefinition = BeanDefinitionBuilder + .rootBeanDefinition(String.class) + .setFactoryMethodOnBean("deprecatedString", "config").getBeanDefinition(); + beanFactory.registerBeanDefinition("config", BeanDefinitionBuilder + .genericBeanDefinition(DeprecatedForRemovalMemberConfiguration.class).getBeanDefinition()); + compileAndCheckWarnings(beanDefinition); + } + + @Test + void generateWhenTargetFactoryMethodParameterIsDeprecatedForRemoval() { + BeanDefinition beanDefinition = BeanDefinitionBuilder + .rootBeanDefinition(String.class) + .setFactoryMethodOnBean("deprecatedParameter", "config").getBeanDefinition(); + beanFactory.registerBeanDefinition("config", BeanDefinitionBuilder + .genericBeanDefinition(DeprecatedForRemovalMemberConfiguration.class).getBeanDefinition()); + beanFactory.registerBeanDefinition("parameter", new RootBeanDefinition(DeprecatedForRemovalBean.class)); + compileAndCheckWarnings(beanDefinition); + } + + private void compileAndCheckWarnings(BeanDefinition beanDefinition) { + assertThatNoException().isThrownBy(() -> compile(TEST_COMPILER, beanDefinition, + ((instanceSupplier, compiled) -> {}))); + } + + } + private ReflectionHints getReflectionHints() { return this.generationContext.getRuntimeHints().reflection(); } @@ -285,6 +396,11 @@ class InstanceSupplierCodeGeneratorTests { } private void compile(BeanDefinition beanDefinition, BiConsumer, Compiled> result) { + compile(TestCompiler.forSystem(), beanDefinition, result); + } + + private void compile(TestCompiler testCompiler, BeanDefinition beanDefinition, + BiConsumer, Compiled> result) { DefaultListableBeanFactory freshBeanFactory = new DefaultListableBeanFactory(this.beanFactory); freshBeanFactory.registerBeanDefinition("testBean", beanDefinition); @@ -306,8 +422,8 @@ class InstanceSupplierCodeGeneratorTests { .addStatement("return $L", generatedCode).build()); }); this.generationContext.writeGeneratedContent(); - TestCompiler.forSystem().with(this.generationContext).compile(compiled -> - result.accept((InstanceSupplier) compiled.getInstance(Supplier.class).get(), compiled)); + testCompiler.with(this.generationContext).compile(compiled -> result.accept( + (InstanceSupplier) compiled.getInstance(Supplier.class).get(), compiled)); } } diff --git a/spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/deprecation/DeprecatedBean.java b/spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/deprecation/DeprecatedBean.java new file mode 100644 index 00000000000..7cad80f3ffb --- /dev/null +++ b/spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/deprecation/DeprecatedBean.java @@ -0,0 +1,27 @@ +/* + * Copyright 2002-2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.testfixture.beans.factory.generator.deprecation; + +/** + * A sample bean that's fully deprecated. + * + * @author Stephane Nicoll + */ +@Deprecated +public class DeprecatedBean { +} + diff --git a/spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/deprecation/DeprecatedConstructor.java b/spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/deprecation/DeprecatedConstructor.java new file mode 100644 index 00000000000..ca4ca987cb3 --- /dev/null +++ b/spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/deprecation/DeprecatedConstructor.java @@ -0,0 +1,34 @@ +/* + * Copyright 2002-2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.testfixture.beans.factory.generator.deprecation; + +import org.springframework.core.env.Environment; + +/** + * A sample whose factory method (constructor) is deprecated. + * + * @author Stephane Nicoll + */ +public class DeprecatedConstructor { + + @Deprecated + public DeprecatedConstructor(Environment environment) { + + } + +} + diff --git a/spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/deprecation/DeprecatedForRemovalBean.java b/spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/deprecation/DeprecatedForRemovalBean.java new file mode 100644 index 00000000000..cb11be7017c --- /dev/null +++ b/spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/deprecation/DeprecatedForRemovalBean.java @@ -0,0 +1,27 @@ +/* + * Copyright 2002-2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.testfixture.beans.factory.generator.deprecation; + +/** + * A sample bean that's fully deprecated for removal. + * + * @author Stephane Nicoll + */ +@Deprecated(forRemoval = true) +public class DeprecatedForRemovalBean { +} + diff --git a/spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/deprecation/DeprecatedForRemovalConstructor.java b/spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/deprecation/DeprecatedForRemovalConstructor.java new file mode 100644 index 00000000000..7b4047e2e04 --- /dev/null +++ b/spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/deprecation/DeprecatedForRemovalConstructor.java @@ -0,0 +1,34 @@ +/* + * Copyright 2002-2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.testfixture.beans.factory.generator.deprecation; + +import org.springframework.core.env.Environment; + +/** + * A sample whose factory method (constructor) is deprecated for removal + * + * @author Stephane Nicoll + */ +public class DeprecatedForRemovalConstructor { + + @Deprecated(forRemoval = true) + public DeprecatedForRemovalConstructor(Environment environment) { + + } + +} + diff --git a/spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/deprecation/DeprecatedForRemovalMemberConfiguration.java b/spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/deprecation/DeprecatedForRemovalMemberConfiguration.java new file mode 100644 index 00000000000..577fbf83ac7 --- /dev/null +++ b/spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/deprecation/DeprecatedForRemovalMemberConfiguration.java @@ -0,0 +1,36 @@ +/* + * Copyright 2002-2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.testfixture.beans.factory.generator.deprecation; + +/** + * A class with deprecated members for removal to test various use cases. + * + * @author Stephane Nicoll + */ +public class DeprecatedForRemovalMemberConfiguration { + + @Deprecated(forRemoval = true) + public String deprecatedString() { + return "deprecated"; + } + + public String deprecatedParameter(DeprecatedForRemovalBean bean) { + return bean.toString(); + } + +} + diff --git a/spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/deprecation/DeprecatedMemberConfiguration.java b/spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/deprecation/DeprecatedMemberConfiguration.java new file mode 100644 index 00000000000..96ca7add31c --- /dev/null +++ b/spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/generator/deprecation/DeprecatedMemberConfiguration.java @@ -0,0 +1,40 @@ +/* + * Copyright 2002-2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.beans.testfixture.beans.factory.generator.deprecation; + +/** + * A class with deprecated members to test various use cases. + * + * @author Stephane Nicoll + */ +public class DeprecatedMemberConfiguration { + + @Deprecated + public String deprecatedString() { + return "deprecated"; + } + + public String deprecatedParameter(DeprecatedBean bean) { + return bean.toString(); + } + + public DeprecatedBean deprecatedReturnType() { + return new DeprecatedBean(); + } + +} +