diff --git a/kotlin/src/main/java/com/squareup/moshi/KotlinJsonAdapter.kt b/kotlin/src/main/java/com/squareup/moshi/KotlinJsonAdapter.kt index 77a689e..bdecb4e 100644 --- a/kotlin/src/main/java/com/squareup/moshi/KotlinJsonAdapter.kt +++ b/kotlin/src/main/java/com/squareup/moshi/KotlinJsonAdapter.kt @@ -115,12 +115,6 @@ internal class KotlinJsonAdapter( val adapter: JsonAdapter

, val property: KProperty1, 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 set(result: K, value: P) { @@ -171,11 +165,13 @@ object KotlinJsonAdapterFactory : JsonAdapter.Factory { for (property in rawType.kotlin.memberProperties) { if (Modifier.isTransient(property.javaField?.modifiers ?: 0)) continue + val parameter = parametersByName[property.name] + if (property !is KMutableProperty1 && parameter == null) continue + property.isAccessible = true var allAnnotations = property.annotations var jsonAnnotation = property.findAnnotation() - val parameter = parametersByName[property.name] if (parameter != null) { allAnnotations += parameter.annotations if (jsonAnnotation == null) { diff --git a/kotlin/src/test/java/com/squareup/moshi/KotlinJsonAdapterTest.kt b/kotlin/src/test/java/com/squareup/moshi/KotlinJsonAdapterTest.kt index e3e87d8..9b4ce08 100644 --- a/kotlin/src/test/java/com/squareup/moshi/KotlinJsonAdapterTest.kt +++ b/kotlin/src/test/java/com/squareup/moshi/KotlinJsonAdapterTest.kt @@ -445,15 +445,17 @@ class KotlinJsonAdapterTest { } } - @Test fun unsettableProperty() { + @Test fun unsettablePropertyIgnored() { val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory).build() - try { - moshi.adapter(UnsettableProperty::class.java) - fail() - } catch(expected: IllegalArgumentException) { - assertThat(expected).hasMessage("No constructor or var property for " + - "val ${UnsettableProperty::class.qualifiedName}.a: kotlin.Int") - } + val jsonAdapter = moshi.adapter(UnsettableProperty::class.java) + + val encoded = UnsettableProperty() + encoded.b = 5 + assertThat(jsonAdapter.toJson(encoded)).isEqualTo("{\"b\":5}") + + val decoded = jsonAdapter.fromJson("{\"a\":4,\"b\":6}")!! + assertThat(decoded.a).isEqualTo(-1) + assertThat(decoded.b).isEqualTo(6) } class UnsettableProperty { @@ -461,6 +463,52 @@ class KotlinJsonAdapterTest { 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() { val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory).build() try {