Skip to content

[ver. 1.14.0] Adapter generation fails if JsonQualifier has nested annotations #1581

Open

Description

@lev-zakaryan

Minimal setup to reproduce:

@JsonClass(generateAdapter = true)
data class MessageConnectionTest(
    @DecodeTypesTest(
        DecodeTypeTest("TextMessage")
    )
    var node: String? = null
)

@JsonQualifier
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FIELD)
annotation class DecodeTypesTest(
    vararg val value: DecodeTypeTest
)

@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FIELD)
annotation class DecodeTypeTest(val name: String)

Moshi 1.12.0 + kotlin 1.5.0 + kapt generates proper adapter with the following internal val (full generated adapter attached in zip):

  @field:DecodeTypesTest(value = [DecodeTypeTest(name = "TextMessage")])
  private val nullableStringAtDecodeTypesTestAdapter: JsonAdapter<String?> =
      moshi.adapter(String::class.java, Types.getFieldJsonQualifierAnnotations(javaClass,
      "nullableStringAtDecodeTypesTestAdapter"), "node")

Moshi 1.14.0 + kotlin 1.6.21 + kapt generates adapter with the following internal val (this generated adapter also attached in zip):

  private val nullableStringAtDecodeTypesTestAdapter: JsonAdapter<String?> =
      moshi.adapter(String::class.java, setOf(DecodeTypesTest(value = arrayOf(@DecodeTypeTest(name =
      "TextMessage")))), "node")

Compilation of this code fails with an error "Expecting an element", because "@DecodeTypeTest" was generated instead of "DecodeTypeTest".

generated_adapters_OK_and_FAILED.zip

Activity

  1. lev-zakaryan commented on Mar 13, 2023

    @lev-zakaryan
    Author

    Here is a simple test for JsonClassCodegenProcessorTest.kt to reproduce the problem in moshi 1.14:

      @Test
      fun nestedAnnotationsTest() {
        val result = compile(
          kotlin(
            "source.kt",
            """
              import com.squareup.moshi.JsonClass
              import com.squareup.moshi.JsonQualifier
              import kotlin.annotation.AnnotationRetention.RUNTIME
              import kotlin.annotation.AnnotationTarget.FIELD
              import kotlin.annotation.Retention
              import kotlin.annotation.Target
              import kotlin.reflect.KClass
    
              @JsonClass(generateAdapter = true)
              class TestAdapterClass(
                  @OuterAnnotation(
                    InnerAnnotation("first"),
                    InnerAnnotation("second"),
                    InnerAnnotation("third")
                  )
                  var param: String
              )
    
              @JsonQualifier
              @Retention(RUNTIME)
              @Target(FIELD)
              annotation class OuterAnnotation(
                  vararg val values: InnerAnnotation
              )
    
              @Retention(RUNTIME)
              @Target(FIELD)
              annotation class InnerAnnotation(val name: String)
              """,
          ),
        )
        assertThat(result.exitCode).isEqualTo(KotlinCompilation.ExitCode.OK)
      }
    
  2. lev-zakaryan commented on Mar 16, 2023

    @lev-zakaryan
    Author

    The problem seems to appear because of commit 7355328

    Specifically, this change to DelegateKey:
    7355328#diff-38d9cd4fce3da293198ab776387c064107fd9da2b3ded024807af16cea91a12a

    This changes the output of generated output, now a set of instantiated annotations are passed to moshi instead of Types.getFieldJsonQualifierAnnotations

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions