Suppress deprecated warnings for autowiring
This commit extends our handling of deprecated with AOT to autowiring. Closes gh-33295
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2024 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.
|
||||
@@ -21,6 +21,7 @@ import java.util.function.BiFunction;
|
||||
|
||||
import javax.lang.model.element.Modifier;
|
||||
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.aot.generate.MethodReference;
|
||||
@@ -28,9 +29,17 @@ import org.springframework.aot.generate.MethodReference.ArgumentCodeGenerator;
|
||||
import org.springframework.aot.hint.predicate.RuntimeHintsPredicates;
|
||||
import org.springframework.aot.test.generate.TestGenerationContext;
|
||||
import org.springframework.beans.factory.aot.BeanRegistrationAotContribution;
|
||||
import org.springframework.beans.factory.aot.CodeWarnings;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.RegisteredBean;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.beans.testfixture.beans.factory.annotation.DeprecatedInjectionSamples.DeprecatedFieldInjectionPointSample;
|
||||
import org.springframework.beans.testfixture.beans.factory.annotation.DeprecatedInjectionSamples.DeprecatedFieldInjectionTypeSample;
|
||||
import org.springframework.beans.testfixture.beans.factory.annotation.DeprecatedInjectionSamples.DeprecatedMethodInjectionPointSample;
|
||||
import org.springframework.beans.testfixture.beans.factory.annotation.DeprecatedInjectionSamples.DeprecatedMethodInjectionTypeSample;
|
||||
import org.springframework.beans.testfixture.beans.factory.annotation.DeprecatedInjectionSamples.DeprecatedPrivateFieldInjectionTypeSample;
|
||||
import org.springframework.beans.testfixture.beans.factory.annotation.DeprecatedInjectionSamples.DeprecatedPrivateMethodInjectionTypeSample;
|
||||
import org.springframework.beans.testfixture.beans.factory.annotation.DeprecatedInjectionSamples.DeprecatedSample;
|
||||
import org.springframework.beans.testfixture.beans.factory.annotation.PackagePrivateFieldInjectionSample;
|
||||
import org.springframework.beans.testfixture.beans.factory.annotation.PackagePrivateMethodInjectionSample;
|
||||
import org.springframework.beans.testfixture.beans.factory.annotation.PrivateFieldInjectionSample;
|
||||
@@ -49,6 +58,7 @@ import org.springframework.javapoet.MethodSpec;
|
||||
import org.springframework.javapoet.ParameterizedTypeName;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatNoException;
|
||||
|
||||
/**
|
||||
* Tests for {@link AutowiredAnnotationBeanPostProcessor} for AOT contributions.
|
||||
@@ -199,6 +209,69 @@ class AutowiredAnnotationBeanRegistrationAotContributionTests {
|
||||
assertThat(contribution).isNull();
|
||||
}
|
||||
|
||||
@Nested
|
||||
@SuppressWarnings("deprecation")
|
||||
class DeprecationTests {
|
||||
|
||||
private static final TestCompiler TEST_COMPILER = TestCompiler.forSystem()
|
||||
.withCompilerOptions("-Xlint:all", "-Xlint:-rawtypes", "-Werror");
|
||||
|
||||
@Test
|
||||
void contributeWhenTargetClassIsDeprecated() {
|
||||
RegisteredBean registeredBean = getAndApplyContribution(DeprecatedSample.class);
|
||||
compileAndCheckWarnings(registeredBean);
|
||||
}
|
||||
|
||||
@Test
|
||||
void contributeWhenFieldInjectionsUsesADeprecatedType() {
|
||||
RegisteredBean registeredBean = getAndApplyContribution(
|
||||
DeprecatedFieldInjectionTypeSample.class);
|
||||
compileAndCheckWarnings(registeredBean);
|
||||
}
|
||||
|
||||
@Test
|
||||
void contributeWhenFieldInjectionsUsesADeprecatedTypeWithReflection() {
|
||||
RegisteredBean registeredBean = getAndApplyContribution(
|
||||
DeprecatedPrivateFieldInjectionTypeSample.class);
|
||||
compileAndCheckWarnings(registeredBean);
|
||||
}
|
||||
|
||||
@Test
|
||||
void contributeWhenFieldInjectionsIsDeprecated() {
|
||||
RegisteredBean registeredBean = getAndApplyContribution(
|
||||
DeprecatedFieldInjectionPointSample.class);
|
||||
compileAndCheckWarnings(registeredBean);
|
||||
}
|
||||
|
||||
@Test
|
||||
void contributeWhenMethodInjectionsUsesADeprecatedType() {
|
||||
RegisteredBean registeredBean = getAndApplyContribution(
|
||||
DeprecatedMethodInjectionTypeSample.class);
|
||||
compileAndCheckWarnings(registeredBean);
|
||||
}
|
||||
|
||||
@Test
|
||||
void contributeWhenMethodInjectionsUsesADeprecatedTypeWithReflection() {
|
||||
RegisteredBean registeredBean = getAndApplyContribution(
|
||||
DeprecatedPrivateMethodInjectionTypeSample.class);
|
||||
compileAndCheckWarnings(registeredBean);
|
||||
}
|
||||
|
||||
@Test
|
||||
void contributeWhenMethodInjectionsIsDeprecated() {
|
||||
RegisteredBean registeredBean = getAndApplyContribution(
|
||||
DeprecatedMethodInjectionPointSample.class);
|
||||
compileAndCheckWarnings(registeredBean);
|
||||
}
|
||||
|
||||
|
||||
private void compileAndCheckWarnings(RegisteredBean registeredBean) {
|
||||
assertThatNoException().isThrownBy(() -> compile(TEST_COMPILER, registeredBean,
|
||||
((instanceSupplier, compiled) -> {})));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private RegisteredBean getAndApplyContribution(Class<?> beanClass) {
|
||||
RegisteredBean registeredBean = registerBean(beanClass);
|
||||
BeanRegistrationAotContribution contribution = this.beanPostProcessor.processAheadOfTime(registeredBean);
|
||||
@@ -218,11 +291,17 @@ class AutowiredAnnotationBeanRegistrationAotContributionTests {
|
||||
return compiled.getSourceFileFromPackage(sample.getPackageName());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void compile(RegisteredBean registeredBean,
|
||||
BiConsumer<BiFunction<RegisteredBean, Object, Object>, Compiled> result) {
|
||||
compile(TestCompiler.forSystem(), registeredBean, result);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void compile(TestCompiler testCompiler, RegisteredBean registeredBean,
|
||||
BiConsumer<BiFunction<RegisteredBean, Object, Object>, Compiled> result) {
|
||||
Class<?> target = registeredBean.getBeanClass();
|
||||
MethodReference methodReference = this.beanRegistrationCode.getInstancePostProcessors().get(0);
|
||||
CodeWarnings codeWarnings = new CodeWarnings();
|
||||
this.beanRegistrationCode.getTypeBuilder().set(type -> {
|
||||
CodeBlock methodInvocation = methodReference.toInvokeCodeBlock(
|
||||
ArgumentCodeGenerator.of(RegisteredBean.class, "registeredBean").and(target, "instance"),
|
||||
@@ -235,10 +314,11 @@ class AutowiredAnnotationBeanRegistrationAotContributionTests {
|
||||
.addParameter(target, "instance").returns(target)
|
||||
.addStatement("return $L", methodInvocation)
|
||||
.build());
|
||||
|
||||
codeWarnings.detectDeprecation(target);
|
||||
codeWarnings.suppress(type);
|
||||
});
|
||||
this.generationContext.writeGeneratedContent();
|
||||
TestCompiler.forSystem().with(this.generationContext).compile(compiled ->
|
||||
testCompiler.with(this.generationContext).printFiles(System.out).compile(compiled ->
|
||||
result.accept(compiled.getInstance(BiFunction.class), compiled));
|
||||
}
|
||||
|
||||
|
||||
@@ -34,8 +34,10 @@ import org.springframework.beans.testfixture.beans.factory.generator.deprecation
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.test.tools.Compiled;
|
||||
import org.springframework.core.test.tools.TestCompiler;
|
||||
import org.springframework.javapoet.FieldSpec;
|
||||
import org.springframework.javapoet.MethodSpec;
|
||||
import org.springframework.javapoet.MethodSpec.Builder;
|
||||
import org.springframework.javapoet.TypeSpec;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -59,30 +61,49 @@ class CodeWarningsTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void registerNoWarningDoesNotIncludeAnnotation() {
|
||||
compile(method -> {
|
||||
void registerNoWarningDoesNotIncludeAnnotationOnMethod() {
|
||||
compileWithMethod(method -> {
|
||||
this.codeWarnings.suppress(method);
|
||||
method.addStatement("$T bean = $S", String.class, "Hello");
|
||||
}, compiled -> assertThat(compiled.getSourceFile()).doesNotContain("@SuppressWarnings"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void registerNoWarningDoesNotIncludeAnnotationOnType() {
|
||||
compile(type -> {
|
||||
this.codeWarnings.suppress(type);
|
||||
type.addField(FieldSpec.builder(String.class, "type").build());
|
||||
}, compiled -> assertThat(compiled.getSourceFile()).doesNotContain("@SuppressWarnings"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("deprecation")
|
||||
void registerWarningSuppressesIt() {
|
||||
void registerWarningSuppressesItOnMethod() {
|
||||
this.codeWarnings.register("deprecation");
|
||||
compile(method -> {
|
||||
compileWithMethod(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")
|
||||
void registerWarningSuppressesItOnType() {
|
||||
this.codeWarnings.register("deprecation");
|
||||
compile(type -> {
|
||||
this.codeWarnings.suppress(type);
|
||||
type.addField(FieldSpec.builder(DeprecatedBean.class, "bean").build());
|
||||
}, compiled -> assertThat(compiled.getSourceFile())
|
||||
.contains("@SuppressWarnings(\"deprecation\")"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings({ "deprecation", "removal" })
|
||||
void registerSeveralWarningsSuppressesThem() {
|
||||
void registerSeveralWarningsSuppressesThemOnMethod() {
|
||||
this.codeWarnings.register("deprecation");
|
||||
this.codeWarnings.register("removal");
|
||||
compile(method -> {
|
||||
compileWithMethod(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);
|
||||
@@ -90,6 +111,19 @@ class CodeWarningsTests {
|
||||
.contains("@SuppressWarnings({ \"deprecation\", \"removal\" })"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings({ "deprecation", "removal" })
|
||||
void registerSeveralWarningsSuppressesThemOnType() {
|
||||
this.codeWarnings.register("deprecation");
|
||||
this.codeWarnings.register("removal");
|
||||
compile(type -> {
|
||||
this.codeWarnings.suppress(type);
|
||||
type.addField(FieldSpec.builder(DeprecatedBean.class, "bean").build());
|
||||
type.addField(FieldSpec.builder(DeprecatedForRemovalBean.class, "another").build());
|
||||
}, compiled -> assertThat(compiled.getSourceFile())
|
||||
.contains("@SuppressWarnings({ \"deprecation\", \"removal\" })"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("deprecation")
|
||||
void detectDeprecationOnAnnotatedElementWithDeprecated() {
|
||||
@@ -171,16 +205,20 @@ class CodeWarningsTests {
|
||||
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 -> {
|
||||
private void compileWithMethod(Consumer<Builder> method, Consumer<Compiled> result) {
|
||||
compile(type -> {
|
||||
type.addModifiers(Modifier.PUBLIC);
|
||||
Builder methodBuilder = MethodSpec.methodBuilder("apply")
|
||||
.addModifiers(Modifier.PUBLIC);
|
||||
method.accept(methodBuilder);
|
||||
type.addMethod(methodBuilder.build());
|
||||
});
|
||||
}, result);
|
||||
}
|
||||
|
||||
private void compile(Consumer<TypeSpec.Builder> type, Consumer<Compiled> result) {
|
||||
DeferredTypeBuilder typeBuilder = new DeferredTypeBuilder();
|
||||
this.generationContext.getGeneratedClasses().addForFeature("TestCode", typeBuilder);
|
||||
typeBuilder.set(type);
|
||||
this.generationContext.writeGeneratedContent();
|
||||
TEST_COMPILER.with(this.generationContext).compile(result);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user