FlexTradeUKLtd / jfixture

JFixture is an open source library based on the popular .NET library, AutoFixture
MIT License
105 stars 22 forks source link

Basic support for WildcardType #57

Open mattmook opened 5 years ago

mattmook commented 5 years ago

When using jfixture on Kotlin it's common to define a class with a generic type as follows:

data class Something(val data: List<OtherClass>)

In Java this compiles down to the equivalent of List<? extends OtherClass>.

It would be possible to at least perform some basic logic in this scenario of a WildcardType, by for example, detecting a single upper bounds and using that for the type information rather than throwing an UnsupportedOperationException in SpecimenType.getFields().

Something similar to the following for example:

    private static SpecimenTypeFields getFields(Type type) {
        …
        } else if (type instanceof WildcardType) {
            if (((WildcardType) type).getUpperBounds().length == 1 && ((WildcardType) type).getLowerBounds().length == 0) {
                SpecimenTypeFields fields = new SpecimenTypeFields();
                fields.rawType = (Class) ((WildcardType) type).getUpperBounds()[0];
                fields.genericTypeArguments = GenericTypeCollection.empty();

                return fields;
            } else {
                throw new UnsupportedOperationException("Wildcard types not supported");
            }
        }

Of course the downside is it will only create types of that type, rather than super types but often that is enough.

TWiStErRob commented 5 years ago

👍 Note: we usually do data class Something(val data: List<@JvmSuppressWildcards OtherClass>) as a workaround.

mattmook commented 5 years ago

Meant to mention that as a workaround, but it means your class is then compiling as the invariant List<OtherClass> which isn't ideal if you still care about Java compatibility. You want to use bounded wildcards to increase API flexibility as per Item 31 in Effective Java Third Edition.