mirror of
https://github.com/fankes/moshi.git
synced 2025-10-20 00:19:21 +08:00
Merge pull request #660 from square/eric.fix-preemptive-null-check
Allow user adapters to convert null to non-null in codegen.
This commit is contained in:
@@ -69,11 +69,9 @@ internal data class DelegateKey(
|
|||||||
}
|
}
|
||||||
val finalArgs = arrayOf(*standardArgs, *args)
|
val finalArgs = arrayOf(*standardArgs, *args)
|
||||||
|
|
||||||
val nullModifier = if (nullable) ".nullSafe()" else ".nonNull()"
|
|
||||||
|
|
||||||
return PropertySpec.builder(adapterName, adapterTypeName, KModifier.PRIVATE)
|
return PropertySpec.builder(adapterName, adapterTypeName, KModifier.PRIVATE)
|
||||||
.addAnnotations(jsonQualifiers)
|
.addAnnotations(jsonQualifiers)
|
||||||
.initializer("%1N.adapter%2L(%3L$initializerString)$nullModifier", *finalArgs)
|
.initializer("%1N.adapter%2L(%3L$initializerString)", *finalArgs)
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -413,7 +413,7 @@ class GeneratedAdaptersTest {
|
|||||||
jsonAdapter.fromJson("{\"a\":null}")
|
jsonAdapter.fromJson("{\"a\":null}")
|
||||||
fail()
|
fail()
|
||||||
} catch (expected: JsonDataException) {
|
} catch (expected: JsonDataException) {
|
||||||
assertThat(expected).hasMessage("Unexpected null at \$.a")
|
assertThat(expected).hasMessage("Non-null value 'a' was null at \$.a")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -432,7 +432,10 @@ class GeneratedAdaptersTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@JsonClass(generateAdapter = true)
|
@JsonClass(generateAdapter = true)
|
||||||
class HasNonNullConstructorParameter(val a: String)
|
data class HasNonNullConstructorParameter(val a: String)
|
||||||
|
|
||||||
|
@JsonClass(generateAdapter = true)
|
||||||
|
data class HasNullableConstructorParameter(val a: String?)
|
||||||
|
|
||||||
@Test fun explicitNull() {
|
@Test fun explicitNull() {
|
||||||
val moshi = Moshi.Builder().build()
|
val moshi = Moshi.Builder().build()
|
||||||
@@ -592,7 +595,7 @@ class GeneratedAdaptersTest {
|
|||||||
jsonAdapter.fromJson("{\"a\":null}")
|
jsonAdapter.fromJson("{\"a\":null}")
|
||||||
fail()
|
fail()
|
||||||
} catch (expected: JsonDataException) {
|
} catch (expected: JsonDataException) {
|
||||||
assertThat(expected).hasMessage("Unexpected null at \$.a")
|
assertThat(expected).hasMessage("Non-null value 'a' was null at \$.a")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1083,6 +1086,50 @@ class GeneratedAdaptersTest {
|
|||||||
assertThat(adapter.fromJson("null")).isNull()
|
assertThat(adapter.fromJson("null")).isNull()
|
||||||
assertThat(adapter.toJson(null)).isEqualTo("null")
|
assertThat(adapter.toJson(null)).isEqualTo("null")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
|
annotation class Nullable
|
||||||
|
|
||||||
|
@Test fun delegatesToInstalledAdaptersBeforeNullChecking() {
|
||||||
|
val moshi = Moshi.Builder()
|
||||||
|
.add(object {
|
||||||
|
@FromJson fun fromJson(@Nullable string: String?): String {
|
||||||
|
return string ?: "fallback"
|
||||||
|
}
|
||||||
|
|
||||||
|
@ToJson fun toJson(@Nullable value: String?): String {
|
||||||
|
return value ?: "fallback"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.build()
|
||||||
|
|
||||||
|
val hasNonNullConstructorParameterAdapter =
|
||||||
|
moshi.adapter(HasNonNullConstructorParameter::class.java)
|
||||||
|
assertThat(hasNonNullConstructorParameterAdapter
|
||||||
|
.fromJson("{\"a\":null}")).isEqualTo(HasNonNullConstructorParameter("fallback"))
|
||||||
|
|
||||||
|
val hasNullableConstructorParameterAdapter =
|
||||||
|
moshi.adapter(HasNullableConstructorParameter::class.java)
|
||||||
|
assertThat(hasNullableConstructorParameterAdapter
|
||||||
|
.fromJson("{\"a\":null}")).isEqualTo(HasNullableConstructorParameter("fallback"))
|
||||||
|
assertThat(hasNullableConstructorParameterAdapter
|
||||||
|
.toJson(HasNullableConstructorParameter(null))).isEqualTo("{\"a\":\"fallback\"}")
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonClass(generateAdapter = true)
|
||||||
|
data class HasNullableTypeWithGeneratedAdapter(val a: HasNonNullConstructorParameter?)
|
||||||
|
|
||||||
|
@Test fun delegatesToInstalledAdaptersBeforeNullCheckingWithGeneratedAdapter() {
|
||||||
|
val moshi = Moshi.Builder().build()
|
||||||
|
val adapter = moshi.adapter(HasNullableTypeWithGeneratedAdapter::class.java)
|
||||||
|
|
||||||
|
val encoded = HasNullableTypeWithGeneratedAdapter(null)
|
||||||
|
assertThat(adapter.toJson(encoded)).isEqualTo("""{}""")
|
||||||
|
assertThat(adapter.serializeNulls().toJson(encoded)).isEqualTo("""{"a":null}""")
|
||||||
|
|
||||||
|
val decoded = adapter.fromJson("""{"a":null}""")!!
|
||||||
|
assertThat(decoded.a).isEqualTo(null)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Has to be outside to avoid Types seeing an owning class
|
// Has to be outside to avoid Types seeing an owning class
|
||||||
|
@@ -170,7 +170,9 @@ class KotlinJsonAdapterTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class HasNonNullConstructorParameter(val a: String)
|
data class HasNonNullConstructorParameter(val a: String)
|
||||||
|
|
||||||
|
data class HasNullableConstructorParameter(val a: String?)
|
||||||
|
|
||||||
@Test fun nonNullPropertySetToNullFailsWithJsonDataException() {
|
@Test fun nonNullPropertySetToNullFailsWithJsonDataException() {
|
||||||
val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()
|
val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()
|
||||||
@@ -853,6 +855,31 @@ class KotlinJsonAdapterTest {
|
|||||||
assertThat(adapter.toJson(value)).isEqualTo(json)
|
assertThat(adapter.toJson(value)).isEqualTo(json)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Retention(RUNTIME)
|
||||||
|
annotation class Nullable
|
||||||
|
|
||||||
|
@Test fun delegatesToInstalledAdaptersBeforeNullChecking() {
|
||||||
|
val moshi = Moshi.Builder()
|
||||||
|
.add(object {
|
||||||
|
@FromJson fun fromJson(@Nullable string: String?): String {
|
||||||
|
return string ?: "fallback"
|
||||||
|
}
|
||||||
|
|
||||||
|
@ToJson fun toJson(@Nullable value: String?): String {
|
||||||
|
return value ?: "fallback"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.build()
|
||||||
|
|
||||||
|
assertThat(moshi.adapter(HasNonNullConstructorParameter::class.java)
|
||||||
|
.fromJson("{\"a\":null}")).isEqualTo(HasNonNullConstructorParameter("fallback"))
|
||||||
|
|
||||||
|
assertThat(moshi.adapter(HasNullableConstructorParameter::class.java)
|
||||||
|
.fromJson("{\"a\":null}")).isEqualTo(HasNullableConstructorParameter("fallback"))
|
||||||
|
assertThat(moshi.adapter(HasNullableConstructorParameter::class.java)
|
||||||
|
.toJson(HasNullableConstructorParameter(null))).isEqualTo("{\"a\":\"fallback\"}")
|
||||||
|
}
|
||||||
|
|
||||||
@Test fun mixingReflectionAndCodegen() {
|
@Test fun mixingReflectionAndCodegen() {
|
||||||
val moshi = Moshi.Builder()
|
val moshi = Moshi.Builder()
|
||||||
.add(KotlinJsonAdapterFactory())
|
.add(KotlinJsonAdapterFactory())
|
||||||
|
Reference in New Issue
Block a user