- java.lang.Object
-
- org.scijava.types.infer.GenericAssignability
-
public final class GenericAssignability extends Object
Bigger-picture, method-level static methods.Whereas the methods of
Typesanswer questions like "does this type assign to that type", whereas this class's methods address questions like "does this set of method arguments assign to this set of method parameters given shared type variables?"- Author:
- Gabriel Selzer
-
-
Method Summary
All Methods Static Methods Concrete Methods Modifier and Type Method Description static booleancheckGenericAssignability(Type src, ParameterizedType dest, boolean safeAssignability)static booleancheckGenericAssignability(Type src, ParameterizedType dest, Map<TypeVariable<?>,Type> typeVarAssigns, boolean safeAssignability)Checks whether it would be legal to assign theTypesource to the specifiedParameterizedTypedestination (which could possibly be a supertype of the source type).static voidinferTypeVariables(Type[] types, Type[] inferFroms, Map<TypeVariable<?>,Type> typeVarAssigns)Tries to infer type vars contained in types from corresponding types from inferFrom, putting them into the specified map.static Map<TypeVariable<?>,Type>inferTypeVariables(Type type, Type inferFrom)Tries to infer type vars contained in types from corresponding types from inferFrom, putting them into the specified map.static booleanisSafeAssignable(Type[] destTypes, Map<TypeVariable<?>,Type> typeVarAssigns, Type src, Type dest)We know that the special types for the Op candidate and what we asked for are the same (i.e.static Type[]mapVarToTypes(Type[] typesToMap, Map<TypeVariable<?>,Type> typeAssigns)Map type vars in specified type list to types using the specified map.
-
-
-
Method Detail
-
checkGenericAssignability
public static boolean checkGenericAssignability(Type src, ParameterizedType dest, boolean safeAssignability)
- Parameters:
src- the type for which assignment should be checked fromdest- the parameterized type for which assignment should be checked tosafeAssignability- used to determine if we want to check if the src→dest assignment would be safely assignable even though it would cause a compiler error if we explicitly tried to do this (useful pretty much only for Op matching)- Returns:
- whether and assignment of source to destination would be a legal java statement
-
checkGenericAssignability
public static boolean checkGenericAssignability(Type src, ParameterizedType dest, Map<TypeVariable<?>,Type> typeVarAssigns, boolean safeAssignability)
Checks whether it would be legal to assign theTypesource to the specifiedParameterizedTypedestination (which could possibly be a supertype of the source type). Thereby, possibleTypeVariables contained in the parameters of the source are tried to be inferred in the sense of empty angle brackets when a new object is created:List<Integer> listOfInts = new ArrayList<>();
Hence, the types to put between the brackets are tried to be determined. Inference will be done by simple matching of an encounteredTypeVariablein the source to the corresponding type in the parameters of the destination. If anTypeVariableis encountered more than once, the corresponding type in the destination needs to perfectly match. Else, false will be returned.Examples:
If we have a class:class NumberSupplier<M extends Number> implements Supplier<M>
The following check will return true:checkGenericAssignability(NumberSupplier.class, new Nil<Supplier<Double>>() {}.type())Which will check if the following assignment would be legal:Supplier<Double> list = new NumberSupplier<>()
Here, the parameter<M extends Number>can be inferred to be of typeDoublefrom the typeSupplier<Double>Consequently the following will return false:
checkGenericAssignability(NumberSupplier.class, new Nil<Supplier<String>>() {}.type())<M extends Number>can't be inferred, as typeStringis not within the bounds ofM.Furthermore, the following will return false for:
class NumberFunc<M extends Number> implements Function<M, M>:checkGenericAssignability(NumberSupplier.class, new Nil<Function<Double, Integer>>() {}.type())<M extends Number>can't be inferred, as typesDoubleandIntegerare ambiguous forM.- Parameters:
src- the type for which assignment should be checked fromdest- the parameterized type for which assignment should be checked totypeVarAssigns- the map ofTypeVariables toTypes to populate with what would occur in this scenario; must be empty or nullsafeAssignability- used to determine if we want to check if the src→dest assignment would be safely assignable even though it would cause a compiler error if we explicitly tried to do this (useful pretty much only for Op matching)- Returns:
- whether and assignment of source to destination would be a legal java statement
-
inferTypeVariables
public static Map<TypeVariable<?>,Type> inferTypeVariables(Type type, Type inferFrom)
Tries to infer type vars contained in types from corresponding types from inferFrom, putting them into the specified map. When aTypeInferenceExceptionis thrown, the caller should assume that some of the mappings withintypeMappingsare incorrect.- Parameters:
type-inferFrom-- Returns:
- the mapping of
TypeVariables intypetoTypes ininferFrom
-
inferTypeVariables
public static void inferTypeVariables(Type[] types, Type[] inferFroms, Map<TypeVariable<?>,Type> typeVarAssigns)
Tries to infer type vars contained in types from corresponding types from inferFrom, putting them into the specified map. When aTypeInferenceExceptionis thrown, the caller should assume that some of the mappings withintypeMappingsare incorrect.- Parameters:
types- - the types containingTypeVariablesinferFroms- - the types used to infer theTypeVariables withintypestypeVarAssigns- - the mapping ofTypeVariables toTypes
-
isSafeAssignable
public static boolean isSafeAssignable(Type[] destTypes, Map<TypeVariable<?>,Type> typeVarAssigns, Type src, Type dest)
We know that the special types for the Op candidate and what we asked for are the same (i.e. that we are trying to determine if one Function can be assigned to another Function). There are some situations (that are particularly common when using ops.run()) where the Function SHOULD NOT NORMALLY MATCH UP but WE KNOW IT WILL BE SAFE TO ASSIGN. This method attempts to tease those situations out as a last resort.- Parameters:
destTypes- - the array of Parameterized types of the OpInfo we called the matcher on (in the case of ops.run(), it is a Type array of the types of the args we passed through.)typeVarAssigns- - a Map of all of the Type Variables already determined.dest- - the special type of the Op that we want to find a match for (determined by the user / ops.run())- Returns:
- boolean - true if we can safely match this Op even though the types do not directly match up. False otherwise.
-
mapVarToTypes
public static Type[] mapVarToTypes(Type[] typesToMap, Map<TypeVariable<?>,Type> typeAssigns)
Map type vars in specified type list to types using the specified map. In doing so, type vars mapping to other type vars will not be followed but just replaced.- Parameters:
typesToMap-typeAssigns-- Returns:
- a copy of
typesToMapin which theTypeVariables (that are present intypeAssigns) are mapped to the associated values within theMap.
-
-