Add @Json.ignore (#1417)

* Default Json.name to an unset value

* Promote shared transient tests to DualKotlinTest

* Add new ignore property to Json

* Support it in ClassJsonAdapter

* Mention no enum/record support

* Support in KotlinJsonAdapter

* Rework code gen API to know of "ignored"

* Support in apt code gen

* Support in KSP

* Update old non-working transient example test

* Synthetic holders

* Use field on both
This commit is contained in:
Zac Sweers
2021-11-08 11:16:57 -05:00
committed by GitHub
parent 48e6dd3f03
commit 954ca46b9e
19 changed files with 317 additions and 108 deletions

View File

@@ -17,3 +17,7 @@
plugins {
kotlin("jvm")
}
dependencies {
implementation(project(":moshi"))
}

View File

@@ -15,10 +15,14 @@
*/
package com.squareup.moshi.kotlin.codegen.test.extra
import com.squareup.moshi.Json
public abstract class AbstractClassInModuleA {
// Transients to ensure processor sees them across module boundaries since @Transient is
// SOURCE-only
// TODO uncomment these when https://github.com/google/ksp/issues/710 is fixed
// @Transient private lateinit var lateinitTransient: String
// @Transient private var regularTransient: String = "regularTransient"
// Ignored to ensure processor sees them across module boundaries.
// @Transient doesn't work for this case because it's source-only and jvm modifiers aren't currently visible in KSP.
// Note that we target the field because otherwise it is stored on the synthetic holder method for
// annotations, which isn't visible from kapt
@field:Json(ignore = true) private lateinit var lateinitIgnored: String
@field:Json(ignore = true) private var regularIgnored: String = "regularIgnored"
}

View File

@@ -625,6 +625,124 @@ class DualKotlinTest {
data class IntersectionTypes<E>(
val value: E
) where E : Enum<E>, E : IntersectionTypeInterface<E>
@Test fun transientConstructorParameter() {
val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()
val jsonAdapter = moshi.adapter<TransientConstructorParameter>()
val encoded = TransientConstructorParameter(3, 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 TransientConstructorParameter(@Transient var a: Int = -1, var b: Int = -1)
@Test fun multipleTransientConstructorParameters() {
val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()
val jsonAdapter = moshi.adapter(MultipleTransientConstructorParameters::class.java)
val encoded = MultipleTransientConstructorParameters(3, 5, 7)
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)
assertThat(decoded.c).isEqualTo(-1)
}
class MultipleTransientConstructorParameters(@Transient var a: Int = -1, var b: Int = -1, @Transient var c: Int = -1)
@Test fun transientProperty() {
val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()
val jsonAdapter = moshi.adapter<TransientProperty>()
val encoded = TransientProperty()
encoded.a = 3
encoded.setB(4)
encoded.c = 5
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("""{"c":5}""")
val decoded = jsonAdapter.fromJson("""{"a":4,"b":5,"c":6}""")!!
assertThat(decoded.a).isEqualTo(-1)
assertThat(decoded.getB()).isEqualTo(-1)
assertThat(decoded.c).isEqualTo(6)
}
class TransientProperty {
@Transient var a: Int = -1
@Transient private var b: Int = -1
var c: Int = -1
fun getB() = b
fun setB(b: Int) {
this.b = b
}
}
@Test fun ignoredConstructorParameter() {
val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()
val jsonAdapter = moshi.adapter<IgnoredConstructorParameter>()
val encoded = IgnoredConstructorParameter(3, 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 IgnoredConstructorParameter(@Json(ignore = true) var a: Int = -1, var b: Int = -1)
@Test fun multipleIgnoredConstructorParameters() {
val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()
val jsonAdapter = moshi.adapter(MultipleIgnoredConstructorParameters::class.java)
val encoded = MultipleIgnoredConstructorParameters(3, 5, 7)
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)
assertThat(decoded.c).isEqualTo(-1)
}
class MultipleIgnoredConstructorParameters(
@Json(ignore = true) var a: Int = -1,
var b: Int = -1,
@Json(ignore = true) var c: Int = -1
)
@Test fun ignoredProperty() {
val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()
val jsonAdapter = moshi.adapter<IgnoredProperty>()
val encoded = IgnoredProperty()
encoded.a = 3
encoded.setB(4)
encoded.c = 5
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("""{"c":5}""")
val decoded = jsonAdapter.fromJson("""{"a":4,"b":5,"c":6}""")!!
assertThat(decoded.a).isEqualTo(-1)
assertThat(decoded.getB()).isEqualTo(-1)
assertThat(decoded.c).isEqualTo(6)
}
class IgnoredProperty {
@Json(ignore = true) var a: Int = -1
@Json(ignore = true) private var b: Int = -1
var c: Int = -1
fun getB() = b
fun setB(b: Int) {
this.b = b
}
}
}
typealias TypeAlias = Int

View File

@@ -278,35 +278,6 @@ class KotlinJsonAdapterTest {
var b: Int = -1
}
@Test fun transientConstructorParameter() {
val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()
val jsonAdapter = moshi.adapter<TransientConstructorParameter>()
val encoded = TransientConstructorParameter(3, 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 TransientConstructorParameter(@Transient var a: Int = -1, var b: Int = -1)
@Test fun multipleTransientConstructorParameters() {
val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()
val jsonAdapter = moshi.adapter(MultipleTransientConstructorParameters::class.java)
val encoded = MultipleTransientConstructorParameters(3, 5, 7)
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)
assertThat(decoded.c).isEqualTo(-1)
}
class MultipleTransientConstructorParameters(@Transient var a: Int = -1, var b: Int = -1, @Transient var c: Int = -1)
@Test fun requiredTransientConstructorParameterFails() {
val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()
try {
@@ -323,34 +294,22 @@ class KotlinJsonAdapterTest {
class RequiredTransientConstructorParameter(@Transient var a: Int)
@Test fun transientProperty() {
@Test fun requiredIgnoredConstructorParameterFails() {
val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()
val jsonAdapter = moshi.adapter<TransientProperty>()
val encoded = TransientProperty()
encoded.a = 3
encoded.setB(4)
encoded.c = 5
assertThat(jsonAdapter.toJson(encoded)).isEqualTo("""{"c":5}""")
val decoded = jsonAdapter.fromJson("""{"a":4,"b":5,"c":6}""")!!
assertThat(decoded.a).isEqualTo(-1)
assertThat(decoded.getB()).isEqualTo(-1)
assertThat(decoded.c).isEqualTo(6)
}
class TransientProperty {
@Transient var a: Int = -1
@Transient private var b: Int = -1
var c: Int = -1
fun getB() = b
fun setB(b: Int) {
this.b = b
try {
moshi.adapter<RequiredIgnoredConstructorParameter>()
fail()
} catch (expected: IllegalArgumentException) {
assertThat(expected).hasMessageThat().isEqualTo(
"No default value for ignored constructor parameter #0 " +
"a of fun <init>(kotlin.Int): " +
"com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterTest.RequiredIgnoredConstructorParameter"
)
}
}
class RequiredIgnoredConstructorParameter(@Json(ignore = true) var a: Int)
@Test fun constructorParametersAndPropertiesWithSameNamesMustHaveSameTypes() {
val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()
try {