Fix incorrect type variance being applied on generated adapters (#1010)

* Fix: force object type for type arguments

* Add outDeclaration regression test for #1009

* Create mapTypesUtility for reusing recursive type mapping

* Strip typevar variance where appropriate

Resolves #1009
This commit is contained in:
Zac Sweers
2019-11-08 14:35:13 -08:00
committed by GitHub
parent 3c0e3edff3
commit d25abb1ee5
5 changed files with 90 additions and 44 deletions

View File

@@ -522,6 +522,24 @@ class DualKotlinTest(useReflection: Boolean) {
val convolutedMultiNullableShouldBeNullable: NullableB?,
val deepNestedNullableShouldBeNullable: E
)
// Regression test for https://github.com/square/moshi/issues/1009
@Test fun outDeclaration() {
val adapter = moshi.adapter<OutDeclaration<Int>>()
@Language("JSON")
val testJson = """{"input":3}"""
val instance = OutDeclaration(3)
assertThat(adapter.serializeNulls().toJson(instance))
.isEqualTo(testJson)
val result = adapter.fromJson(testJson)!!
assertThat(result).isEqualTo(instance)
}
@JsonClass(generateAdapter = true)
data class OutDeclaration<out T>(val input: T)
}
typealias TypeAlias = Int

View File

@@ -57,12 +57,16 @@ fun <T> Moshi.adapter(ktype: KType): JsonAdapter<T> {
}
@PublishedApi
internal fun KType.toType(): Type {
internal fun KType.toType(allowPrimitives: Boolean = true): Type {
classifier?.let {
when (it) {
is KTypeParameter -> throw IllegalArgumentException("Type parameters are not supported")
is KClass<*> -> {
val javaType = it.java
val javaType = if (allowPrimitives) {
it.java
} else {
it.javaObjectType
}
if (javaType.isArray) {
return Types.arrayOf(javaType.componentType)
}
@@ -88,7 +92,7 @@ internal fun KType.toType(): Type {
}
internal fun KTypeProjection.toType(): Type {
val javaType = type?.toType() ?: return Any::class.java
val javaType = type?.toType(allowPrimitives = false) ?: return Any::class.java
return when (variance) {
null -> Any::class.java
KVariance.INVARIANT -> javaType