Fix type detection with annotated getter

This commit makes sure that the `type` of a property is generated
property if the getter of the property is annotated. Previously, a type
implementation may expose the annotation information.

Closes gh-11512
This commit is contained in:
Stephane Nicoll
2018-01-17 10:45:10 +01:00
parent 6c191e149d
commit d8b1f1692a
5 changed files with 222 additions and 35 deletions

View File

@@ -25,8 +25,10 @@ import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.PrimitiveType;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.SimpleTypeVisitor6;
import javax.lang.model.util.Types;
/**
@@ -65,6 +67,8 @@ class TypeUtils {
private final ProcessingEnvironment env;
private final TypeExtractor typeExtractor;
private final TypeMirror collectionType;
private final TypeMirror mapType;
@@ -72,6 +76,7 @@ class TypeUtils {
TypeUtils(ProcessingEnvironment env) {
this.env = env;
Types types = env.getTypeUtils();
this.typeExtractor = new TypeExtractor(types);
this.collectionType = getDeclaredType(types, Collection.class, 1);
this.mapType = getDeclaredType(types, Map.class, 2);
}
@@ -100,20 +105,7 @@ class TypeUtils {
* {@link Class#forName(String)}
*/
public String getQualifiedName(Element element) {
if (element == null) {
return null;
}
TypeElement enclosingElement = getEnclosingTypeElement(element.asType());
if (enclosingElement != null) {
return getQualifiedName(enclosingElement) + "$"
+ ((DeclaredType) element.asType()).asElement().getSimpleName()
.toString();
}
if (element instanceof TypeElement) {
return ((TypeElement) element).getQualifiedName().toString();
}
throw new IllegalStateException(
"Could not extract qualified name from " + element);
return this.typeExtractor.getQualifiedName(element);
}
/**
@@ -126,27 +118,7 @@ class TypeUtils {
if (type == null) {
return null;
}
Class<?> wrapper = getWrapperFor(type);
if (wrapper != null) {
return wrapper.getName();
}
TypeElement enclosingElement = getEnclosingTypeElement(type);
if (enclosingElement != null) {
return getQualifiedName(enclosingElement) + "$"
+ ((DeclaredType) type).asElement().getSimpleName().toString();
}
return type.toString();
}
private TypeElement getEnclosingTypeElement(TypeMirror type) {
if (type instanceof DeclaredType) {
DeclaredType declaredType = (DeclaredType) type;
Element enclosingElement = declaredType.asElement().getEnclosingElement();
if (enclosingElement != null && enclosingElement instanceof TypeElement) {
return (TypeElement) enclosingElement;
}
}
return null;
return type.accept(this.typeExtractor, null);
}
public boolean isCollectionOrMap(TypeMirror type) {
@@ -194,4 +166,62 @@ class TypeUtils {
return WRAPPER_TO_PRIMITIVE.get(type.toString());
}
/**
* A visitor that extracts the full qualified name of a type, including generic
* information.
*/
private static class TypeExtractor extends SimpleTypeVisitor6<String, Void> {
private final Types types;
TypeExtractor(Types types) {
this.types = types;
}
@Override
public String visitDeclared(DeclaredType type, Void none) {
TypeElement enclosingElement = getEnclosingTypeElement(type);
if (enclosingElement != null) {
return getQualifiedName(enclosingElement) + "$"
+ type.asElement().getSimpleName().toString();
}
return type.toString();
}
@Override
public String visitPrimitive(PrimitiveType t, Void none) {
return this.types.boxedClass(t).getQualifiedName().toString();
}
public String getQualifiedName(Element element) {
if (element == null) {
return null;
}
TypeElement enclosingElement = getEnclosingTypeElement(element.asType());
if (enclosingElement != null) {
return getQualifiedName(enclosingElement) + "$"
+ ((DeclaredType) element.asType()).asElement().getSimpleName()
.toString();
}
if (element instanceof TypeElement) {
return ((TypeElement) element).getQualifiedName().toString();
}
throw new IllegalStateException(
"Could not extract qualified name from " + element);
}
private TypeElement getEnclosingTypeElement(TypeMirror type) {
if (type instanceof DeclaredType) {
DeclaredType declaredType = (DeclaredType) type;
Element enclosingElement = declaredType.asElement().getEnclosingElement();
if (enclosingElement != null && enclosingElement instanceof TypeElement) {
return (TypeElement) enclosingElement;
}
}
return null;
}
}
}