tschuchortdev / kotlin-compile-testing

A library for testing Kotlin and Java annotation processors, compiler plugins and code generation

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Java sources for testing KSP?

mars885 opened this issue · comments

Does the library support Java sources when testing KSP?

For example, this test passes and HiltBinderKspProcessorProvider.create runs when debugging:

@Test
fun `Test kotlin sources`() {
    val compilation = KotlinCompilation().apply {
        sources = listOf(
            kotlin("Testable.kt", "interface Testable"),
            kotlin(
                "Test.kt",
                """
                import com.paulrybitskyi.hiltbinder.BindType
    
                @BindType
                class Test : Testable
                """.trimIndent()
            )
        )
        symbolProcessorProviders = listOf(HiltBinderKspProcessorProvider())
        verbose = false
        inheritClassPath = true
    }
    val result = compilation.compile()
    val generatedModule = File(compilation.kspSourcesDir, "kotlin/HiltBinder_SingletonComponentModule.kt")

    assertThat(result.exitCode).isEqualTo(ExitCode.OK)
    assertThat(generatedModule.exists()).isTrue()
    assertThat(generatedModule.readText()).isEqualTo(
        """
        // Generated by @BindType. Do not modify!
        
        import dagger.Binds
        import dagger.Module
        import dagger.hilt.InstallIn
        import dagger.hilt.components.SingletonComponent

        @Module
        @InstallIn(SingletonComponent::class)
        public interface HiltBinder_SingletonComponentModule {
          @Binds
          public fun bind_Test(binding: Test): Testable
        }
        """.trimIndent()
    )
}

However, Java's analog of the above test fails and HiltBinderKspProcessorProvider.create does not run at all:

@Test
fun `Test java sources`() {
    val compilation = KotlinCompilation().apply {
        sources = listOf(
            java(
                "Testable.java",
                "public interface Testable {}"
            ),
            java(
                "Test.java",
                """
                import com.paulrybitskyi.hiltbinder.BindType;

                @BindType
                public class Test implements Testable {}
                """.trimIndent()
            )
        )
        symbolProcessorProviders = listOf(HiltBinderKspProcessorProvider())
        verbose = false
        inheritClassPath = true
    }
    val result = compilation.compile()
    val generatedModule = File(compilation.kspSourcesDir, "kotlin/HiltBinder_SingletonComponentModule.kt")

    assertThat(result.exitCode).isEqualTo(ExitCode.OK)
    assertThat(generatedModule.exists()).isTrue()
    assertThat(generatedModule.readText()).isEqualTo(
        """
        // Generated by @BindType. Do not modify!
        
        import dagger.Binds
        import dagger.Module
        import dagger.hilt.InstallIn
        import dagger.hilt.components.SingletonComponent

        @Module
        @InstallIn(SingletonComponent::class)
        public interface HiltBinder_SingletonComponentModule {
          @Binds
          public fun bind_Test(binding: Test): Testable
        }
        """.trimIndent()
    )
}

Doesn't the KSP support both kotlin and java sources? Am I doing something wrong? Thanks.

I don't use KSP myself so I don't know how far along the Java support is but I remember reading somewhere that it works with Java, too and https://github.com/google/ksp/76 suggests that it was implemented. Does your KSP processor work on Java files in a Gradle project? If so, then KCT should support it too. Apparently there are no tests for KSP and Java files right now, but I can say for sure that it works with KAPT. Unless you need to do something special for KSP, it should work there as well since the K2JVMCompiler always receives both Java and Kotlin source files.

I can confirm KSP can work on java sources but ignores them when using this project.

It's not that KSP ignores java sources, but that KSP isn't run when there are no kotlin sources. Workaround is to add a SourceFile.kotlin("Dummy.kt", "").

It's not that KSP ignores java sources, but that KSP isn't run when there are no kotlin sources. Workaround is to add a SourceFile.kotlin("Dummy.kt", "").

That does seem to work. Thanks.

Thanks for finding this out @F43nd1r. This is a trick we are already using for KAPT. I suppose it would make sense to also use it for the other call to K2JVMCompiler at least when compiler plugins are present.

Should be fixed in 143b175.