Merge pull request #300 from square/jwilson.0507.synthetic_properties

Support more kinds of properties in KotlinJsonAdapter
This commit is contained in:
Jake Wharton
2017-05-07 17:31:21 -04:00
committed by GitHub
2 changed files with 59 additions and 15 deletions

View File

@@ -115,12 +115,6 @@ internal class KotlinJsonAdapter<T>(
val adapter: JsonAdapter<P>, val adapter: JsonAdapter<P>,
val property: KProperty1<K, P>, val property: KProperty1<K, P>,
val parameter: KParameter?) { val parameter: KParameter?) {
init {
if (property !is KMutableProperty1 && parameter == null) {
throw IllegalArgumentException("No constructor or var property for ${property}")
}
}
fun get(value: K) = property.get(value) fun get(value: K) = property.get(value)
fun set(result: K, value: P) { fun set(result: K, value: P) {
@@ -171,11 +165,13 @@ object KotlinJsonAdapterFactory : JsonAdapter.Factory {
for (property in rawType.kotlin.memberProperties) { for (property in rawType.kotlin.memberProperties) {
if (Modifier.isTransient(property.javaField?.modifiers ?: 0)) continue if (Modifier.isTransient(property.javaField?.modifiers ?: 0)) continue
val parameter = parametersByName[property.name]
if (property !is KMutableProperty1 && parameter == null) continue
property.isAccessible = true property.isAccessible = true
var allAnnotations = property.annotations var allAnnotations = property.annotations
var jsonAnnotation = property.findAnnotation<Json>() var jsonAnnotation = property.findAnnotation<Json>()
val parameter = parametersByName[property.name]
if (parameter != null) { if (parameter != null) {
allAnnotations += parameter.annotations allAnnotations += parameter.annotations
if (jsonAnnotation == null) { if (jsonAnnotation == null) {

View File

@@ -445,15 +445,17 @@ class KotlinJsonAdapterTest {
} }
} }
@Test fun unsettableProperty() { @Test fun unsettablePropertyIgnored() {
val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory).build() val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory).build()
try { val jsonAdapter = moshi.adapter(UnsettableProperty::class.java)
moshi.adapter(UnsettableProperty::class.java)
fail() val encoded = UnsettableProperty()
} catch(expected: IllegalArgumentException) { encoded.b = 5
assertThat(expected).hasMessage("No constructor or var property for " + assertThat(jsonAdapter.toJson(encoded)).isEqualTo("{\"b\":5}")
"val ${UnsettableProperty::class.qualifiedName}.a: kotlin.Int")
} val decoded = jsonAdapter.fromJson("{\"a\":4,\"b\":6}")!!
assertThat(decoded.a).isEqualTo(-1)
assertThat(decoded.b).isEqualTo(6)
} }
class UnsettableProperty { class UnsettableProperty {
@@ -461,6 +463,52 @@ class KotlinJsonAdapterTest {
var b: Int = -1 var b: Int = -1
} }
@Test fun getterOnlyNoBackingField() {
val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory).build()
val jsonAdapter = moshi.adapter(GetterOnly::class.java)
val encoded = GetterOnly(3, 5)
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("{\"a\":3,\"b\":5}")
val decoded = jsonAdapter.fromJson("{\"a\":4,\"b\":6}")!!
assertThat(decoded.a).isEqualTo(4)
assertThat(decoded.b).isEqualTo(6)
assertThat(decoded.total).isEqualTo(10)
}
class GetterOnly(var a: Int, var b: Int) {
val total : Int
get() = a + b
}
@Test fun getterAndSetterNoBackingField() {
val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory).build()
val jsonAdapter = moshi.adapter(GetterAndSetter::class.java)
val encoded = GetterAndSetter(3, 5)
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("{\"a\":3,\"b\":5,\"total\":8}")
// Whether b is 6 or 7 is an implementation detail. Currently we call constructors then setters.
val decoded1 = jsonAdapter.fromJson("{\"a\":4,\"b\":6,\"total\":11}")!!
assertThat(decoded1.a).isEqualTo(4)
assertThat(decoded1.b).isEqualTo(7)
assertThat(decoded1.total).isEqualTo(11)
// Whether b is 6 or 7 is an implementation detail. Currently we call constructors then setters.
val decoded2 = jsonAdapter.fromJson("{\"a\":4,\"total\":11,\"b\":6}")!!
assertThat(decoded2.a).isEqualTo(4)
assertThat(decoded2.b).isEqualTo(7)
assertThat(decoded2.total).isEqualTo(11)
}
class GetterAndSetter(var a: Int, var b: Int) {
var total : Int
get() = a + b
set(value) {
b = value - a
}
}
@Test fun nonPropertyConstructorParameter() { @Test fun nonPropertyConstructorParameter() {
val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory).build() val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory).build()
try { try {