Skip to content

Commit 34f0448

Browse files
mbelladesebersole
authored andcommitted
Simplify resolveTypeVariable and tweaks for parameterized types
1 parent 158bebe commit 34f0448

File tree

3 files changed

+34
-36
lines changed

3 files changed

+34
-36
lines changed

src/main/java/org/hibernate/models/spi/ClassDetails.java

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212
import org.hibernate.models.internal.SimpleClassDetails;
1313
import org.hibernate.models.internal.util.IndexedConsumer;
1414

15-
import static org.hibernate.models.spi.TypeDetailsHelper.resolveTypeVariableFromParameterizedType;
16-
1715
/**
1816
* Abstraction for what Hibernate understands about a "class", generally before it has access to
1917
* the actual {@link Class} reference, if there is a {@code Class} at all (dynamic models).
@@ -149,23 +147,12 @@ default TypeDetails resolveTypeVariable(TypeVariableDetails typeVariable) {
149147

150148
if ( isSuperclass( typeVariable.getDeclaringType() ) ) {
151149
final TypeDetails genericSuperType = getGenericSuperType();
152-
if ( genericSuperType != null && genericSuperType.getTypeKind() == TypeDetails.Kind.PARAMETERIZED_TYPE ) {
153-
final TypeDetails resolvedType = resolveTypeVariableFromParameterizedType(
154-
genericSuperType.asParameterizedType(),
155-
typeVariable
156-
);
157-
if ( resolvedType != null ) {
158-
return resolvedType;
159-
}
160-
}
161-
162-
final ClassDetails superClass = getSuperClass();
163-
if ( superClass != null ) {
164-
return superClass.resolveTypeVariable( typeVariable );
150+
if ( genericSuperType != null ) {
151+
return genericSuperType.resolveTypeVariable( typeVariable );
165152
}
166153
}
167154

168-
return ClassBasedTypeDetails.OBJECT_TYPE_DETAILS;
155+
return null;
169156
}
170157

171158
@Override

src/main/java/org/hibernate/models/spi/TypeDetailsHelper.java

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -194,31 +194,42 @@ public static TypeDetails resolveTypeVariableFromParameterizedType(
194194
ParameterizedTypeDetails parameterizedType,
195195
TypeVariableDetails typeVariable) {
196196
final ClassDetails classDetails = parameterizedType.getRawClassDetails();
197-
final List<TypeVariableDetails> typeParameters = classDetails.getTypeParameters();
198-
final List<TypeDetails> typeArguments = parameterizedType.getArguments();
199-
assert typeParameters.size() == typeArguments.size();
197+
final TypeDetails typeArgument = findMatchingTypeArgument(
198+
classDetails.getTypeParameters(),
199+
parameterizedType.getArguments(),
200+
typeVariable.getIdentifier()
201+
);
202+
203+
// If no type argument is found, or the type variable is defined by another
204+
// class, try resolving it in the generic super type if present
205+
if ( typeArgument == null || classDetails != typeVariable.getDeclaringType() ) {
206+
final TypeDetails genericSuper = classDetails.getGenericSuperType();
207+
final TypeDetails resolvedType = genericSuper != null ?
208+
genericSuper.resolveTypeVariable( typeVariable ) :
209+
null;
210+
if ( typeArgument == null || resolvedType != null
211+
&& resolvedType.getTypeKind() != TypeDetails.Kind.TYPE_VARIABLE ) {
212+
return resolvedType;
213+
}
214+
}
215+
216+
// Either we found the exact type variable's argument, or the parameterized class redefines
217+
// a type variable with the same identifier as a supertype, and it should be ignored.
218+
// Return the matching generic type argument
219+
return typeArgument;
220+
}
200221

222+
private static TypeDetails findMatchingTypeArgument(
223+
List<TypeVariableDetails> typeParameters,
224+
List<TypeDetails> typeArguments,
225+
String identifier) {
226+
assert typeParameters.size() == typeArguments.size();
201227
for ( int i = 0; i < typeParameters.size(); i++ ) {
202228
final TypeVariableDetails typeParameter = typeParameters.get( i );
203-
if ( typeParameter.getIdentifier().equals( typeVariable.getIdentifier() ) ) {
204-
if ( classDetails != typeVariable.getDeclaringType() ) {
205-
final TypeDetails genericSuper = classDetails.getGenericSuperType();
206-
if ( genericSuper != null && genericSuper.getTypeKind() == TypeDetails.Kind.PARAMETERIZED_TYPE ) {
207-
// Recursively check if the type variable is resolved in supertypes
208-
final TypeDetails superResolvedType = classDetails.resolveTypeVariable( typeVariable );
209-
if ( superResolvedType.getTypeKind() != TypeDetails.Kind.TYPE_VARIABLE
210-
&& superResolvedType != OBJECT_TYPE_DETAILS ) {
211-
return superResolvedType;
212-
}
213-
}
214-
}
215-
// Either we found the exact parameter definition, or the local generic supertype
216-
// redefines a type variable with the same identifier, and we should ignore it.
217-
// Return the matching generic type argument
229+
if ( typeParameter.getIdentifier().equals( identifier ) ) {
218230
return typeArguments.get( i );
219231
}
220232
}
221-
222233
return null;
223234
}
224235

src/main/java/org/hibernate/models/spi/TypeVariableScope.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public interface TypeVariableScope {
3535
*
3636
* @param typeVariable The type variable to resolve
3737
*
38-
* @return The type variable's resolved type, or {@code null} none could be found
38+
* @return The type variable's resolved type, or {@code null} if none could be found
3939
*/
4040
TypeDetails resolveTypeVariable(TypeVariableDetails typeVariable);
4141

0 commit comments

Comments
 (0)