Accommodate with Lombok generation ordering

Previously, if lombok was running before the configuration metadata
annotation processor, duplicated keys were created as both the
getter/setter and the special lombok handling applied.

This commit makes sure to be lenient by removing duplicate metadata
entries. This commit also makes sure to identify the getter of a
nested group if present. That way, the sourceMethod is set consistently
and avoid the creation of a duplicate group.

Closes gh-8886
This commit is contained in:
Stephane Nicoll
2017-05-12 16:48:31 +02:00
parent a2e749940e
commit 643dea18ee
7 changed files with 161 additions and 22 deletions

View File

@@ -294,7 +294,8 @@ public class ConfigurationMetadataAnnotationProcessor extends AbstractProcessor
String name = entry.getKey();
VariableElement field = entry.getValue();
if (isLombokField(field, element)) {
processNestedType(prefix, element, source, name, null, field,
ExecutableElement getter = members.getPublicGetter(name, field.asType());
processNestedType(prefix, element, source, name, getter, field,
field.asType());
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2016 the original author or authors.
* Copyright 2012-2017 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.
@@ -16,8 +16,8 @@
package org.springframework.boot.configurationprocessor;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
@@ -39,7 +39,7 @@ import org.springframework.boot.configurationprocessor.metadata.ItemMetadata;
*/
public class MetadataCollector {
private final List<ItemMetadata> metadataItems = new ArrayList<ItemMetadata>();
private final Set<ItemMetadata> metadataItems = new LinkedHashSet<ItemMetadata>();
private final ProcessingEnvironment processingEnvironment;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2016 the original author or authors.
* Copyright 2012-2017 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.
@@ -171,6 +171,22 @@ class TypeElementMembers {
return Collections.unmodifiableMap(this.publicGetters);
}
public ExecutableElement getPublicGetter(String name, TypeMirror type) {
ExecutableElement candidate = this.publicGetters.get(name);
if (candidate != null) {
TypeMirror returnType = candidate.getReturnType();
if (this.env.getTypeUtils().isSameType(returnType, type)) {
return candidate;
}
TypeMirror alternative = this.typeUtils.getWrapperOrPrimitiveFor(type);
if (alternative != null &&
this.env.getTypeUtils().isSameType(returnType, alternative)) {
return candidate;
}
}
return null;
}
public ExecutableElement getPublicSetter(String name, TypeMirror type) {
List<ExecutableElement> candidates = this.publicSetters.get(name);
if (candidates != null) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2017 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.
@@ -24,7 +24,7 @@ package org.springframework.boot.configurationprocessor.metadata;
* @since 1.2.0
* @see ConfigurationMetadata
*/
public class ItemMetadata implements Comparable<ItemMetadata> {
public final class ItemMetadata implements Comparable<ItemMetadata> {
private ItemType itemType;
@@ -143,13 +143,59 @@ public class ItemMetadata implements Comparable<ItemMetadata> {
return string.toString();
}
protected final void buildToStringProperty(StringBuilder string, String property,
protected void buildToStringProperty(StringBuilder string, String property,
Object value) {
if (value != null) {
string.append(" ").append(property).append(":").append(value);
}
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
ItemMetadata other = (ItemMetadata) o;
return nullSafeEquals(this.itemType, other.itemType)
&& nullSafeEquals(this.name, other.name)
&& nullSafeEquals(this.type, other.type)
&& nullSafeEquals(this.description, other.description)
&& nullSafeEquals(this.sourceType, other.sourceType)
&& nullSafeEquals(this.sourceMethod, other.sourceMethod)
&& nullSafeEquals(this.defaultValue, other.defaultValue)
&& nullSafeEquals(this.deprecation, other.deprecation);
}
@Override
public int hashCode() {
int result = nullSafeHashCode(this.itemType);
result = 31 * result + nullSafeHashCode(this.name);
result = 31 * result + nullSafeHashCode(this.type);
result = 31 * result + nullSafeHashCode(this.description);
result = 31 * result + nullSafeHashCode(this.sourceType);
result = 31 * result + nullSafeHashCode(this.sourceMethod);
result = 31 * result + nullSafeHashCode(this.defaultValue);
result = 31 * result + nullSafeHashCode(this.deprecation);
return result;
}
private boolean nullSafeEquals(Object o1, Object o2) {
if (o1 == o2) {
return true;
}
if (o1 == null || o2 == null) {
return false;
}
return o1.equals(o2);
}
private int nullSafeHashCode(Object o) {
return (o == null ? 0 : o.hashCode());
}
@Override
public int compareTo(ItemMetadata o) {
return getName().compareTo(o.getName());