Detect use of deprecated API
This commit is a best effort attempt at identifying the members that code generation invokes and might be deprecated. It introduces a CodeWarnings helper class that records warnings, with special handling for `@Deprecated`. See gh-29597
This commit is contained in:
parent
35372e5e72
commit
ea66883d79
|
|
@ -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));
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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<String> 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<AnnotatedElement> 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<String> 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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -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<ReflectionHints> 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();
|
||||
|
|
|
|||
|
|
@ -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<RootBeanDefinition, Compiled> result) {
|
||||
compile(TestCompiler.forSystem(), method, result);
|
||||
}
|
||||
|
||||
private void compile(TestCompiler testCompiler, MethodReference method, BiConsumer<RootBeanDefinition, Compiled> 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));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<Builder> method,
|
||||
Consumer<Compiled> 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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<InstanceSupplier<?>, Compiled> result) {
|
||||
compile(TestCompiler.forSystem(), beanDefinition, result);
|
||||
}
|
||||
|
||||
private void compile(TestCompiler testCompiler, BeanDefinition beanDefinition,
|
||||
BiConsumer<InstanceSupplier<?>, 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));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
}
|
||||
|
||||
|
|
@ -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) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -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 {
|
||||
}
|
||||
|
||||
|
|
@ -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) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue