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 { fun render(typeName: TypeName): CodeBlock {
if (typeName.nullable) { 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()) 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.FromJson
import com.squareup.moshi.Json import com.squareup.moshi.Json
import com.squareup.moshi.JsonAdapter
import com.squareup.moshi.JsonClass import com.squareup.moshi.JsonClass
import com.squareup.moshi.JsonDataException import com.squareup.moshi.JsonDataException
import com.squareup.moshi.JsonQualifier import com.squareup.moshi.JsonQualifier
import com.squareup.moshi.JsonReader
import com.squareup.moshi.JsonWriter
import com.squareup.moshi.Moshi import com.squareup.moshi.Moshi
import com.squareup.moshi.ToJson import com.squareup.moshi.ToJson
import com.squareup.moshi.Types import com.squareup.moshi.Types
@@ -28,6 +31,7 @@ import org.intellij.lang.annotations.Language
import org.junit.Assert.fail import org.junit.Assert.fail
import org.junit.Ignore import org.junit.Ignore
import org.junit.Test import org.junit.Test
import java.lang.reflect.Type
import java.util.Locale import java.util.Locale
class GeneratedAdaptersTest { class GeneratedAdaptersTest {
@@ -865,6 +869,36 @@ class GeneratedAdaptersTest {
return s.toLowerCase(Locale.US) 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 // 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.FromJson
import com.squareup.moshi.Json import com.squareup.moshi.Json
import com.squareup.moshi.JsonAdapter
import com.squareup.moshi.JsonClass import com.squareup.moshi.JsonClass
import com.squareup.moshi.JsonDataException import com.squareup.moshi.JsonDataException
import com.squareup.moshi.JsonQualifier import com.squareup.moshi.JsonQualifier
import com.squareup.moshi.JsonReader
import com.squareup.moshi.JsonWriter
import com.squareup.moshi.Moshi import com.squareup.moshi.Moshi
import com.squareup.moshi.ToJson import com.squareup.moshi.ToJson
import com.squareup.moshi.Types import com.squareup.moshi.Types
@@ -881,4 +884,33 @@ class KotlinJsonAdapterTest {
return s.toLowerCase(Locale.US) 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}""")
}
} }