Fall back to reflection when generated adapter is not found. (#728)

* Fall back to reflection when generated adapter is not found.

This is handy for development builds where kapt is disabled and models still have @JsonClass(generatedAdapter = true).

* Add test for Kotlin reflection fallback behavior.
This commit is contained in:
Eric Cochran
2018-11-05 23:28:36 -08:00
committed by Jesse Wilson
parent a8102bccd2
commit 5c41565f39
4 changed files with 87 additions and 46 deletions

View File

@@ -24,6 +24,7 @@ import com.squareup.moshi.JsonWriter
import com.squareup.moshi.Moshi
import com.squareup.moshi.Types
import com.squareup.moshi.internal.Util
import com.squareup.moshi.internal.Util.generatedAdapter
import com.squareup.moshi.internal.Util.resolve
import java.lang.reflect.Modifier
import java.lang.reflect.Type
@@ -174,8 +175,17 @@ class KotlinJsonAdapterFactory : JsonAdapter.Factory {
if (rawType.isEnum) return null
if (!rawType.isAnnotationPresent(KOTLIN_METADATA)) return null
if (Util.isPlatformType(rawType)) return null
val jsonClass = rawType.getAnnotation(JsonClass::class.java)
if (jsonClass != null && jsonClass.generateAdapter) return null
try {
val generatedAdapter = generatedAdapter(moshi, type, rawType)
if (generatedAdapter != null) {
return generatedAdapter
}
} catch (e: RuntimeException) {
if (e.cause !is ClassNotFoundException) {
throw e
}
// Fall back to a reflective adapter when the generated adapter is not found.
}
if (rawType.isLocalClass) {
throw IllegalArgumentException("Cannot serialize local class or object expression ${rawType.name}")

View File

@@ -0,0 +1,21 @@
package com.squareup.moshi.kotlin.reflect
import com.squareup.moshi.JsonClass
import com.squareup.moshi.Moshi
import org.assertj.core.api.Assertions.assertThat
import org.junit.Test
class KotlinJsonAdapterTest {
@JsonClass(generateAdapter = true)
class Data
@Test fun fallsBackToReflectiveAdapterWithoutCodegen() {
val moshi = Moshi.Builder()
.add(KotlinJsonAdapterFactory())
.build()
val adapter = moshi.adapter(Data::class.java)
assertThat(adapter.toString()).isEqualTo(
"KotlinJsonAdapter(com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterTest.Data).nullSafe()"
)
}
}