Generate metadata for records using implicit constructor binding

Closes gh-27216
This commit is contained in:
Andy Wilkinson 2021-07-26 09:43:32 +01:00
parent a5656e0932
commit 681df90d33
3 changed files with 70 additions and 3 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 the original author or authors.
* Copyright 2012-2021 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.
@ -197,7 +197,8 @@ class PropertyDescriptorResolver {
}
private static boolean isConstructorBoundType(TypeElement type, MetadataGenerationEnvironment env) {
if (env.hasConstructorBindingAnnotation(type)) {
if (env.hasConstructorBindingAnnotation(type)
|| "java.lang.Record".equals(type.getSuperclass().toString())) {
return true;
}
if (type.getNestingKind() == NestingKind.MEMBER) {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2021 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.
@ -18,6 +18,7 @@ package org.springframework.boot.configurationprocessor;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.io.TempDir;
@ -54,4 +55,11 @@ public abstract class AbstractMetadataGenerationTests {
return processor.getMetadata();
}
protected ConfigurationMetadata compile(File... sources) {
TestConfigurationMetadataAnnotationProcessor processor = new TestConfigurationMetadataAnnotationProcessor(
this.compiler.getOutputLocation());
this.compiler.getTask(Arrays.asList(sources)).call(processor);
return processor.getMetadata();
}
}

View File

@ -16,7 +16,15 @@
package org.springframework.boot.configurationprocessor;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledForJreRange;
import org.junit.jupiter.api.condition.JRE;
import org.junit.jupiter.api.io.TempDir;
import org.springframework.boot.configurationprocessor.metadata.ConfigurationMetadata;
import org.springframework.boot.configurationprocessor.metadata.ItemMetadata;
@ -402,4 +410,54 @@ class ConfigurationMetadataAnnotationProcessorTests extends AbstractMetadataGene
compile(RecursiveProperties.class);
}
@Test
@EnabledForJreRange(min = JRE.JAVA_16)
void explicityBoundRecordProperties(@TempDir File temp) throws IOException {
File exampleRecord = new File(temp, "ExampleRecord.java");
try (PrintWriter writer = new PrintWriter(new FileWriter(exampleRecord))) {
writer.println("@org.springframework.boot.configurationsample.ConstructorBinding");
writer.println("@org.springframework.boot.configurationsample.ConfigurationProperties(\"explicit\")");
writer.println("public record ExampleRecord(String someString, Integer someInteger) {");
writer.println("}");
}
ConfigurationMetadata metadata = compile(exampleRecord);
assertThat(metadata).has(Metadata.withProperty("explicit.some-string"));
assertThat(metadata).has(Metadata.withProperty("explicit.some-integer"));
}
@Test
@EnabledForJreRange(min = JRE.JAVA_16)
void implicitlyBoundRecordProperties(@TempDir File temp) throws IOException {
File exampleRecord = new File(temp, "ExampleRecord.java");
try (PrintWriter writer = new PrintWriter(new FileWriter(exampleRecord))) {
writer.println("@org.springframework.boot.configurationsample.ConfigurationProperties(\"implicit\")");
writer.println("public record ExampleRecord(String someString, Integer someInteger) {");
writer.println("}");
}
ConfigurationMetadata metadata = compile(exampleRecord);
assertThat(metadata).has(Metadata.withProperty("implicit.some-string"));
assertThat(metadata).has(Metadata.withProperty("implicit.some-integer"));
}
@Test
@EnabledForJreRange(min = JRE.JAVA_16)
void multiConstructorRecordProperties(@TempDir File temp) throws IOException {
File exampleRecord = new File(temp, "ExampleRecord.java");
try (PrintWriter writer = new PrintWriter(new FileWriter(exampleRecord))) {
writer.println("@org.springframework.boot.configurationsample.ConfigurationProperties(\"multi\")");
writer.println("public record ExampleRecord(String someString, Integer someInteger) {");
writer.println(" @org.springframework.boot.configurationsample.ConstructorBinding");
writer.println(" public ExampleRecord(String someString) {");
writer.println(" this(someString, 42);");
writer.println(" }");
writer.println(" public ExampleRecord(Integer someInteger) {");
writer.println(" this(\"someString\", someInteger);");
writer.println(" }");
writer.println("}");
}
ConfigurationMetadata metadata = compile(exampleRecord);
assertThat(metadata).has(Metadata.withProperty("multi.some-string"));
assertThat(metadata).doesNotHave(Metadata.withProperty("multi.some-integer"));
}
}