mcarleio/konvert

Collection mapping error using KSP2

Closed this issue · 5 comments

Hi,

I'm not sure whether this is a konvert or KSP2 issue.

I've switched our project experimentally to KSP2 beta and our build started failing with a strange error.

Considering the following example:

@Konverter
interface AMapper {
  fun map(domain: Domain): DTO
  fun map(domains: Collection<Domain>): List<DTO>
}

data class Domain(val prop: String)
data class DTO(val prop: String)

KSP version 2.0.20-1.0.25:

e: [ksp] java.util.NoSuchElementException: List is empty.

KSP version 2.0.20-1.0.24, 2.0.10-1.0.24:

e: [ksp] java.lang.IllegalArgumentException: Can't escape identifier `Collection<INVARIANT·Domain>` because it contains illegal characters: <>

I can not reproduce this error. I simply added your example code to the example code and updated the build.gradle.kts to kotlin 2.0.20 and ksp to 2.0.20-1.0.25. With that, it successfully generates the following code:

import io.mcarle.konvert.api.GeneratedKonverter
import kotlin.collections.Collection
import kotlin.collections.List

public class AMapperImpl : AMapper {
  @GeneratedKonverter(priority = 5_000)
  override fun map(domain: Domain): DTO = DTO(
    prop = domain.prop
  )

  @GeneratedKonverter(priority = 5_000)
  override fun map(domains: Collection<Domain>): List<DTO> = domains.map { this.map(domain = it) }
}

Please verify your example and provide further details if it still fails for you!

I checked out the example code and made also the updates to kotlin and ksp. This builds without any issues that version runs in KSP1 mode by default.

But as soon as I activate KSP2 mode the build fails. For the example code the failure is with 2.0.21-1.0.25 somewhere in the Spring examples:

> Task :kspKotlin FAILED
e: [ksp] java.lang.RuntimeException: Reflecting org.springframework.stereotype.Component[] failed!

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':kspKotlin'.
> A failure occurred while executing com.google.devtools.ksp.gradle.KspAAWorkerAction
   > Reflecting org.springframework.stereotype.Component[] failed!

Using version 2.0.21-1.0.26 it fails with the collection error on AMapper.

KSP2 mode is activated by setting ksp.useKSP2=true in gradle.properties of the project [1].

[1] https://github.com/google/ksp/blob/main/docs/ksp2.md

Ah... I forgot to activate KSP2, sorry! 😅 Thanks for pointing this out!

I will have a look into that, as KSP2 is the future.

Short update: KSP 1.0.25 has a bug that is fixed in 1.0.26, which was responsible for the org.springframework.stereotype.Component[] error.

I identified the problem with Collection<INVARIANT·Domain>. Back when I implemented the code that handles custom alias, I had not find a better way than comparing Strings to identify if the source contained a custom alias to reuse in the generated code. This broke with KSP2.
I did a quick fix of this, but there might be other places that have changed behavior in KSP2 which might result in exceptions or wrong behavior. Although Konvert has a lot of tests, I have no good idea yet how/if it is possible to run them in KSP1 and KSP2 mode, to ensure Konvert is working in both modes...

Thank you for the quick fix.