From 0454ccd25e8bf45c015cb41f3e419be9af1a2f64 Mon Sep 17 00:00:00 2001 From: Johannes Link Date: Fri, 20 Oct 2023 10:13:05 +0200 Subject: [PATCH] Optimized resolution of type variables in type hierarchies --- .../engine/support/GenericsClassContext.java | 39 +++++++++---------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/engine/src/main/java/net/jqwik/engine/support/GenericsClassContext.java b/engine/src/main/java/net/jqwik/engine/support/GenericsClassContext.java index eaedcfe71..8f6b6df47 100644 --- a/engine/src/main/java/net/jqwik/engine/support/GenericsClassContext.java +++ b/engine/src/main/java/net/jqwik/engine/support/GenericsClassContext.java @@ -102,7 +102,7 @@ public AnnotatedType[] getAnnotatedActualTypeArguments() { private TypeResolution resolveVariable(TypeResolution typeVariableResolution) { TypeResolution localResolution = resolveVariableLocally(typeVariableResolution); if (localResolution.isVariable()) { - TypeResolution supertypeResolution = resolveVariableInSupertypes(localResolution); + TypeResolution supertypeResolution = resolveVariableInSupertypesOf(localResolution, contextType); if (supertypeResolution.typeHasChanged()) { return resolveType(supertypeResolution); } @@ -119,29 +119,25 @@ private TypeResolution resolveVariableLocally(TypeResolution typeResolution) { return resolutions.getOrDefault(variable, typeResolution.unchanged()); } - private TypeResolution resolveVariableInSupertypes(TypeResolution typeResolution) { - // TODO: Optimize so that only get supertypes of supertypes if necessary - // i.e. it cannot be resolved in direct supertypes - Set superTypes = getAllSupertypes(contextType); - List typeResolutionList = - superTypes.stream() - .map(GenericsSupport::contextFor) - .map(context -> context.resolveVariableLocally(typeResolution)) - .filter(TypeResolution::typeHasChanged) - .collect(Collectors.toList()); - - return typeResolutionList.stream() - .findFirst() - .orElse(typeResolution.unchanged()); + private static TypeResolution resolveVariableInSupertypesOf(TypeResolution variableResolution, TypeUsage type) { + return resolveVariableInTypes(variableResolution, type.getSuperTypes()); } - private Set getAllSupertypes(TypeUsage contextType) { - List directSupertypes = contextType.getSuperTypes(); - Set allSupertypes = new LinkedHashSet<>(directSupertypes); - for (TypeUsage directSupertype : directSupertypes) { - allSupertypes.addAll(getAllSupertypes(directSupertype)); + private static TypeResolution resolveVariableInTypes(TypeResolution variableResolution, Collection superTypes) { + for (TypeUsage superType : superTypes) { + GenericsClassContext context = GenericsSupport.contextFor(superType); + TypeResolution resolved = context.resolveVariableLocally(variableResolution); + if (resolved.typeHasChanged()) { + return resolved; + } + } + for (TypeUsage superType : superTypes) { + TypeResolution typeResolution = resolveVariableInSupertypesOf(variableResolution, superType); + if (typeResolution.typeHasChanged()) { + return typeResolution; + } } - return allSupertypes; + return variableResolution.unchanged(); } private static class LookupTypeVariable { @@ -243,6 +239,7 @@ public Annotation[] getDeclaredAnnotations() { // For compatibility with JDK >= 9. A breaking change in the JDK :-( // @Override + @SuppressWarnings("Since15") public AnnotatedType getAnnotatedOwnerType() { // TODO: Return annotatedType.getAnnotatedOwnerType() as soon as Java >= 9 is being used return null;