All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.jqwik.engine.support.GenericsSupport Maven / Gradle / Ivy

The newest version!
package net.jqwik.engine.support;

import java.lang.reflect.*;
import java.util.*;

import net.jqwik.api.providers.*;

public class GenericsSupport {

	private static final Map contextsCache = new LinkedHashMap<>();

	/**
	 * Return a context object which can resolve generic types for a given {@code contextClass}.
	 * 

* Must be synchronized because of caching. * * @param contextClass The class to wrap in a context * @return a potentially cached context object */ public synchronized static GenericsClassContext contextFor(Class contextClass) { if (contextClass == null) { return GenericsClassContext.NULL; } return contextFor(TypeUsage.of(contextClass)); } public synchronized static GenericsClassContext contextFor(TypeUsage typeUsage) { return contextsCache.computeIfAbsent(typeUsage, GenericsSupport::createContext); } private static GenericsClassContext createContext(TypeUsage typeUsage) { Class contextClass = typeUsage.getRawType(); GenericsClassContext context = new GenericsClassContext(contextClass); addOwnResolutions(typeUsage, context); addResolutionsForSuperclass(context); addResolutionsForInterfaces(context); return context; } private static void addResolutionsForInterfaces(GenericsClassContext context) { Class[] interfaces = context.contextClass().getInterfaces(); Type[] genericInterfaces = context.contextClass().getGenericInterfaces(); AnnotatedType[] annotatedInterfaces = context.contextClass().getAnnotatedInterfaces(); for (int i = 0; i < interfaces.length; i++) { Class supertype = interfaces[i]; Type genericSupertype = genericInterfaces[i]; AnnotatedType annotatedSupertype = annotatedInterfaces[i]; addResolutionsForSupertype(supertype, genericSupertype, annotatedSupertype, context); } } private static void addResolutionsForSuperclass(GenericsClassContext context) { addResolutionsForSupertype( context.contextClass().getSuperclass(), context.contextClass().getGenericSuperclass(), context.contextClass().getAnnotatedSuperclass(), context ); } private static void addOwnResolutions(TypeUsage typeUsage, GenericsClassContext context) { if (typeUsage.getTypeArguments().isEmpty()) { return; } List typeArgumentsList = typeUsage.getTypeArguments(); Type[] typeArguments = new Type[typeArgumentsList.size()]; AnnotatedType[] annotatedTypeVariables = new AnnotatedType[typeArgumentsList.size()]; for (int i = 0; i < typeArgumentsList.size(); i++) { typeArguments[i] = typeArgumentsList.get(i).getType(); annotatedTypeVariables[i] = typeArgumentsList.get(i).getAnnotatedType(); } TypeVariable[] typeVariables = typeUsage.getRawType().getTypeParameters(); addResolutions(context, typeArguments, typeVariables, annotatedTypeVariables); } private static void addResolutionsForSupertype( Class supertype, Type genericSupertype, AnnotatedType annotatedSupertype, GenericsClassContext context ) { if (!(genericSupertype instanceof ParameterizedType)) { return; } ParameterizedType genericParameterizedType = (ParameterizedType) genericSupertype; Type[] typeArguments = genericParameterizedType.getActualTypeArguments(); TypeVariable[] typeVariables = supertype.getTypeParameters(); AnnotatedType[] annotatedTypeVariables = ((AnnotatedParameterizedType) annotatedSupertype).getAnnotatedActualTypeArguments(); addResolutions(context, typeArguments, typeVariables, annotatedTypeVariables); } private static void addResolutions( GenericsClassContext context, Type[] typeArguments, TypeVariable[] typeVariables, AnnotatedType[] annotatedTypeVariables ) { for (int i = 0; i < typeVariables.length; i++) { TypeVariable variable = typeVariables[i]; Type resolvedType = typeArguments[i]; AnnotatedType annotatedType = annotatedTypeVariables[i]; context.addResolution(variable, resolvedType, annotatedType); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy