Merge branch '2.2.x'

Closes gh-19441
pull/19446/head
Stephane Nicoll 5 years ago
commit 6d9c176e19

@ -44,15 +44,18 @@ class TypeElementMembers {
private final MetadataGenerationEnvironment env; private final MetadataGenerationEnvironment env;
private final TypeElement targetType;
private final Map<String, VariableElement> fields = new LinkedHashMap<>(); private final Map<String, VariableElement> fields = new LinkedHashMap<>();
private final Map<String, ExecutableElement> publicGetters = new LinkedHashMap<>(); private final Map<String, ExecutableElement> publicGetters = new LinkedHashMap<>();
private final Map<String, List<ExecutableElement>> publicSetters = new LinkedHashMap<>(); private final Map<String, List<ExecutableElement>> publicSetters = new LinkedHashMap<>();
TypeElementMembers(MetadataGenerationEnvironment env, TypeElement element) { TypeElementMembers(MetadataGenerationEnvironment env, TypeElement targetType) {
this.env = env; this.env = env;
process(element); this.targetType = targetType;
process(targetType);
} }
private void process(TypeElement element) { private void process(TypeElement element) {
@ -116,8 +119,19 @@ class TypeElementMembers {
private boolean isSetterReturnType(ExecutableElement method) { private boolean isSetterReturnType(ExecutableElement method) {
TypeMirror returnType = method.getReturnType(); TypeMirror returnType = method.getReturnType();
return (TypeKind.VOID == returnType.getKind() if (TypeKind.VOID == returnType.getKind()) {
|| this.env.getTypeUtils().isSameType(method.getEnclosingElement().asType(), returnType)); return true;
}
if (TypeKind.DECLARED == returnType.getKind()
&& this.env.getTypeUtils().isSameType(method.getEnclosingElement().asType(), returnType)) {
return true;
}
if (TypeKind.TYPEVAR == returnType.getKind()) {
String resolvedType = this.env.getTypeUtils().getType(this.targetType, returnType);
return (resolvedType != null
&& resolvedType.equals(this.env.getTypeUtils().getQualifiedName(this.targetType)));
}
return false;
} }
private String getAccessorName(String methodName) { private String getAccessorName(String methodName) {

@ -22,6 +22,7 @@ import org.springframework.boot.configurationprocessor.metadata.ConfigurationMet
import org.springframework.boot.configurationprocessor.metadata.Metadata; import org.springframework.boot.configurationprocessor.metadata.Metadata;
import org.springframework.boot.configurationsample.generic.AbstractGenericProperties; import org.springframework.boot.configurationsample.generic.AbstractGenericProperties;
import org.springframework.boot.configurationsample.generic.ComplexGenericProperties; import org.springframework.boot.configurationsample.generic.ComplexGenericProperties;
import org.springframework.boot.configurationsample.generic.ConcreteBuilderProperties;
import org.springframework.boot.configurationsample.generic.GenericConfig; import org.springframework.boot.configurationsample.generic.GenericConfig;
import org.springframework.boot.configurationsample.generic.SimpleGenericProperties; import org.springframework.boot.configurationsample.generic.SimpleGenericProperties;
import org.springframework.boot.configurationsample.generic.UnresolvedGenericProperties; import org.springframework.boot.configurationsample.generic.UnresolvedGenericProperties;
@ -110,4 +111,15 @@ class GenericsMetadataGenerationTests extends AbstractMetadataGenerationTests {
assertThat(metadata.getItems()).hasSize(3); assertThat(metadata.getItems()).hasSize(3);
} }
@Test
void builderPatternWithGenericReturnType() {
ConfigurationMetadata metadata = compile(ConcreteBuilderProperties.class);
assertThat(metadata).has(Metadata.withGroup("builder").fromSource(ConcreteBuilderProperties.class));
assertThat(metadata).has(
Metadata.withProperty("builder.number", Integer.class).fromSource(ConcreteBuilderProperties.class));
assertThat(metadata).has(
Metadata.withProperty("builder.description", String.class).fromSource(ConcreteBuilderProperties.class));
assertThat(metadata.getItems()).hasSize(3);
}
} }

@ -0,0 +1,40 @@
/*
* Copyright 2012-2019 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.boot.configurationsample.generic;
import org.springframework.boot.configurationsample.ConfigurationProperties;
/**
* Builder pattern with a resolved generic
*
* @author Stephane Nicoll
*/
@ConfigurationProperties("builder")
public class ConcreteBuilderProperties extends GenericBuilderProperties<ConcreteBuilderProperties> {
private String description;
public String getDescription() {
return this.description;
}
public ConcreteBuilderProperties setDescription(String description) {
this.description = description;
return this;
}
}

@ -0,0 +1,38 @@
/*
* Copyright 2012-2019 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.boot.configurationsample.generic;
/**
* A configuration properties that uses the builder pattern with a generic.
*
* @param <T> the type of the return type
* @author Stephane Nicoll
*/
public class GenericBuilderProperties<T extends GenericBuilderProperties<T>> {
private int number;
public int getNumber() {
return this.number;
}
public T setNumber(int number) {
this.number = number;
return (T) this;
}
}
Loading…
Cancel
Save