Check types parameter size in init (#1063)

* Add types size check in code gen

Resolves #932

* Add more useful message for mismatched generics lookup

* Add tests

* Style
This commit is contained in:
Zac Sweers
2020-01-14 01:50:53 -05:00
committed by GitHub
parent cc4b5b3ad2
commit f891c8187b
3 changed files with 57 additions and 7 deletions

View File

@@ -18,6 +18,7 @@ package com.squareup.moshi.kotlin.codegen.api
import com.squareup.kotlinpoet.ARRAY
import com.squareup.kotlinpoet.AnnotationSpec
import com.squareup.kotlinpoet.CodeBlock
import com.squareup.kotlinpoet.CodeBlock.Companion
import com.squareup.kotlinpoet.FileSpec
import com.squareup.kotlinpoet.FunSpec
import com.squareup.kotlinpoet.INT
@@ -158,6 +159,22 @@ internal class AdapterGenerator(
if (typeVariables.isNotEmpty()) {
result.addTypeVariables(typeVariables.map { it.stripTypeVarVariance() as TypeVariableName })
// require(types.size == 1) {
// "TypeVariable mismatch: Expecting 1 type(s) for generic type variables [T], but received ${types.size} with values $types"
// }
result.addInitializerBlock(CodeBlock.builder()
.beginControlFlow("require(types.size == %L)", typeVariables.size)
.addStatement(
"buildString·{·append(%S).append(%L).append(%S).append(%S).append(%S).append(%L)·}",
"TypeVariable mismatch: Expecting ",
typeVariables.size,
" ${if (typeVariables.size == 1) "type" else "types"} for generic type variables [",
typeVariables.joinToString(", ") { it.name },
"], but received ",
"${typesParam.name}.size"
)
.endControlFlow()
.build())
}
// TODO make this configurable. Right now it just matches the source model

View File

@@ -1220,6 +1220,30 @@ class GeneratedAdaptersTest {
val propertyWithAnnotatedType: @TypeAnnotation String = "",
val generic: List<@TypeAnnotation String>
)
@Test fun typesSizeCheckMessages_noArgs() {
try {
moshi.adapter(MultipleGenerics::class.java)
fail("Should have failed to construct the adapter due to missing generics")
} catch (e: RuntimeException) {
assertThat(e).hasMessage("Failed to find the generated JsonAdapter constructor for 'class com.squareup.moshi.kotlin.codegen.GeneratedAdaptersTest\$MultipleGenerics'. Suspiciously, the type was not parameterized but the target class 'com.squareup.moshi.kotlin.codegen.GeneratedAdaptersTest_MultipleGenericsJsonAdapter' is generic. Consider using Types#newParameterizedType() to define these missing type variables.")
}
}
@Test fun typesSizeCheckMessages_wrongNumberOfArgs() {
try {
GeneratedAdaptersTest_MultipleGenericsJsonAdapter<String, Any, Any, Any>(
moshi,
arrayOf(String::class.java)
)
fail("Should have failed to construct the adapter due to wrong number of generics")
} catch (e: IllegalArgumentException) {
assertThat(e).hasMessage("TypeVariable mismatch: Expecting 4 types for generic type variables [A, B, C, D], but received 1")
}
}
@JsonClass(generateAdapter = true)
data class MultipleGenerics<A, B, C, D>(val prop: String)
}
// Regression test for https://github.com/square/moshi/issues/1022