HHH-17873 some handling for generics in lifecycle method signatures

This commit is contained in:
Gavin King 2024-03-21 01:02:02 +01:00
parent 9305610a32
commit f7fbbae538
1 changed files with 31 additions and 8 deletions

View File

@ -891,20 +891,23 @@ public class AnnotationMetaEntity extends AnnotationMeta {
final boolean returnArgument = returnType.getKind() != TypeKind.VOID; final boolean returnArgument = returnType.getKind() != TypeKind.VOID;
final String operation = lifecycleOperation( method ); final String operation = lifecycleOperation( method );
final VariableElement parameter = method.getParameters().get(0); final VariableElement parameter = method.getParameters().get(0);
final TypeMirror parameterType = parameter.asType(); final TypeMirror declaredParameterType = parameter.asType();
final TypeMirror parameterType = parameterType( declaredParameterType );
final DeclaredType declaredType = entityType( parameterType ); final DeclaredType declaredType = entityType( parameterType );
if ( declaredType == null ) { if ( declaredType == null ) {
context.message( parameter, context.message( parameter,
"incorrect parameter type '" + parameterType + "' is not an entity type", "incorrect parameter type '" + parameterType + "' is not an entity type",
Diagnostic.Kind.ERROR ); Diagnostic.Kind.ERROR );
} }
else if ( !containsAnnotation( declaredType.asElement(), ENTITY ) ) { else if ( !containsAnnotation( declaredType.asElement(), ENTITY )
// TODO: improve this (carefully consider the case of an erased type variable)
&& declaredParameterType == parameterType ) {
context.message( parameter, context.message( parameter,
"incorrect parameter type '" + parameterType + "' is not annotated '@Entity'", "incorrect parameter type '" + parameterType + "' is not annotated '@Entity'",
Diagnostic.Kind.ERROR ); Diagnostic.Kind.ERROR );
} }
else if ( returnArgument else if ( returnArgument
&& !context.getTypeUtils().isSameType( returnType, parameterType ) ) { && !context.getTypeUtils().isSameType( returnType, declaredParameterType ) ) {
context.message( parameter, context.message( parameter,
"return type '" + returnType "return type '" + returnType
+ "' disagrees with parameter type '" + parameterType + "'", + "' disagrees with parameter type '" + parameterType + "'",
@ -933,6 +936,10 @@ public class AnnotationMetaEntity extends AnnotationMeta {
private @Nullable DeclaredType entityType(TypeMirror parameterType) { private @Nullable DeclaredType entityType(TypeMirror parameterType) {
switch ( parameterType.getKind() ) { switch ( parameterType.getKind() ) {
case TYPEVAR:
final TypeVariable typeVariable = (TypeVariable) parameterType;
parameterType = typeVariable.getUpperBound();
//INTENTIONAL FALL THROUGH
case DECLARED: case DECLARED:
final DeclaredType declaredType = (DeclaredType) parameterType; final DeclaredType declaredType = (DeclaredType) parameterType;
final Types types = context.getTypeUtils(); final Types types = context.getTypeUtils();
@ -940,7 +947,7 @@ public class AnnotationMetaEntity extends AnnotationMeta {
if ( types.isAssignable( declaredType, if ( types.isAssignable( declaredType,
types.erasure( elements.getTypeElement(ITERABLE).asType() ) ) types.erasure( elements.getTypeElement(ITERABLE).asType() ) )
&& !declaredType.getTypeArguments().isEmpty() ) { && !declaredType.getTypeArguments().isEmpty() ) {
final TypeMirror elementType = declaredType.getTypeArguments().get(0); final TypeMirror elementType = parameterType( declaredType.getTypeArguments().get(0) );
return elementType.getKind() == TypeKind.DECLARED ? (DeclaredType) elementType : null; return elementType.getKind() == TypeKind.DECLARED ? (DeclaredType) elementType : null;
} }
else { else {
@ -948,7 +955,7 @@ public class AnnotationMetaEntity extends AnnotationMeta {
} }
case ARRAY: case ARRAY:
final ArrayType arrayType = (ArrayType) parameterType; final ArrayType arrayType = (ArrayType) parameterType;
final TypeMirror componentType = arrayType.getComponentType(); final TypeMirror componentType = parameterType( arrayType.getComponentType() );
return componentType.getKind() == TypeKind.DECLARED ? (DeclaredType) componentType : null; return componentType.getKind() == TypeKind.DECLARED ? (DeclaredType) componentType : null;
default: default:
return null; return null;
@ -2099,12 +2106,28 @@ public class AnnotationMetaEntity extends AnnotationMeta {
.collect(toList()); .collect(toList());
} }
private static List<String> parameterTypes(ExecutableElement method) { private List<String> parameterTypes(ExecutableElement method) {
return method.getParameters().stream() return method.getParameters().stream()
.map(param -> param.asType().toString()) .map(param -> parameterType(param.asType()).toString())
.collect(toList()); .collect(toList());
} }
private TypeMirror parameterType(TypeMirror type) {
switch (type.getKind()) {
case TYPEVAR:
final TypeVariable typeVariable = (TypeVariable) type;
return context.getTypeUtils().erasure(typeVariable);
case DECLARED:
final DeclaredType declaredType = (DeclaredType) type;
return declaredType.getTypeArguments().stream()
.anyMatch(arg -> arg.getKind() == TypeKind.TYPEVAR)
? context.getTypeUtils().erasure(type)
: type;
default:
return type;
}
}
private static List<Boolean> parameterPatterns(ExecutableElement method) { private static List<Boolean> parameterPatterns(ExecutableElement method) {
return method.getParameters().stream() return method.getParameters().stream()
.map(param -> hasAnnotation(param, PATTERN)) .map(param -> hasAnnotation(param, PATTERN))
@ -2237,7 +2260,7 @@ public class AnnotationMetaEntity extends AnnotationMeta {
private boolean usingReactiveSession(String sessionType) { private boolean usingReactiveSession(String sessionType) {
return MUTINY_SESSION.equals(sessionType) return MUTINY_SESSION.equals(sessionType)
|| Constants.UNI_MUTINY_SESSION.equals(sessionType); || UNI_MUTINY_SESSION.equals(sessionType);
} }
private boolean usingStatelessSession(String sessionType) { private boolean usingStatelessSession(String sessionType) {