Skip to content

Commit f542358

Browse files
committed
Types: add isRecursiveBound method
Helper method to determine if a bound of another type is in fact recursive, with its own type parameter equal to the bounded type.
1 parent 7bbe8b9 commit f542358

File tree

3 files changed

+22
-2
lines changed

3 files changed

+22
-2
lines changed

scijava-types/src/main/java/org/scijava/types/Types.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,26 @@ public static boolean isRecursive(final Type type) {
581581
return false;
582582
}
583583

584+
/**
585+
* Helper method to detect if a particular bound, {@code typeBound}, of a
586+
* reference type, {@code refType}, is a recursive type parameter: that is, if
587+
* {@code typeBound} itself has a type argument equal to {@code refType}.
588+
*
589+
*
590+
* @param refType Base type to check
591+
* @param typeBound A bound of {@code refType}
592+
* @return True if {@code typeBound} is parameterized with a type argument
593+
* that is itself equal to {@code refType}
594+
*/
595+
public static boolean isRecursiveBound(final Type refType, final Type typeBound) {
596+
if (typeBound instanceof ParameterizedType) {
597+
for (Type boundArg : ((ParameterizedType) typeBound).getActualTypeArguments()) {
598+
if (Objects.equals(refType,boundArg)) return true;
599+
}
600+
}
601+
return false;
602+
}
603+
584604
/**
585605
* Discerns whether it would be legal to pass a sequence of references of the
586606
* given source types to a method with parameters typed according to the

scijava-types/src/main/java/org/scijava/types/inference/GenericAssignability.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -611,7 +611,7 @@ private static void inferTypeVariables(TypeVariable<?> type, Type inferFrom,
611611
throw new TypeInferenceException();
612612
}
613613
}
614-
else {
614+
else if (!Types.isRecurisveBound(type, bound)) {
615615
// Else go into recursion as we encountered a new var.
616616
inferTypeVariables(bound, inferFrom, typeMappings);
617617
}

scijava-types/src/test/java/org/scijava/types/inference/InferTypeVariablesTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ public <O extends RecursiveThing<O>> void testInferRecursiveTypeVar() {
248248
// We expect O = FooThing
249249
TypeVariable<?> typeVarO = (TypeVariable<?>) new Nil<O>() {}.getType();
250250
Map<TypeVariable<?>, TypeMapping> expected = new HashMap<>();
251-
expected.put(typeVarO, new TypeMapping(typeVarO, FooThing.class, false));
251+
expected.put(typeVarO, new TypeMapping(typeVarO, FooThing.class, true));
252252

253253
Assertions.assertEquals(expected, typeAssigns);
254254
}

0 commit comments

Comments
 (0)