Skip to content

Commit 4c892c1

Browse files
committed
Merge branch 'types-fixes'
This improves the Types utility class and related functionality, to pave the way for more sophisticated type analysis in scijava-ops.
2 parents d99dcad + 93682f0 commit 4c892c1

File tree

4 files changed

+80
-19
lines changed

4 files changed

+80
-19
lines changed

Diff for: pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
</parent>
1111

1212
<artifactId>scijava-common</artifactId>
13-
<version>2.77.1-SNAPSHOT</version>
13+
<version>2.78.0-SNAPSHOT</version>
1414

1515
<name>SciJava Common</name>
1616
<description>SciJava Common is a shared library for SciJava software. It provides a plugin framework, with an extensible mechanism for service discovery, backed by its own annotation processor, so that plugins can be loaded dynamically. It is used by downstream projects in the SciJava ecosystem, such as ImageJ and SCIFIO.</description>

Diff for: src/main/java/org/scijava/util/ClassUtils.java

+1
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,7 @@ public static void setValue(final Field field, final Object instance,
352352

353353
// -- Comparison --
354354

355+
// START HERE: Migrate remaining methods to Types, then deprecate this class.
355356
/**
356357
* Compares two {@link Class} objects using their fully qualified names.
357358
* <p>

Diff for: src/main/java/org/scijava/util/Types.java

+17-18
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,6 @@
2929
* #L%
3030
*/
3131

32-
package org.scijava.util;
33-
34-
import java.io.File;
35-
3632
// Portions of this class were adapted from the
3733
// org.apache.commons.lang3.reflect.TypeUtils and
3834
// org.apache.commons.lang3.Validate classes of
@@ -46,6 +42,9 @@
4642
//
4743
// See NOTICE.txt for further details on third-party licenses.
4844

45+
package org.scijava.util;
46+
47+
import java.io.File;
4948
import java.io.Serializable;
5049
import java.lang.reflect.Array;
5150
import java.lang.reflect.Field;
@@ -70,8 +69,6 @@
7069
import java.util.Objects;
7170
import java.util.Set;
7271

73-
import org.scijava.util.FileUtils;
74-
7572
/**
7673
* Utility class for working with generic types, fields and methods.
7774
* <p>
@@ -86,6 +83,7 @@
8683
* </ul>
8784
*
8885
* @author Curtis Rueden
86+
* @author Gabe Selzer
8987
*/
9088
public final class Types {
9189

@@ -791,22 +789,22 @@ public static <T> T enumValue(final String name, final Class<T> dest) {
791789
public static ParameterizedType parameterize(final Class<?> rawType,
792790
final Type... typeArgs)
793791
{
794-
return parameterize(rawType, rawType.getDeclaringClass(), typeArgs);
792+
return parameterizeWithOwner(null, rawType, typeArgs);
795793
}
796794

797795
/**
798796
* Creates a new {@link ParameterizedType} of the given class together with
799797
* the specified type arguments.
800798
*
801-
* @param rawType The class of the {@link ParameterizedType}.
802799
* @param ownerType The owner type of the parameterized class.
800+
* @param rawType The class of the {@link ParameterizedType}.
803801
* @param typeArgs The type arguments to use in parameterizing it.
804802
* @return The newly created {@link ParameterizedType}.
805803
*/
806-
public static ParameterizedType parameterize(final Class<?> rawType,
807-
final Type ownerType, final Type... typeArgs)
804+
public static ParameterizedType parameterizeWithOwner(final Type ownerType,
805+
final Class<?> rawType, final Type... typeArgs)
808806
{
809-
return new TypeUtils.ParameterizedTypeImpl(rawType, ownerType, typeArgs);
807+
return TypeUtils.parameterizeWithOwner(ownerType, rawType, typeArgs);
810808
}
811809

812810
/**
@@ -1416,7 +1414,7 @@ private static boolean isAssignable(final Type type,
14161414
// parameters must either be absent from the subject type, within
14171415
// the bounds of the wildcard type, or be an exact match to the
14181416
// parameters of the target type.
1419-
if (fromTypeArg != null && !toTypeArg.equals(fromTypeArg) &&
1417+
if (fromTypeArg != null && !fromTypeArg.equals(toTypeArg) &&
14201418
!(toTypeArg instanceof WildcardType && isAssignable(fromTypeArg,
14211419
toTypeArg, typeVarAssigns)))
14221420
{
@@ -3206,7 +3204,7 @@ else if (isMissingTypeParameters(clazz)) {
32063204
Arrays.fill(arguments, UNBOUND_WILDCARD);
32073205
final Type owner = clazz.getDeclaringClass() == null ? null
32083206
: addWildcardParameters(clazz.getDeclaringClass());
3209-
return parameterize(clazz, owner, arguments);
3207+
return parameterizeWithOwner(owner, clazz, arguments);
32103208
}
32113209
else {
32123210
return clazz;
@@ -3584,9 +3582,9 @@ public static Type capture(final Type type) {
35843582
for (final CaptureTypeImpl captured : toInit) {
35853583
captured.init(varMap);
35863584
}
3587-
final Type ownerType = (pType.getOwnerType() == null) ? null : capture(
3585+
final Type ownerType = pType.getOwnerType() == null ? null : capture(
35883586
pType.getOwnerType());
3589-
return parameterize(clazz, ownerType, capturedArguments);
3587+
return parameterizeWithOwner(ownerType, clazz, capturedArguments);
35903588
}
35913589
return type;
35923590
}
@@ -3764,9 +3762,10 @@ else if (type instanceof TypeVariable) {
37643762
}
37653763
else if (type instanceof ParameterizedType) {
37663764
final ParameterizedType pType = (ParameterizedType) type;
3767-
return parameterize((Class<?>) pType.getRawType(), pType
3768-
.getOwnerType() == null ? pType.getOwnerType() : map(pType
3769-
.getOwnerType()), map(pType.getActualTypeArguments()));
3765+
final Type ownerType = pType.getOwnerType() == null ? //
3766+
pType.getOwnerType() : map(pType.getOwnerType());
3767+
return parameterizeWithOwner(ownerType, (Class<?>) pType.getRawType(),
3768+
map(pType.getActualTypeArguments()));
37703769
}
37713770
else if (type instanceof WildcardType) {
37723771
final WildcardType wType = (WildcardType) type;

Diff for: src/test/java/org/scijava/util/TypesTest.java

+61
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,12 @@ public void testBox() {
310310
}
311311
}
312312

313+
/** Tests {@link Types#unbox(Class)}. */
314+
@Test
315+
public void testUnbox() {
316+
// TODO
317+
}
318+
313319
/** Tests {@link Types#nullValue(Class)}. */
314320
@Test
315321
public void testNullValue() {
@@ -510,6 +516,31 @@ public void testIsAssignableClassToNull() {
510516
Types.isAssignable(Object.class, null);
511517
}
512518

519+
/** Tests {@link Types#isAssignable(Type, Type)} with type variable. */
520+
@Test
521+
public <T extends Number> void testIsAssignableT() {
522+
final Type t = genericTestType("t");
523+
final Type listT = genericTestType("listT");
524+
final Type listNumber = genericTestType("listNumber");
525+
final Type listInteger = genericTestType("listInteger");
526+
final Type listExtendsNumber = genericTestType("listExtendsNumber");
527+
528+
assertTrue(Types.isAssignable(t, t));
529+
assertTrue(Types.isAssignable(listT, listT));
530+
assertTrue(Types.isAssignable(listNumber, listNumber));
531+
assertTrue(Types.isAssignable(listInteger, listInteger));
532+
assertTrue(Types.isAssignable(listExtendsNumber, listExtendsNumber));
533+
534+
assertTrue(Types.isAssignable(listT, listExtendsNumber));
535+
assertTrue(Types.isAssignable(listNumber, listExtendsNumber));
536+
assertTrue(Types.isAssignable(listInteger, listExtendsNumber));
537+
538+
assertFalse(Types.isAssignable(listNumber, listT));
539+
assertFalse(Types.isAssignable(listInteger, listT));
540+
assertFalse(Types.isAssignable(listExtendsNumber, listT));
541+
assertFalse(Types.isAssignable(listExtendsNumber, listNumber));
542+
}
543+
513544
/** Tests {@link Types#isInstance(Object, Class)}. */
514545
@Test
515546
public void testIsInstance() {
@@ -572,9 +603,28 @@ public void testEnumValueNonEnum() {
572603
Types.enumValue("HOOYAH", String.class);
573604
}
574605

606+
/** Tests {@link Types#parameterize(Class, Map)}. */
607+
@Test
608+
public void testParameterizeMap() {
609+
// TODO
610+
}
611+
612+
/** Tests {@link Types#parameterize(Class, Type...)}. */
613+
@Test
614+
public void testParameterizeTypes() {
615+
// TODO
616+
}
617+
618+
/** Tests {@link Types#parameterizeWithOwner(Type, Class, Type...)}. */
619+
@Test
620+
public void testParameterizeWithOwner() {
621+
// TODO
622+
}
623+
575624
// -- Helper classes --
576625

577626
private static class Thing<T> {
627+
578628
@SuppressWarnings("unused")
579629
private T thing;
580630
}
@@ -598,6 +648,14 @@ public static enum Words {
598648
FOO, BAR, FUBAR
599649
}
600650

651+
private interface TestTypes<T extends Number> {
652+
T t();
653+
List<T> listT();
654+
List<Number> listNumber();
655+
List<Integer> listInteger();
656+
List<? extends Number> listExtendsNumber();
657+
}
658+
601659
// -- Helper methods --
602660

603661
/**
@@ -671,4 +729,7 @@ private void assertAllTheSame(final List<?> list, final Object... values) {
671729
}
672730
}
673731

732+
private Type genericTestType(final String name) {
733+
return Types.method(TestTypes.class, name).getGenericReturnType();
734+
}
674735
}

0 commit comments

Comments
 (0)