mirror of
https://github.com/fankes/moshi.git
synced 2025-10-20 00:19:21 +08:00
Call Types.newParameterizedTypeWithOwner when necessary.
Otherwise we crash with an exception attempting to create an adapter for an enclosed type that has a type parameter. I ran into this looking for a test case for issue 615. https://github.com/square/moshi/issues/615
This commit is contained in:
@@ -66,12 +66,21 @@ abstract class TypeRenderer {
|
|||||||
Types::class,
|
Types::class,
|
||||||
render(typeName.typeArguments[0].objectType()))
|
render(typeName.typeArguments[0].objectType()))
|
||||||
} else {
|
} else {
|
||||||
val placeholders = typeName.typeArguments.joinToString(", ") { "%L" }
|
val builder = CodeBlock.builder().apply {
|
||||||
CodeBlock.of(
|
add("%T.", Types::class)
|
||||||
"%T.newParameterizedType(%T::class.java, $placeholders)",
|
val enclosingClassName = typeName.rawType.enclosingClassName()
|
||||||
Types::class,
|
if (enclosingClassName != null) {
|
||||||
typeName.rawType.objectType(),
|
add("newParameterizedTypeWithOwner(%L, ", render(enclosingClassName))
|
||||||
*(typeName.typeArguments.map { render(it.objectType()) }.toTypedArray()))
|
} else {
|
||||||
|
add("newParameterizedType(")
|
||||||
|
}
|
||||||
|
add("%T::class.java", typeName.rawType.objectType())
|
||||||
|
for (typeArgument in typeName.typeArguments) {
|
||||||
|
add(", %L", render(typeArgument.objectType()))
|
||||||
|
}
|
||||||
|
add(")")
|
||||||
|
}
|
||||||
|
builder.build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -28,6 +28,7 @@ import com.squareup.moshi.ToJson
|
|||||||
import com.squareup.moshi.Types
|
import com.squareup.moshi.Types
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import org.intellij.lang.annotations.Language
|
import org.intellij.lang.annotations.Language
|
||||||
|
import org.junit.Assert.assertNull
|
||||||
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
|
||||||
@@ -901,6 +902,55 @@ class GeneratedAdaptersTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test fun propertyIsNothing() {
|
||||||
|
val moshi = Moshi.Builder()
|
||||||
|
.add(NothingAdapter())
|
||||||
|
.build()
|
||||||
|
val jsonAdapter = moshi.adapter(HasNothingProperty::class.java).serializeNulls()
|
||||||
|
|
||||||
|
val toJson = HasNothingProperty()
|
||||||
|
toJson.a = "1"
|
||||||
|
assertThat(jsonAdapter.toJson(toJson)).isEqualTo("""{"a":"1","b":null}""")
|
||||||
|
|
||||||
|
val fromJson = jsonAdapter.fromJson("""{"a":"3","b":null}""")!!
|
||||||
|
assertThat(fromJson.a).isEqualTo("3")
|
||||||
|
assertNull(fromJson.b)
|
||||||
|
}
|
||||||
|
|
||||||
|
class NothingAdapter {
|
||||||
|
@ToJson fun toJson(jsonWriter: JsonWriter, unused: Nothing?) {
|
||||||
|
jsonWriter.nullValue()
|
||||||
|
}
|
||||||
|
|
||||||
|
@FromJson fun fromJson(jsonReader: JsonReader) : Nothing? {
|
||||||
|
jsonReader.skipValue()
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonClass(generateAdapter = true)
|
||||||
|
class HasNothingProperty {
|
||||||
|
var a: String? = null
|
||||||
|
var b: Nothing? = null
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test fun enclosedParameterizedType() {
|
||||||
|
val jsonAdapter = moshi.adapter(HasParameterizedProperty::class.java)
|
||||||
|
|
||||||
|
assertThat(jsonAdapter.toJson(HasParameterizedProperty(Twins("1", "2"))))
|
||||||
|
.isEqualTo("""{"twins":{"a":"1","b":"2"}}""")
|
||||||
|
|
||||||
|
val hasParameterizedProperty = jsonAdapter.fromJson("""{"twins":{"a":"3","b":"4"}}""")!!
|
||||||
|
assertThat(hasParameterizedProperty.twins.a).isEqualTo("3")
|
||||||
|
assertThat(hasParameterizedProperty.twins.b).isEqualTo("4")
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonClass(generateAdapter = true)
|
||||||
|
class Twins<T>(var a: T, var b: T)
|
||||||
|
|
||||||
|
@JsonClass(generateAdapter = true)
|
||||||
|
class HasParameterizedProperty(val twins: Twins<String>)
|
||||||
|
|
||||||
@JsonQualifier
|
@JsonQualifier
|
||||||
annotation class Uppercase(val inFrench: Boolean, val onSundays: Boolean = false)
|
annotation class Uppercase(val inFrench: Boolean, val onSundays: Boolean = false)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user