Merge pull request #627 from square/eric.2018-08-17.boxed-primitive-adapters

Make nullable primitives in codegen use boxed type adapters.
This commit is contained in:
Jesse Wilson
2018-08-19 07:36:12 -04:00
committed by GitHub
3 changed files with 76 additions and 0 deletions

View File

@@ -43,6 +43,16 @@ abstract class TypeRenderer {
fun render(typeName: TypeName): CodeBlock {
if (typeName.nullable) {
if (typeName == BOOLEAN.asNullable()
|| typeName == BYTE.asNullable()
|| typeName == CHAR.asNullable()
|| typeName == DOUBLE.asNullable()
|| typeName == FLOAT.asNullable()
|| typeName == INT.asNullable()
|| typeName == LONG.asNullable()
|| typeName == SHORT.asNullable()) {
return CodeBlock.of("%T::class.javaObjectType", typeName.asNonNullable())
}
return render(typeName.asNonNullable())
}

View File

@@ -17,9 +17,12 @@ package com.squareup.moshi.kotlin.codgen
import com.squareup.moshi.FromJson
import com.squareup.moshi.Json
import com.squareup.moshi.JsonAdapter
import com.squareup.moshi.JsonClass
import com.squareup.moshi.JsonDataException
import com.squareup.moshi.JsonQualifier
import com.squareup.moshi.JsonReader
import com.squareup.moshi.JsonWriter
import com.squareup.moshi.Moshi
import com.squareup.moshi.ToJson
import com.squareup.moshi.Types
@@ -28,6 +31,7 @@ import org.intellij.lang.annotations.Language
import org.junit.Assert.fail
import org.junit.Ignore
import org.junit.Test
import java.lang.reflect.Type
import java.util.Locale
class GeneratedAdaptersTest {
@@ -865,6 +869,36 @@ class GeneratedAdaptersTest {
return s.toLowerCase(Locale.US)
}
}
@JsonClass(generateAdapter = true)
data class HasNullableBoolean(val boolean: Boolean?)
@Test fun nullablePrimitivesUseBoxedPrimitiveAdapters() {
val moshi = Moshi.Builder()
.add(JsonAdapter.Factory { type, annotations, moshi ->
if (Boolean::class.javaObjectType == type) {
return@Factory object:JsonAdapter<Boolean?>() {
override fun fromJson(reader: JsonReader): Boolean? {
if (reader.peek() != JsonReader.Token.BOOLEAN) {
reader.skipValue()
return null
}
return reader.nextBoolean()
}
override fun toJson(writer: JsonWriter, value: Boolean?) {
writer.value(value)
}
}
}
null
})
.build()
val adapter = moshi.adapter(HasNullableBoolean::class.java).serializeNulls()
assertThat(adapter.fromJson("""{"boolean":"not a boolean"}"""))
.isEqualTo(HasNullableBoolean(null))
assertThat(adapter.toJson(HasNullableBoolean(null))).isEqualTo("""{"boolean":null}""")
}
}
// Has to be outside to avoid Types seeing an owning class

View File

@@ -17,9 +17,12 @@ package com.squareup.moshi.kotlin.reflect
import com.squareup.moshi.FromJson
import com.squareup.moshi.Json
import com.squareup.moshi.JsonAdapter
import com.squareup.moshi.JsonClass
import com.squareup.moshi.JsonDataException
import com.squareup.moshi.JsonQualifier
import com.squareup.moshi.JsonReader
import com.squareup.moshi.JsonWriter
import com.squareup.moshi.Moshi
import com.squareup.moshi.ToJson
import com.squareup.moshi.Types
@@ -881,4 +884,33 @@ class KotlinJsonAdapterTest {
return s.toLowerCase(Locale.US)
}
}
data class HasNullableBoolean(val boolean: Boolean?)
@Test fun nullablePrimitivesUseBoxedPrimitiveAdapters() {
val moshi = Moshi.Builder()
.add(JsonAdapter.Factory { type, annotations, moshi ->
if (Boolean::class.javaObjectType == type) {
return@Factory object: JsonAdapter<Boolean?>() {
override fun fromJson(reader: JsonReader): Boolean? {
if (reader.peek() != JsonReader.Token.BOOLEAN) {
reader.skipValue()
return null
}
return reader.nextBoolean()
}
override fun toJson(writer: JsonWriter, value: Boolean?) {
writer.value(value)
}
}
}
null
})
.build()
val adapter = moshi.adapter(HasNullableBoolean::class.java).serializeNulls()
assertThat(adapter.fromJson("""{"boolean":"not a boolean"}"""))
.isEqualTo(HasNullableBoolean(null))
assertThat(adapter.toJson(HasNullableBoolean(null))).isEqualTo("""{"boolean":null}""")
}
}