From 60670b3f999a287251265e7bcfbf2f4e78a4dc1c Mon Sep 17 00:00:00 2001 From: Sebastian Zalewski <49704887+zalewskise@users.noreply.github.com> Date: Tue, 30 Apr 2024 21:30:05 +0200 Subject: [PATCH] Add support for generated Java code with KSP (#1139) * Add support for generating Java code with KSP * Add dagger to ksp sample project * Run java compilation action only when ksp generates java * Update ksp tests --- MODULE.bazel | 6 +- docs/kotlin.md | 4 +- examples/ksp/BUILD | 148 +++++++------- examples/ksp/CoffeeApp.kt | 23 ++- examples/ksp/CoffeeMaker.kt | 40 ++++ examples/ksp/DripCoffeeModule.kt | 29 +++ examples/ksp/ElectricHeater.kt | 29 +++ examples/ksp/Heater.kt | 22 +++ examples/ksp/Pump.kt | 20 ++ examples/ksp/PumpModule.kt | 25 +++ examples/ksp/Thermosiphon.kt | 28 +++ examples/ksp/WORKSPACE | 12 +- examples/ksp/third_party/BUILD.bazel | 90 +++++++++ kotlin/internal/jvm/BUILD | 4 +- kotlin/internal/jvm/BUILD.release.bazel | 2 +- kotlin/internal/jvm/compile.bzl | 8 +- kotlin/internal/jvm/impl.bzl | 62 +++--- kotlin/internal/jvm/jetbrains-deshade.jarjar | 2 - kotlin/internal/jvm/jvm.bzl | 21 +- .../jvm/kotlin-compiler-reshade.jarjar | 3 + kotlin/internal/jvm/plugins.bzl | 7 + kotlin_rules_maven_install.json | 180 +++++++++--------- .../builder/tasks/jvm/CompilationTask.kt | 1 + src/main/starlark/core/plugin/providers.bzl | 1 + src/main/starlark/core/repositories/setup.bzl | 6 +- src/test/data/jvm/ksp/BUILD | 108 ++++++++++- src/test/data/jvm/ksp/CoffeeApp.kt | 17 +- src/test/data/jvm/ksp/CoffeeBean.java | 7 + src/test/data/jvm/ksp/CoffeeMaker.kt | 30 +++ src/test/data/jvm/ksp/DripCoffeeModule.kt | 48 +++++ .../bazel/kotlin/KotlinJvmKspAssertionTest.kt | 104 ++++++++-- 31 files changed, 839 insertions(+), 248 deletions(-) create mode 100644 examples/ksp/CoffeeMaker.kt create mode 100644 examples/ksp/DripCoffeeModule.kt create mode 100644 examples/ksp/ElectricHeater.kt create mode 100644 examples/ksp/Heater.kt create mode 100644 examples/ksp/Pump.kt create mode 100644 examples/ksp/PumpModule.kt create mode 100644 examples/ksp/Thermosiphon.kt create mode 100644 examples/ksp/third_party/BUILD.bazel delete mode 100644 kotlin/internal/jvm/jetbrains-deshade.jarjar create mode 100644 kotlin/internal/jvm/kotlin-compiler-reshade.jarjar create mode 100644 src/test/data/jvm/ksp/CoffeeBean.java create mode 100644 src/test/data/jvm/ksp/CoffeeMaker.kt create mode 100644 src/test/data/jvm/ksp/DripCoffeeModule.kt diff --git a/MODULE.bazel b/MODULE.bazel index c125a9b56..ccff54660 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -63,9 +63,9 @@ maven.install( "com.google.auto.service:auto-service-annotations:1.0.1", "com.google.auto.value:auto-value:1.10.1", "com.google.auto.value:auto-value-annotations:1.10.1", - "com.google.dagger:dagger:2.43.2", - "com.google.dagger:dagger-compiler:2.43.2", - "com.google.dagger:dagger-producers:2.43.2", + "com.google.dagger:dagger:2.51", + "com.google.dagger:dagger-compiler:2.51", + "com.google.dagger:dagger-producers:2.51", "javax.annotation:javax.annotation-api:1.3.2", "javax.inject:javax.inject:1", "org.pantsbuild:jarjar:1.7.2", diff --git a/docs/kotlin.md b/docs/kotlin.md index 446674080..6bbde134d 100755 --- a/docs/kotlin.md +++ b/docs/kotlin.md @@ -448,7 +448,7 @@ kt_kotlinc_options(name, name, deps, processor_class) +kt_ksp_plugin(name, deps, generates_java, processor_class, target_embedded_compiler) Define a KSP plugin for the Kotlin compiler to run. The plugin can then be referenced in the `plugins` attribute @@ -481,7 +481,9 @@ kt_ksp_plugin(name, name | A unique name for this target. | Name | required | | |deps | The list of libraries to be added to the compiler's plugin classpath | List of labels | optional | [] | +|generates_java | Runs Java compilation action for plugin generating Java output. | Boolean | optional | False | |processor_class | The fully qualified class name that the Java compiler uses as an entry point to the annotation processor. | String | required | | +|target_embedded_compiler | Plugin was compiled against the embeddable kotlin compiler. These plugins expect shaded kotlinc dependencies, and will fail when running against a non-embeddable compiler. | Boolean | optional | False | diff --git a/examples/ksp/BUILD b/examples/ksp/BUILD index 6722c96f2..3105bf80c 100644 --- a/examples/ksp/BUILD +++ b/examples/ksp/BUILD @@ -1,5 +1,5 @@ load("@bazel_skylib//rules:build_test.bzl", "build_test") -load("@rules_java//java:defs.bzl", "java_binary", "java_plugin") +load("@rules_java//java:defs.bzl", "java_binary") # Copyright 2018 The Bazel Authors. All rights reserved. # @@ -14,37 +14,73 @@ load("@rules_java//java:defs.bzl", "java_binary", "java_plugin") # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -load("@rules_kotlin//kotlin:core.bzl", "define_kt_toolchain", "kt_compiler_plugin", "kt_ksp_plugin", "kt_plugin_cfg") +load("@rules_kotlin//kotlin:core.bzl", "define_kt_toolchain") load("@rules_kotlin//kotlin:jvm.bzl", "kt_jvm_library") package(default_visibility = ["//visibility:public"]) define_kt_toolchain(name = "kotlin_toolchain") -java_plugin( - name = "autovalue", - generates_api = True, - processor_class = "com.google.auto.value.processor.AutoValueProcessor", - deps = ["@maven//:com_google_auto_value_auto_value"], +# Generate a srcjar to validate intellij plugin correctly attaches it. +genrule( + name = "tea_lib_src", + outs = ["tea_lib_src.srcjar"], + cmd = """ +cat << EOF > TeaPot.kt +package tea +object TeaPot { + fun isEmpty() = true +} +EOF +$(JAVABASE)/bin/jar -cf $@ TeaPot.kt +rm TeaPot.kt +""", + toolchains = ["@bazel_tools//tools/jdk:current_host_java_runtime"], ) -kt_ksp_plugin( - name = "moshi-kotlin-codegen", - processor_class = "com.squareup.moshi.kotlin.codegen.ksp.JsonClassSymbolProcessorProvider", - deps = [ - "@maven//:com_squareup_moshi_moshi", - "@maven//:com_squareup_moshi_moshi_kotlin", - "@maven//:com_squareup_moshi_moshi_kotlin_codegen", - ], +genrule( + name = "chai_lib_src", + outs = ["chai_lib_src.srcjar"], + cmd = """ +cat << EOF > ChaiCup.kt +package chai +object ChaiCup { + fun isEmpty() = true +} +EOF +$(JAVABASE)/bin/jar -cf $@ ChaiCup.kt +rm ChaiCup.kt +""", + toolchains = ["@bazel_tools//tools/jdk:current_host_java_runtime"], ) -kt_ksp_plugin( - name = "autoservice", - processor_class = "dev.zacsweers.autoservice.ksp.AutoServiceSymbolProcessor$Provider", - deps = [ - "@maven//:com_google_auto_service_auto_service_annotations", - "@maven//:dev_zacsweers_autoservice_auto_service_ksp", - ], +genrule( + name = "genereated_module_src", + outs = ["genarated_module_src.srcjar"], + cmd = """ +cat << EOF > GeneratedModule.kt +package generated + +import dagger.Provides +import dagger.Module + +@Module +object GeneratedModule { + @Provides + fun provideString() = "Hello Coffee" +} +EOF +$(JAVABASE)/bin/jar -cf $@ GeneratedModule.kt +rm GeneratedModule.kt +""", + toolchains = ["@bazel_tools//tools/jdk:current_host_java_runtime"], +) + +kt_jvm_library( + name = "generated_lib", + srcs = [":genereated_module_src"], + plugins = ["//third_party:dagger_ksp_plugin"], + deps = ["@maven//:com_google_dagger_dagger"], ) kt_jvm_library( @@ -52,17 +88,25 @@ kt_jvm_library( srcs = glob([ "*.kt", "*.java", - ]), + ]) + [ + # Adding a file ending with .srcjar is how code generation patterns are implemented. + ":tea_lib_src", + ":chai_lib_src", + ], plugins = [ - "//:moshi-kotlin-codegen", - "//:autovalue", - "//:autoservice", + "//third_party:dagger_ksp_plugin", + "//third_party:moshi-kotlin-codegen", + "//third_party:autovalue", + "//third_party:autoservice", ], deps = [ + ":generated_lib", "@maven//:com_google_auto_service_auto_service_annotations", "@maven//:com_google_auto_value_auto_value_annotations", + "@maven//:com_google_dagger_dagger", "@maven//:com_squareup_moshi_moshi", "@maven//:com_squareup_moshi_moshi_kotlin", + "@maven//:org_jetbrains_kotlinx_kotlinx_coroutines_core", ], ) @@ -82,60 +126,12 @@ build_test( ], ) -kt_compiler_plugin( - name = "ksp", - compile_phase = True, - id = "com.google.devtools.ksp.symbol-processing", - options = { - "apclasspath": "{classpath}", - # projectBaseDir shouldn't matter because incremental is disabled - "projectBaseDir": "{temp}", - # Disable incremental mode - "incremental": "false", - # Directory where class files are written to. Files written to this directory are class - # files being written directly from the annotation processor, not Kotlinc - "classOutputDir": "{generatedClasses}", - # Directory where generated Java sources files are written to - "javaOutputDir": "{generatedSources}", - # Directory where generated Kotlin sources files are written to - "kotlinOutputDir": "{generatedSources}", - # Directory where META-INF data is written to. This might not be the most ideal place to - # write this. Maybe just directly to the classes directory? - "resourceOutputDir": "{generatedSources}", - # TODO(bencodes) Not sure what this directory is yet. - "kspOutputDir": "{temp}", - # Directory to write KSP caches. Shouldn't matter because incremental is disabled - "cachesDir": "{temp}", - # Include in compilation as an example. This should be processed in the stubs phase. - "withCompilation": "true", - # Set returnOkOnError to false because we want to fail the build if there are any errors - "returnOkOnError": "false", - "allWarningsAsErrors": "false", - }, - deps = [ - "@rules_kotlin//kotlin/compiler:symbol-processing-api", - "@rules_kotlin//kotlin/compiler:symbol-processing-cmdline", - ], -) - -kt_plugin_cfg( - name = "ksp_moshi", - options = { - }, - plugin = ":ksp", - deps = [ - "@maven//:com_squareup_moshi_moshi", - "@maven//:com_squareup_moshi_moshi_kotlin", - "@maven//:com_squareup_moshi_moshi_kotlin_codegen", - ], -) - kt_jvm_library( name = "raw_ksp_coffee_app_lib", srcs = ["CoffeeAppModel.kt"], plugins = [ - "//:ksp", - "//:ksp_moshi", + "//third_party:ksp", + "//third_party:ksp_moshi", ], deps = [ "@maven//:com_google_auto_service_auto_service_annotations", diff --git a/examples/ksp/CoffeeApp.kt b/examples/ksp/CoffeeApp.kt index a0c0f4d9e..70f36adc1 100644 --- a/examples/ksp/CoffeeApp.kt +++ b/examples/ksp/CoffeeApp.kt @@ -16,9 +16,21 @@ package coffee import com.squareup.moshi.Moshi +import generated.GeneratedModule +import dagger.Component +import kotlinx.coroutines.runBlocking +import tea.TeaPot +import chai.ChaiCup +import javax.inject.Singleton class CoffeeApp { + @Singleton + @Component(modules = [DripCoffeeModule::class, GeneratedModule::class]) + interface CoffeeShop { + fun maker(): CoffeeMaker + } + companion object { private val adapter = CoffeeAppModelJsonAdapter(Moshi.Builder().build()) @@ -28,9 +40,14 @@ class CoffeeApp { @JvmStatic fun main(args: Array) { - println( - adapter.toJson(d.coffeeAppModel()) - ) + println("Coffee model: ${adapter.toJson(d.coffeeAppModel())}") + + if (TeaPot.isEmpty() && ChaiCup.isEmpty()) { + val coffeeShop = DaggerCoffeeApp_CoffeeShop.builder().build() + runBlocking { + coffeeShop.maker().brew() + } + } } } } diff --git a/examples/ksp/CoffeeMaker.kt b/examples/ksp/CoffeeMaker.kt new file mode 100644 index 000000000..792e132ec --- /dev/null +++ b/examples/ksp/CoffeeMaker.kt @@ -0,0 +1,40 @@ +/* + * Copyright 2018 The Bazel Authors. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package coffee + +import dagger.Lazy +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import javax.inject.Inject + +class CoffeeMaker @Inject internal constructor( + // Create a possibly costly heater only when we use it. + private val heater: Lazy, + private val pump: Pump, + private val string: String +) { + + suspend fun brew() { + // this function is async to verify intellij support for coroutines. + withContext(Dispatchers.Default) { + heater.get().on() + pump.pump() + println(" [_]P coffee! [_]P ") + println(string) + heater.get().off() + } + } +} diff --git a/examples/ksp/DripCoffeeModule.kt b/examples/ksp/DripCoffeeModule.kt new file mode 100644 index 000000000..42bddbc33 --- /dev/null +++ b/examples/ksp/DripCoffeeModule.kt @@ -0,0 +1,29 @@ +/* + * Copyright 2018 The Bazel Authors. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package coffee + +import dagger.Module +import dagger.Provides +import javax.inject.Singleton + +@Module(includes = arrayOf(PumpModule::class)) +internal class DripCoffeeModule { + @Provides + @Singleton + fun provideHeater(): Heater { + return ElectricHeater() + } +} diff --git a/examples/ksp/ElectricHeater.kt b/examples/ksp/ElectricHeater.kt new file mode 100644 index 000000000..32cd9eea7 --- /dev/null +++ b/examples/ksp/ElectricHeater.kt @@ -0,0 +1,29 @@ +/* + * Copyright 2018 The Bazel Authors. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package coffee + +internal class ElectricHeater : Heater { + override var isHot: Boolean = false + + override fun on() { + println("~ ~ ~ heating ~ ~ ~") + this.isHot = true + } + + override fun off() { + this.isHot = false + } +} diff --git a/examples/ksp/Heater.kt b/examples/ksp/Heater.kt new file mode 100644 index 000000000..d4eb52bac --- /dev/null +++ b/examples/ksp/Heater.kt @@ -0,0 +1,22 @@ +/* + * Copyright 2018 The Bazel Authors. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package coffee + +internal interface Heater { + val isHot: Boolean + fun on() + fun off() +} diff --git a/examples/ksp/Pump.kt b/examples/ksp/Pump.kt new file mode 100644 index 000000000..e695cc22b --- /dev/null +++ b/examples/ksp/Pump.kt @@ -0,0 +1,20 @@ +/* + * Copyright 2018 The Bazel Authors. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package coffee + +internal interface Pump { + fun pump() +} diff --git a/examples/ksp/PumpModule.kt b/examples/ksp/PumpModule.kt new file mode 100644 index 000000000..304c3e217 --- /dev/null +++ b/examples/ksp/PumpModule.kt @@ -0,0 +1,25 @@ +/* + * Copyright 2018 The Bazel Authors. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package coffee + +import dagger.Binds +import dagger.Module + +@Module +internal abstract class PumpModule { + @Binds + internal abstract fun providePump(pump: Thermosiphon): Pump +} diff --git a/examples/ksp/Thermosiphon.kt b/examples/ksp/Thermosiphon.kt new file mode 100644 index 000000000..cea1253e4 --- /dev/null +++ b/examples/ksp/Thermosiphon.kt @@ -0,0 +1,28 @@ +/* + * Copyright 2018 The Bazel Authors. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package coffee + +import javax.inject.Inject + +internal class Thermosiphon @Inject +constructor(private val heater: Heater) : Pump { + + override fun pump() { + if (heater.isHot) { + println("=> => pumping => =>") + } + } +} diff --git a/examples/ksp/WORKSPACE b/examples/ksp/WORKSPACE index fd83c8ffd..2618bd18f 100644 --- a/examples/ksp/WORKSPACE +++ b/examples/ksp/WORKSPACE @@ -42,13 +42,17 @@ load("@rules_jvm_external//:defs.bzl", "maven_install") maven_install( artifacts = [ - "com.squareup.moshi:moshi:1.14.0", - "com.squareup.moshi:moshi-kotlin:1.14.0", - "com.squareup.moshi:moshi-kotlin-codegen:1.14.0", "com.google.auto.service:auto-service-annotations:jar:1.1.1", - "com.google.auto.value:auto-value:1.10.1", "com.google.auto.value:auto-value-annotations:1.10.1", + "com.google.auto.value:auto-value:1.10.1", + "com.google.dagger:dagger-compiler:2.51", + "com.google.dagger:dagger-producers:2.51", + "com.google.dagger:dagger:2.51", + "com.squareup.moshi:moshi-kotlin-codegen:1.14.0", + "com.squareup.moshi:moshi-kotlin:1.14.0", + "com.squareup.moshi:moshi:1.14.0", "dev.zacsweers.autoservice:auto-service-ksp:jar:1.1.0", + "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.2", ], repositories = [ "https://maven.google.com", diff --git a/examples/ksp/third_party/BUILD.bazel b/examples/ksp/third_party/BUILD.bazel new file mode 100644 index 000000000..4af98cdab --- /dev/null +++ b/examples/ksp/third_party/BUILD.bazel @@ -0,0 +1,90 @@ +load("@rules_java//java:defs.bzl", "java_plugin") +load("@rules_kotlin//kotlin:core.bzl", "kt_compiler_plugin", "kt_ksp_plugin", "kt_plugin_cfg") + +java_plugin( + name = "autovalue", + generates_api = True, + processor_class = "com.google.auto.value.processor.AutoValueProcessor", + visibility = ["//visibility:public"], + deps = ["@maven//:com_google_auto_value_auto_value"], +) + +kt_compiler_plugin( + name = "ksp", + compile_phase = True, + id = "com.google.devtools.ksp.symbol-processing", + options = { + "apclasspath": "{classpath}", + # projectBaseDir shouldn't matter because incremental is disabled + "projectBaseDir": "{temp}", + # Disable incremental mode + "incremental": "false", + # Directory where class files are written to. Files written to this directory are class + # files being written directly from the annotation processor, not Kotlinc + "classOutputDir": "{generatedClasses}", + # Directory where generated Java sources files are written to + "javaOutputDir": "{generatedSources}", + # Directory where generated Kotlin sources files are written to + "kotlinOutputDir": "{generatedSources}", + # Directory where META-INF data is written to. This might not be the most ideal place to + # write this. Maybe just directly to the classes directory? + "resourceOutputDir": "{generatedSources}", + # TODO(bencodes) Not sure what this directory is yet. + "kspOutputDir": "{temp}", + # Directory to write KSP caches. Shouldn't matter because incremental is disabled + "cachesDir": "{temp}", + # Include in compilation as an example. This should be processed in the stubs phase. + "withCompilation": "true", + # Set returnOkOnError to false because we want to fail the build if there are any errors + "returnOkOnError": "false", + "allWarningsAsErrors": "false", + }, + visibility = ["//visibility:public"], + deps = [ + "@rules_kotlin//kotlin/compiler:symbol-processing-api", + "@rules_kotlin//kotlin/compiler:symbol-processing-cmdline", + ], +) + +kt_plugin_cfg( + name = "ksp_moshi", + options = { + }, + plugin = ":ksp", + visibility = ["//visibility:public"], + deps = [ + "@maven//:com_squareup_moshi_moshi", + "@maven//:com_squareup_moshi_moshi_kotlin", + "@maven//:com_squareup_moshi_moshi_kotlin_codegen", + ], +) + +kt_ksp_plugin( + name = "moshi-kotlin-codegen", + processor_class = "com.squareup.moshi.kotlin.codegen.ksp.JsonClassSymbolProcessorProvider", + visibility = ["//visibility:public"], + deps = [ + "@maven//:com_squareup_moshi_moshi", + "@maven//:com_squareup_moshi_moshi_kotlin", + "@maven//:com_squareup_moshi_moshi_kotlin_codegen", + ], +) + +kt_ksp_plugin( + name = "dagger_ksp_plugin", + generates_java = True, + processor_class = "dagger.internal.codegen.KspComponentProcessor", + target_embedded_compiler = True, + visibility = ["//visibility:public"], + deps = ["@maven//:com_google_dagger_dagger_compiler"], +) + +kt_ksp_plugin( + name = "autoservice", + processor_class = "dev.zacsweers.autoservice.ksp.AutoServiceSymbolProcessor$Provider", + visibility = ["//visibility:public"], + deps = [ + "@maven//:com_google_auto_service_auto_service_annotations", + "@maven//:dev_zacsweers_autoservice_auto_service_ksp", + ], +) diff --git a/kotlin/internal/jvm/BUILD b/kotlin/internal/jvm/BUILD index c7419b123..92480db27 100644 --- a/kotlin/internal/jvm/BUILD +++ b/kotlin/internal/jvm/BUILD @@ -15,11 +15,11 @@ load("@bazel_skylib//:bzl_library.bzl", "bzl_library") # limitations under the License. load("//src/main/starlark/release:packager.bzl", "release_archive") -exports_files(["jetbrains-deshade.jarjar"]) +exports_files(["kotlin-compiler-reshade.jarjar"]) release_archive( name = "pkg", - srcs = glob(["*.bzl"]) + ["jetbrains-deshade.jarjar"], + srcs = glob(["*.bzl"]) + ["kotlin-compiler-reshade.jarjar"], src_map = { "BUILD.release.bazel": "BUILD.bazel", }, diff --git a/kotlin/internal/jvm/BUILD.release.bazel b/kotlin/internal/jvm/BUILD.release.bazel index 23e384bdd..9845548db 100644 --- a/kotlin/internal/jvm/BUILD.release.bazel +++ b/kotlin/internal/jvm/BUILD.release.bazel @@ -14,7 +14,7 @@ load("@bazel_skylib//:bzl_library.bzl", "bzl_library") -exports_files(["jetbrains-deshade.jarjar"]) +exports_files(["kotlin-compiler-reshade.jarjar"]) bzl_library( name = "jvm", diff --git a/kotlin/internal/jvm/compile.bzl b/kotlin/internal/jvm/compile.bzl index f13b938b3..357c516ed 100644 --- a/kotlin/internal/jvm/compile.bzl +++ b/kotlin/internal/jvm/compile.bzl @@ -41,6 +41,7 @@ load( ) load( "//kotlin/internal/jvm:plugins.bzl", + "is_ksp_processor_generating_java", _plugin_mappers = "mappers", ) load( @@ -813,9 +814,10 @@ def _run_kt_java_builder_actions( java_infos.append(kt_java_info) # Build Java - # If there is Java source or KAPT generated Java source compile that Java and fold it into + # If there is Java source or KAPT/KSP generated Java source compile that Java and fold it into # the final ABI jar. Otherwise just use the KT ABI jar as final ABI jar. - if srcs.java or generated_kapt_src_jars or srcs.src_jars: + ksp_generated_java_src_jars = generated_ksp_src_jars and is_ksp_processor_generating_java(ctx.attr.plugins) + if srcs.java or generated_kapt_src_jars or srcs.src_jars or ksp_generated_java_src_jars: javac_opts = javac_options_to_flags(ctx.attr.javac_opts[JavacOptions] if ctx.attr.javac_opts else toolchains.kt.javac_options) # Kotlin takes care of annotation processing. Note that JavaBuilder "discovers" @@ -825,7 +827,7 @@ def _run_kt_java_builder_actions( java_info = java_common.compile( ctx, source_files = srcs.java, - source_jars = generated_kapt_src_jars + srcs.src_jars, + source_jars = generated_kapt_src_jars + srcs.src_jars + generated_ksp_src_jars, output = ctx.actions.declare_file(ctx.label.name + "-java.jar"), deps = compile_deps.deps + kt_stubs_for_java, java_toolchain = toolchains.java, diff --git a/kotlin/internal/jvm/impl.bzl b/kotlin/internal/jvm/impl.bzl index 3e38a000c..2f9e8f372 100644 --- a/kotlin/internal/jvm/impl.bzl +++ b/kotlin/internal/jvm/impl.bzl @@ -316,14 +316,14 @@ def kt_jvm_junit_test_impl(ctx): _KtCompilerPluginClasspathInfo = provider( fields = { - "deshaded_infos": "list deshaded JavaInfos of a compiler library", + "reshaded_infos": "list reshaded JavaInfos of a compiler library", "infos": "list JavaInfos of a compiler library", }, ) def kt_compiler_deps_aspect_impl(target, ctx): """ - Collects and deshades (if necessary) all jars in the plugin transitive closure. + Collects and reshades (if necessary) all jars in the plugin transitive closure. Args: target: Target of the rule being inspected @@ -337,7 +337,7 @@ def kt_compiler_deps_aspect_impl(target, ctx): for t in getattr(ctx.rule.attr, d, []) if _KtCompilerPluginClasspathInfo in t ] - deshaded_infos = [] + reshaded_infos = [] infos = [ i for t in transitive_infos @@ -346,35 +346,35 @@ def kt_compiler_deps_aspect_impl(target, ctx): if JavaInfo in target: ji = target[JavaInfo] infos.append(ji) - deshaded_infos.append( - _deshade_embedded_kotlinc_jars( + reshaded_infos.append( + _reshade_embedded_kotlinc_jars( target = target, ctx = ctx, jars = ji.runtime_output_jars, deps = [ i for t in transitive_infos - for i in t.deshaded_infos + for i in t.reshaded_infos ], ), ) return [ _KtCompilerPluginClasspathInfo( - deshaded_infos = deshaded_infos, + reshaded_infos = reshaded_infos, infos = [java_common.merge(infos)], ), ] -def _deshade_embedded_kotlinc_jars(target, ctx, jars, deps): - deshaded = [ +def _reshade_embedded_kotlinc_jars(target, ctx, jars, deps): + reshaded = [ jarjar_action( actions = ctx.actions, jarjar = ctx.executable._jarjar, - rules = ctx.file._jetbrains_deshade_rules, + rules = ctx.file._kotlin_compiler_reshade_rules, input = jar, output = ctx.actions.declare_file( - "%s_deshaded_%s" % (target.label.name, jar.basename), + "%s_reshaded_%s" % (target.label.name, jar.basename), ), ) for jar in jars @@ -384,7 +384,7 @@ def _deshade_embedded_kotlinc_jars(target, ctx, jars, deps): return java_common.merge( [ JavaInfo(output_jar = jar, compile_jar = jar, deps = deps) - for jar in deshaded + for jar in reshaded ], ) @@ -428,7 +428,7 @@ def kt_compiler_plugin_impl(ctx): info = java_common.merge([ i for d in deps - for i in d[_KtCompilerPluginClasspathInfo].deshaded_infos + for i in d[_KtCompilerPluginClasspathInfo].reshaded_infos ]) else: info = java_common.merge([ @@ -459,20 +459,32 @@ def kt_plugin_cfg_impl(ctx): return plugin.resolve_cfg(plugin, ctx.attr.options, ctx.attr.deps, ctx.expand_location) def kt_ksp_plugin_impl(ctx): - info = java_common.merge([dep[JavaInfo] for dep in ctx.attr.deps]) + deps = ctx.attr.deps + if ctx.attr.target_embedded_compiler: + info = java_common.merge([ + i + for d in deps + for i in d[_KtCompilerPluginClasspathInfo].reshaded_infos + ]) + else: + info = java_common.merge([dep[JavaInfo] for dep in deps]) + classpath = depset(info.runtime_output_jars, transitive = [info.transitive_runtime_jars]) return [ DefaultInfo(files = classpath), - _KspPluginInfo(plugins = [ - JavaPluginInfo( - runtime_deps = [ - info, - ], - processor_class = ctx.attr.processor_class, - # rules_kotlin doesn't support stripping non-api generating annotation - # processors out of the public ABI. - generates_api = True, - ), - ]), + _KspPluginInfo( + plugins = [ + JavaPluginInfo( + runtime_deps = [ + info, + ], + processor_class = ctx.attr.processor_class, + # rules_kotlin doesn't support stripping non-api generating annotation + # processors out of the public ABI. + generates_api = True, + ), + ], + generates_java = ctx.attr.generates_java, + ), ] diff --git a/kotlin/internal/jvm/jetbrains-deshade.jarjar b/kotlin/internal/jvm/jetbrains-deshade.jarjar deleted file mode 100644 index a517f73af..000000000 --- a/kotlin/internal/jvm/jetbrains-deshade.jarjar +++ /dev/null @@ -1,2 +0,0 @@ -rule org.jetbrains.kotlin.com.intellij.** com.intellij.@1 -rule org.jetbrains.kotlin.kotlinx.** kotlinx.@1 \ No newline at end of file diff --git a/kotlin/internal/jvm/jvm.bzl b/kotlin/internal/jvm/jvm.bzl index 76cf17448..05c38af8e 100644 --- a/kotlin/internal/jvm/jvm.bzl +++ b/kotlin/internal/jvm/jvm.bzl @@ -483,8 +483,8 @@ _kt_compiler_deps_aspect = aspect( implementation = _kt_compiler_deps_aspect_impl, attr_aspects = ["deps", "runtime_deps", "exports"], attrs = { - "_jetbrains_deshade_rules": attr.label( - default = Label("//kotlin/internal/jvm:jetbrains-deshade.jarjar"), + "_kotlin_compiler_reshade_rules": attr.label( + default = Label("//kotlin/internal/jvm:kotlin-compiler-reshade.jarjar"), allow_single_file = True, ), "_jarjar": attr.label( @@ -565,8 +565,8 @@ Supports the following template values: dependencies, and will fail when running against a non-embeddable compiler.""", default = False, ), - "_jetbrains_deshade_rules": attr.label( - default = Label("//kotlin/internal/jvm:jetbrains-deshade.jarjar"), + "_kotlin_compiler_reshade_rules": attr.label( + default = Label("//kotlin/internal/jvm:kotlin-compiler-reshade.jarjar"), allow_single_file = True, ), "_jarjar": attr.label( @@ -614,6 +614,19 @@ kt_jvm_library( doc = " The fully qualified class name that the Java compiler uses as an entry point to the annotation processor.", mandatory = True, ), + "target_embedded_compiler": attr.bool( + doc = """Plugin was compiled against the embeddable kotlin compiler. These plugins expect shaded kotlinc + dependencies, and will fail when running against a non-embeddable compiler.""", + default = False, + ), + "_kotlin_compiler_reshade_rules": attr.label( + default = Label("//kotlin/internal/jvm:kotlin-compiler-reshade.jarjar"), + allow_single_file = True, + ), + "generates_java": attr.bool( + doc = """Runs Java compilation action for plugin generating Java output.""", + default = False, + ), }, implementation = _kt_ksp_plugin_impl, provides = [_KspPluginInfo], diff --git a/kotlin/internal/jvm/kotlin-compiler-reshade.jarjar b/kotlin/internal/jvm/kotlin-compiler-reshade.jarjar new file mode 100644 index 000000000..8372b4160 --- /dev/null +++ b/kotlin/internal/jvm/kotlin-compiler-reshade.jarjar @@ -0,0 +1,3 @@ +rule org.jetbrains.kotlin.com.intellij.** com.intellij.@1 +rule org.jetbrains.kotlin.kotlinx.** kotlinx.@1 +rule com.google.common.** org.jetbrains.kotlin.google.common.@1 diff --git a/kotlin/internal/jvm/plugins.bzl b/kotlin/internal/jvm/plugins.bzl index 71c44026e..3674c487a 100644 --- a/kotlin/internal/jvm/plugins.bzl +++ b/kotlin/internal/jvm/plugins.bzl @@ -17,6 +17,13 @@ load( _KspPluginInfo = "KspPluginInfo", ) +def is_ksp_processor_generating_java(targets): + for t in targets: + if _KspPluginInfo in t: + if t[_KspPluginInfo].generates_java: + return True + return False + # Mapping functions for args.add_all. # These preserve the transitive depsets until needed. def _kt_plugin_to_processor(processor): diff --git a/kotlin_rules_maven_install.json b/kotlin_rules_maven_install.json index 8fb9c84dd..522919adb 100755 --- a/kotlin_rules_maven_install.json +++ b/kotlin_rules_maven_install.json @@ -1,10 +1,10 @@ { "__AUTOGENERATED_FILE_DO_NOT_MODIFY_THIS_FILE_MANUALLY": "THERE_IS_NO_DATA_ONLY_ZUUL", - "__INPUT_ARTIFACTS_HASH": -763710014, - "__RESOLVED_ARTIFACTS_HASH": -640184638, + "__INPUT_ARTIFACTS_HASH": -1193919207, + "__RESOLVED_ARTIFACTS_HASH": 368834518, "conflict_resolution": { "com.google.auto.service:auto-service-annotations:1.0.1": "com.google.auto.service:auto-service-annotations:1.1.1", - "com.google.guava:guava:27.1-jre": "com.google.guava:guava:32.1.1-jre" + "com.google.guava:guava:27.1-jre": "com.google.guava:guava:33.0.0-jre" }, "artifacts": { "com.google.auto.service:auto-service": { @@ -58,45 +58,45 @@ }, "com.google.dagger:dagger": { "shasums": { - "jar": "c89681f7cbbf8c527bf4ac2748515d617fdb54a1d425c08d914fdc28192b5fe4", - "sources": "f4f7a04037779a2186aba088b1dab8bc465a171f03b2934ecc046de740d4c0c3" + "jar": "a68b07ce740353462b04c9ad5944d9c22831025a4c8fbf282e3708a5684b68f7", + "sources": "29df2bfb27add94601b4f9aabe8c7d66e70634020f5c01666e33d86fe2ab3e83" }, - "version": "2.43.2" + "version": "2.51" }, "com.google.dagger:dagger-compiler": { "shasums": { - "jar": "298c020ee6ed2f4cc651ebbfdb7f8de329b07c44b618d65be117846a850e2a03", - "sources": "0928ecb0157fc2a9ed67d8747d2f518032dd408a2b4d72cf1720a453b378d4f4" + "jar": "bd1eb4fbba2014fca9e2c3a9bab0203e0a69aea131d1623352726dbcb5afd6ef", + "sources": "2540bb3e79dbe5d9c9a0ee3d93f96ea595ab537494e0b5044e25e20d8e8f43a0" }, - "version": "2.43.2" + "version": "2.51" }, "com.google.dagger:dagger-producers": { "shasums": { - "jar": "e7f5d9ffc85d48a49c8e22e02833d418f7ccad5d7512f529964db5127ab915ff", - "sources": "8bcf611b541b4f542c3a69ad89987fd4448aa83a79f336820a6616fc1013dcf1" + "jar": "1ce4fcd9f77dda4f76c707b5e46600ad089d840079e7bf1f18d952b206d6a4ef", + "sources": "441ec1d7d06c580d96660e5df0a39fff7d73d2e1f799efadf3f0069a3b509034" }, - "version": "2.43.2" + "version": "2.51" }, "com.google.dagger:dagger-spi": { "shasums": { - "jar": "3bae8d9dadeaaa5927da6f094389a560c12c05fec3d2711d2fa79292c7a7d7ad", - "sources": "9db725e2cb99139c5a4b982010dad52158cd03aba8aa2749188fa6f515ad2d59" + "jar": "6f55962a99f06f7d13afb3fd7b7164a830c7c12a1c5a41e5f9d5b01dd934a072", + "sources": "ca467ff8cdae8b4f316a0985ec2e00f9d9f8c7a66c31b27f8ae4af85c5ef9a10" }, - "version": "2.43.2" + "version": "2.51" }, "com.google.devtools.ksp:symbol-processing-api": { "shasums": { - "jar": "adc29417be5ca9ff42118105fea4e36d9ef44987abfc41432309371a60198941", - "sources": "008a5e5eee2616937e495856318105a72dda4e6c3642569f162f047bde49a9d0" + "jar": "d0339396f40dc9eb3b3f7bc86257f93869ee23448fa31ec4a1de900c6b7ae6d7", + "sources": "a7cf0b4ea8a85dff6dd9c068f7528f8b076556beccdbd882c86b6abb7239211c" }, - "version": "1.7.0-1.0.6" + "version": "1.9.20-1.0.14" }, "com.google.errorprone:error_prone_annotations": { "shasums": { - "jar": "9e6814cb71816988a4fd1b07a993a8f21bb7058d522c162b1de849e19bea54ae", - "sources": "a2c0783981c8ad48faaa6ea8de6f1926d8e87c125f5df5ce531a9810b943e032" + "jar": "ec6f39f068b6ff9ac323c68e28b9299f8c0a80ca512dccb1d4a70f40ac3ec054", + "sources": "5b4504609bb93d3c24b87cd839cf0bb7d878135d0a917a05081d0dc9b2a9973f" }, - "version": "2.18.0" + "version": "2.23.0" }, "com.google.errorprone:javac-shaded": { "shasums": { @@ -114,17 +114,17 @@ }, "com.google.guava:failureaccess": { "shasums": { - "jar": "a171ee4c734dd2da837e4b16be9df4661afab72a41adaf31eb84dfdaf936ca26", - "sources": "092346eebbb1657b51aa7485a246bf602bb464cc0b0e2e1c7e7201fadce1e98f" + "jar": "8a8f81cf9b359e3f6dfa691a1e776985c061ef2f223c9b2c80753e1b458e8064", + "sources": "dd3bfa5e2ec5bc5397efb2c3cef044c192313ff77089573667ff97a60c6978e0" }, - "version": "1.0.1" + "version": "1.0.2" }, "com.google.guava:guava": { "shasums": { - "jar": "91fbba37f1c8b251cf9ea9e7d3a369eb79eb1e6a5df1d4bbf483dd0380740281", - "sources": "5e7b6cebd2e9087a536c1054bf52a2e6a49c284772421f146640cfadc54ba573" + "jar": "f4d85c3e4d411694337cb873abea09b242b664bb013320be6105327c45991537", + "sources": "0c17d911785e8a606d091aa6740d6d520f307749c2bddf6e35066d52fe0036e5" }, - "version": "32.1.1-jre" + "version": "33.0.0-jre" }, "com.google.guava:listenablefuture": { "shasums": { @@ -317,10 +317,10 @@ }, "org.checkerframework:checker-qual": { "shasums": { - "jar": "e316255bbfcd9fe50d165314b85abb2b33cb2a66a93c491db648e498a82c2de1", - "sources": "443fa6151982bb4c6ce62e2938f53660085b13a7dceb517202777b87d0dea2c7" + "jar": "2f9f245bf68e4259d610894f2406dc1f6363dc639302bd566e8272e4f4541172", + "sources": "8308220bbdd4e12b49fa06a91de685faf9cc1a376464478c80845be3e87b7d4f" }, - "version": "3.33.0" + "version": "3.41.0" }, "org.codehaus.plexus:plexus-classworlds": { "shasums": { @@ -373,31 +373,31 @@ }, "org.jetbrains.kotlin:kotlin-stdlib": { "shasums": { - "jar": "03a5c3965cc37051128e64e46748e394b6bd4c97fa81c6de6fc72bfd44e3421b", - "sources": "e60342da94ab52368157917916775b7f2f03bbd728aad3c9e86c3f02a93dbeec" + "jar": "28a35bcdff46d864f80f346a617e486284b208d17378c41900dfb1de95a90e6c", + "sources": "e159eaf9f42fe4792ead7572ed44752753a9f4b006f5a10f5eefd04b13b6a363" }, - "version": "1.8.22" + "version": "1.9.20" }, "org.jetbrains.kotlin:kotlin-stdlib-common": { "shasums": { - "jar": "d0c2365e2437ef70f34586d50f055743f79716bcfe65e4bc7239cdd2669ef7c5", - "sources": "598996a205da366f31854b818b60da3afacb1302902005988c8826eeb2916532" + "jar": "32010683330a6f31b8d309f10433acaa109b61f2df3d252dae7dade9730074c2", + "sources": "1b6fb61c316787715aa64dd4adc8ed3cd42e0e430525142155f871de982e44b0" }, - "version": "1.8.22" + "version": "1.4.30" }, "org.jetbrains.kotlin:kotlin-stdlib-jdk7": { "shasums": { - "jar": "055f5cb24287fa106100995a7b47ab92126b81e832e875f5fa2cf0bd55693d0b", + "jar": "b7979a7aac94055f0d9f1fd3b47ce5ffe1cb6032a842ba9fbe7186f085289178", "sources": "ea10d3e5e6e695d8a5283cbf116321acae6ba42d0bdd3eda50f7c34a26fa25cb" }, - "version": "1.8.22" + "version": "1.9.0" }, "org.jetbrains.kotlin:kotlin-stdlib-jdk8": { "shasums": { - "jar": "4198b0eaf090a4f25b6f7e5a59581f4314ba8c9f6cd1d13ee9d348e65ed8f707", + "jar": "a59fa24fdf1ffb594baecdbf0fd10010f977cea10236d487fe3464977a7377fa", "sources": "40e9a80f6b953d12389623760d438e69914098d0c4d7053f70f90533ec041259" }, - "version": "1.8.22" + "version": "1.9.0" }, "org.jetbrains.kotlin:kotlin-stdlib-js": { "shasums": { @@ -413,13 +413,6 @@ }, "version": "0.15.2" }, - "org.jetbrains.kotlinx:kotlinx-metadata-jvm": { - "shasums": { - "jar": "ca063a96639b08b9eaa0de4d65e899480740a6efbe28ab9a8681a2ced03055a4", - "sources": "5efce3734e572cef4fc9c7005ced4f4c10ec2fea9daa232ec3cb63cd203bc786" - }, - "version": "0.5.0" - }, "org.jetbrains.kotlinx:kotlinx-serialization-runtime": { "shasums": { "jar": "b8431c786c81cb84713c038bb674c851aba533c89ba9f04f22fd78f2baacd6c4", @@ -485,19 +478,17 @@ "com.google.dagger:dagger-compiler": [ "com.google.code.findbugs:jsr305", "com.google.dagger:dagger", - "com.google.dagger:dagger-producers", "com.google.dagger:dagger-spi", "com.google.devtools.ksp:symbol-processing-api", "com.google.googlejavaformat:google-java-format", "com.google.guava:failureaccess", "com.google.guava:guava", "com.squareup:javapoet", + "com.squareup:kotlinpoet", "javax.inject:javax.inject", "net.ltgt.gradle.incap:incap", "org.checkerframework:checker-compat-qual", - "org.jetbrains.kotlin:kotlin-stdlib", - "org.jetbrains.kotlin:kotlin-stdlib-jdk8", - "org.jetbrains.kotlinx:kotlinx-metadata-jvm" + "org.jetbrains.kotlin:kotlin-stdlib" ], "com.google.dagger:dagger-producers": [ "com.google.dagger:dagger", @@ -509,17 +500,14 @@ "com.google.dagger:dagger-spi": [ "com.google.code.findbugs:jsr305", "com.google.dagger:dagger", - "com.google.dagger:dagger-producers", "com.google.devtools.ksp:symbol-processing-api", "com.google.guava:failureaccess", "com.google.guava:guava", "com.squareup:javapoet", - "javax.inject:javax.inject", - "org.jetbrains.kotlin:kotlin-stdlib", - "org.jetbrains.kotlin:kotlin-stdlib-jdk8" + "javax.inject:javax.inject" ], "com.google.devtools.ksp:symbol-processing-api": [ - "org.jetbrains.kotlin:kotlin-stdlib" + "org.jetbrains.kotlin:kotlin-stdlib-jdk8" ], "com.google.googlejavaformat:google-java-format": [ "com.google.errorprone:javac-shaded", @@ -617,7 +605,6 @@ "org.jetbrains.kotlin:kotlin-stdlib" ], "org.jetbrains.kotlin:kotlin-stdlib": [ - "org.jetbrains.kotlin:kotlin-stdlib-common", "org.jetbrains:annotations" ], "org.jetbrains.kotlin:kotlin-stdlib-jdk7": [ @@ -634,9 +621,6 @@ "org.jetbrains.kotlin:kotlin-stdlib-common", "org.jetbrains.kotlin:kotlin-stdlib-js" ], - "org.jetbrains.kotlinx:kotlinx-metadata-jvm": [ - "org.jetbrains.kotlin:kotlin-stdlib" - ], "org.jetbrains.kotlinx:kotlinx-serialization-runtime": [ "org.jetbrains.kotlin:kotlin-stdlib", "org.jetbrains.kotlin:kotlin-stdlib-common" @@ -779,9 +763,11 @@ "dagger.internal.codegen.javapoet", "dagger.internal.codegen.kotlin", "dagger.internal.codegen.langmodel", + "dagger.internal.codegen.model", "dagger.internal.codegen.processingstep", "dagger.internal.codegen.validation", - "dagger.internal.codegen.writing" + "dagger.internal.codegen.writing", + "dagger.internal.codegen.xprocessing" ], "com.google.dagger:dagger-producers": [ "dagger.producers", @@ -791,18 +777,48 @@ ], "com.google.dagger:dagger-spi": [ "dagger.internal.codegen.extension", - "dagger.internal.codegen.xprocessing", "dagger.model", "dagger.spi", - "dagger.spi.model", - "dagger.spi.shaded.androidx.room.compiler.processing", - "dagger.spi.shaded.androidx.room.compiler.processing.compat", - "dagger.spi.shaded.androidx.room.compiler.processing.javac", - "dagger.spi.shaded.androidx.room.compiler.processing.javac.kotlin", - "dagger.spi.shaded.androidx.room.compiler.processing.ksp", - "dagger.spi.shaded.androidx.room.compiler.processing.ksp.synthetic", - "dagger.spi.shaded.androidx.room.compiler.processing.util", - "dagger.spi.shaded.auto.common" + "dagger.spi.internal.shaded.androidx.room.compiler.codegen", + "dagger.spi.internal.shaded.androidx.room.compiler.codegen.java", + "dagger.spi.internal.shaded.androidx.room.compiler.codegen.kotlin", + "dagger.spi.internal.shaded.androidx.room.compiler.processing", + "dagger.spi.internal.shaded.androidx.room.compiler.processing.compat", + "dagger.spi.internal.shaded.androidx.room.compiler.processing.javac", + "dagger.spi.internal.shaded.androidx.room.compiler.processing.javac.kotlin", + "dagger.spi.internal.shaded.androidx.room.compiler.processing.ksp", + "dagger.spi.internal.shaded.androidx.room.compiler.processing.ksp.synthetic", + "dagger.spi.internal.shaded.androidx.room.compiler.processing.util", + "dagger.spi.internal.shaded.androidx.room.jarjarred.kotlinx.metadata", + "dagger.spi.internal.shaded.androidx.room.jarjarred.kotlinx.metadata.internal", + "dagger.spi.internal.shaded.androidx.room.jarjarred.kotlinx.metadata.internal.common", + "dagger.spi.internal.shaded.androidx.room.jarjarred.kotlinx.metadata.internal.extensions", + "dagger.spi.internal.shaded.androidx.room.jarjarred.kotlinx.metadata.internal.metadata", + "dagger.spi.internal.shaded.androidx.room.jarjarred.kotlinx.metadata.internal.metadata.builtins", + "dagger.spi.internal.shaded.androidx.room.jarjarred.kotlinx.metadata.internal.metadata.deserialization", + "dagger.spi.internal.shaded.androidx.room.jarjarred.kotlinx.metadata.internal.metadata.jvm", + "dagger.spi.internal.shaded.androidx.room.jarjarred.kotlinx.metadata.internal.metadata.jvm.deserialization", + "dagger.spi.internal.shaded.androidx.room.jarjarred.kotlinx.metadata.internal.metadata.jvm.serialization", + "dagger.spi.internal.shaded.androidx.room.jarjarred.kotlinx.metadata.internal.metadata.serialization", + "dagger.spi.internal.shaded.androidx.room.jarjarred.kotlinx.metadata.internal.protobuf", + "dagger.spi.internal.shaded.androidx.room.jarjarred.kotlinx.metadata.jvm", + "dagger.spi.internal.shaded.androidx.room.jarjarred.kotlinx.metadata.jvm.internal", + "dagger.spi.internal.shaded.auto.common", + "dagger.spi.internal.shaded.kotlinx.metadata", + "dagger.spi.internal.shaded.kotlinx.metadata.internal", + "dagger.spi.internal.shaded.kotlinx.metadata.internal.common", + "dagger.spi.internal.shaded.kotlinx.metadata.internal.extensions", + "dagger.spi.internal.shaded.kotlinx.metadata.internal.metadata", + "dagger.spi.internal.shaded.kotlinx.metadata.internal.metadata.builtins", + "dagger.spi.internal.shaded.kotlinx.metadata.internal.metadata.deserialization", + "dagger.spi.internal.shaded.kotlinx.metadata.internal.metadata.jvm", + "dagger.spi.internal.shaded.kotlinx.metadata.internal.metadata.jvm.deserialization", + "dagger.spi.internal.shaded.kotlinx.metadata.internal.metadata.jvm.serialization", + "dagger.spi.internal.shaded.kotlinx.metadata.internal.metadata.serialization", + "dagger.spi.internal.shaded.kotlinx.metadata.internal.protobuf", + "dagger.spi.internal.shaded.kotlinx.metadata.jvm", + "dagger.spi.internal.shaded.kotlinx.metadata.jvm.internal", + "dagger.spi.model" ], "com.google.devtools.ksp:symbol-processing-api": [ "com.google.devtools.ksp", @@ -1313,22 +1329,6 @@ "kotlin.time", "kotlin.time.jdk8" ], - "org.jetbrains.kotlinx:kotlinx-metadata-jvm": [ - "kotlinx.metadata", - "kotlinx.metadata.impl", - "kotlinx.metadata.impl.extensions", - "kotlinx.metadata.internal.common", - "kotlinx.metadata.internal.metadata", - "kotlinx.metadata.internal.metadata.builtins", - "kotlinx.metadata.internal.metadata.deserialization", - "kotlinx.metadata.internal.metadata.jvm", - "kotlinx.metadata.internal.metadata.jvm.deserialization", - "kotlinx.metadata.internal.metadata.jvm.serialization", - "kotlinx.metadata.internal.metadata.serialization", - "kotlinx.metadata.internal.protobuf", - "kotlinx.metadata.jvm", - "kotlinx.metadata.jvm.impl" - ], "org.jetbrains.kotlinx:kotlinx-serialization-runtime": [ "kotlinx.serialization", "kotlinx.serialization.builtins", @@ -1479,8 +1479,6 @@ "org.jetbrains.kotlin:kotlin-stdlib:jar:sources", "org.jetbrains.kotlinx:atomicfu-js", "org.jetbrains.kotlinx:atomicfu-js:jar:sources", - "org.jetbrains.kotlinx:kotlinx-metadata-jvm", - "org.jetbrains.kotlinx:kotlinx-metadata-jvm:jar:sources", "org.jetbrains.kotlinx:kotlinx-serialization-runtime", "org.jetbrains.kotlinx:kotlinx-serialization-runtime:jar:sources", "org.jetbrains:annotations", @@ -1612,8 +1610,6 @@ "org.jetbrains.kotlin:kotlin-stdlib:jar:sources", "org.jetbrains.kotlinx:atomicfu-js", "org.jetbrains.kotlinx:atomicfu-js:jar:sources", - "org.jetbrains.kotlinx:kotlinx-metadata-jvm", - "org.jetbrains.kotlinx:kotlinx-metadata-jvm:jar:sources", "org.jetbrains.kotlinx:kotlinx-serialization-runtime", "org.jetbrains.kotlinx:kotlinx-serialization-runtime:jar:sources", "org.jetbrains:annotations", @@ -1745,8 +1741,6 @@ "org.jetbrains.kotlin:kotlin-stdlib:jar:sources", "org.jetbrains.kotlinx:atomicfu-js", "org.jetbrains.kotlinx:atomicfu-js:jar:sources", - "org.jetbrains.kotlinx:kotlinx-metadata-jvm", - "org.jetbrains.kotlinx:kotlinx-metadata-jvm:jar:sources", "org.jetbrains.kotlinx:kotlinx-serialization-runtime", "org.jetbrains.kotlinx:kotlinx-serialization-runtime:jar:sources", "org.jetbrains:annotations", diff --git a/src/main/kotlin/io/bazel/kotlin/builder/tasks/jvm/CompilationTask.kt b/src/main/kotlin/io/bazel/kotlin/builder/tasks/jvm/CompilationTask.kt index 679eae607..fd94ba0eb 100644 --- a/src/main/kotlin/io/bazel/kotlin/builder/tasks/jvm/CompilationTask.kt +++ b/src/main/kotlin/io/bazel/kotlin/builder/tasks/jvm/CompilationTask.kt @@ -387,6 +387,7 @@ internal fun JvmCompilationTask.createGeneratedKspKotlinSrcJar() { verbose = false, ).also { it.addDirectory(Paths.get(directories.generatedSources)) + it.addDirectory(Paths.get(directories.generatedJavaSources)) it.setJarOwner(info.label, info.bazelRuleKind) it.execute() } diff --git a/src/main/starlark/core/plugin/providers.bzl b/src/main/starlark/core/plugin/providers.bzl index 93c610bd7..0129f961a 100644 --- a/src/main/starlark/core/plugin/providers.bzl +++ b/src/main/starlark/core/plugin/providers.bzl @@ -30,5 +30,6 @@ KtPluginConfiguration = provider( KspPluginInfo = provider( fields = { "plugins": "List of JavaPluginInfo providers for the plugins to run with KSP", + "generates_java": "Runs Java compilation action for this plugin", }, ) diff --git a/src/main/starlark/core/repositories/setup.bzl b/src/main/starlark/core/repositories/setup.bzl index 72afe746a..7af71e0fe 100644 --- a/src/main/starlark/core/repositories/setup.bzl +++ b/src/main/starlark/core/repositories/setup.bzl @@ -43,9 +43,9 @@ def kt_configure(): "com.google.auto.service:auto-service-annotations:1.0.1", "com.google.auto.value:auto-value:1.10.1", "com.google.auto.value:auto-value-annotations:1.10.1", - "com.google.dagger:dagger:2.43.2", - "com.google.dagger:dagger-compiler:2.43.2", - "com.google.dagger:dagger-producers:2.43.2", + "com.google.dagger:dagger:2.51", + "com.google.dagger:dagger-compiler:2.51", + "com.google.dagger:dagger-producers:2.51", "javax.annotation:javax.annotation-api:1.3.2", "javax.inject:javax.inject:1", "org.pantsbuild:jarjar:1.7.2", diff --git a/src/test/data/jvm/ksp/BUILD b/src/test/data/jvm/ksp/BUILD index b9052e7b7..db4e31ef4 100644 --- a/src/test/data/jvm/ksp/BUILD +++ b/src/test/data/jvm/ksp/BUILD @@ -16,12 +16,26 @@ load("//kotlin:jvm.bzl", "kt_jvm_library") # limitations under the License. package(default_visibility = ["//visibility:private"]) +kt_ksp_plugin( + name = "dagger", + generates_java = True, + processor_class = "dagger.internal.codegen.KspComponentProcessor", + target_embedded_compiler = True, + deps = ["@kotlin_rules_maven//:com_google_dagger_dagger_compiler"], +) + +kt_ksp_plugin( + name = "dagger_no_java", + generates_java = False, + processor_class = "dagger.internal.codegen.KspComponentProcessor", + target_embedded_compiler = True, + deps = ["@kotlin_rules_maven//:com_google_dagger_dagger_compiler"], +) + kt_ksp_plugin( name = "autoservice", processor_class = "dev.zacsweers.autoservice.ksp.AutoServiceSymbolProcessor$Provider", - deps = [ - "@kotlin_rules_maven//:dev_zacsweers_autoservice_auto_service_ksp", - ], + deps = ["@kotlin_rules_maven//:dev_zacsweers_autoservice_auto_service_ksp"], ) kt_ksp_plugin( @@ -35,7 +49,7 @@ kt_ksp_plugin( ) kt_jvm_library( - name = "moshi_lib", + name = "ksp_kotlin_resources", srcs = ["CoffeeAppModel.kt"], plugins = [":moshi"], deps = [ @@ -46,10 +60,82 @@ kt_jvm_library( ) kt_jvm_library( - name = "coffee_lib", - srcs = ["CoffeeAppService.java"], - plugins = [":autoservice"], + name = "ksp_kotlin_resources_missing_plugin", + srcs = ["CoffeeAppModel.kt"], + deps = [ + "@kotlin_rules_maven//:com_squareup_moshi_moshi", + "@kotlin_rules_maven//:com_squareup_moshi_moshi_kotlin", + "@kotlin_rules_maven//:com_squareup_moshi_moshi_kotlin_codegen", + ], +) + +kt_jvm_library( + name = "ksp_kotlin_resources_multiple_plugins", + srcs = [ + "CoffeeAppModel.kt", + "DripCoffeeModule.kt", + ], + plugins = [ + ":dagger", + ":moshi", + ], deps = [ + "@kotlin_rules_maven//:com_google_dagger_dagger", + "@kotlin_rules_maven//:com_squareup_moshi_moshi", + "@kotlin_rules_maven//:com_squareup_moshi_moshi_kotlin", + "@kotlin_rules_maven//:com_squareup_moshi_moshi_kotlin_codegen", + ], +) + +kt_jvm_library( + name = "ksp_kotlin_resources_multiple_plugins_no_java_gen", + srcs = [ + "CoffeeAppModel.kt", + "DripCoffeeModule.kt", + ], + plugins = [ + ":dagger_no_java", + ":moshi", + ], + deps = [ + "@kotlin_rules_maven//:com_google_dagger_dagger", + "@kotlin_rules_maven//:com_squareup_moshi_moshi", + "@kotlin_rules_maven//:com_squareup_moshi_moshi_kotlin", + "@kotlin_rules_maven//:com_squareup_moshi_moshi_kotlin_codegen", + ], +) + +kt_jvm_library( + name = "ksp_mixed_resources", + srcs = [ + "CoffeeApp.kt", + "CoffeeBean.java", + "CoffeeMaker.kt", + "DripCoffeeModule.kt", + ], + plugins = [":dagger"], + deps = ["@kotlin_rules_maven//:com_google_dagger_dagger"], +) + +kt_jvm_library( + name = "ksp_mixed_resources_multiple_plugins", + srcs = [ + "CoffeeApp.kt", + "CoffeeAppModel.kt", + "CoffeeAppService.java", + "CoffeeMaker.kt", + "DripCoffeeModule.kt", + ], + plugins = [ + ":autoservice", + ":dagger", + ":moshi", + ], + deps = [ + "@kotlin_rules_maven//:com_google_dagger_dagger", + "@kotlin_rules_maven//:com_squareup_moshi_moshi", + "@kotlin_rules_maven//:com_squareup_moshi_moshi_kotlin", + "@kotlin_rules_maven//:com_squareup_moshi_moshi_kotlin_codegen", "@kotlin_rules_maven//:dev_zacsweers_autoservice_auto_service_ksp", ], ) @@ -57,8 +143,12 @@ kt_jvm_library( filegroup( name = "ksp", srcs = [ - ":coffee_lib.jar", - ":moshi_lib.jar", + ":ksp_kotlin_resources.jar", + ":ksp_kotlin_resources_missing_plugin.jar", + ":ksp_kotlin_resources_multiple_plugins.jar", + ":ksp_kotlin_resources_multiple_plugins_no_java_gen.jar", + ":ksp_mixed_resources.jar", + ":ksp_mixed_resources_multiple_plugins.jar", ], visibility = ["//visibility:public"], ) diff --git a/src/test/data/jvm/ksp/CoffeeApp.kt b/src/test/data/jvm/ksp/CoffeeApp.kt index 876486649..083c3e96c 100644 --- a/src/test/data/jvm/ksp/CoffeeApp.kt +++ b/src/test/data/jvm/ksp/CoffeeApp.kt @@ -13,17 +13,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package coffee +package src.test.data.jvm.ksp -import com.squareup.moshi.Moshi +import dagger.Component +import javax.inject.Singleton class CoffeeApp { - companion object { + @Singleton + @Component(modules = [DripCoffeeModule::class]) + interface CoffeeShop { + fun maker(): CoffeeMaker + } - private val adapter = CoffeeAppModelJsonAdapter(Moshi.Builder().build()) - private val d = AutoValue_CoffeeAppJavaModel.Builder() - .setCoffeeAppModel(CoffeeAppModel("1")) - .build() + companion object { + private val coffeeShop = DaggerCoffeeApp_CoffeeShop.builder().build() } } diff --git a/src/test/data/jvm/ksp/CoffeeBean.java b/src/test/data/jvm/ksp/CoffeeBean.java new file mode 100644 index 000000000..cd51a2259 --- /dev/null +++ b/src/test/data/jvm/ksp/CoffeeBean.java @@ -0,0 +1,7 @@ +package src.test.data.jvm.ksp; + +public class CoffeeBean { + public Boolean isGood() { + return true; + } +} diff --git a/src/test/data/jvm/ksp/CoffeeMaker.kt b/src/test/data/jvm/ksp/CoffeeMaker.kt new file mode 100644 index 000000000..c404a236b --- /dev/null +++ b/src/test/data/jvm/ksp/CoffeeMaker.kt @@ -0,0 +1,30 @@ +/* + * Copyright 2018 The Bazel Authors. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package src.test.data.jvm.ksp + +import dagger.Lazy +import javax.inject.Inject + +class CoffeeMaker @Inject internal constructor( + private val heater: Lazy, +) { + + fun brew() { + heater.get().on() + println(" [_]P coffee! [_]P ") + heater.get().off() + } +} diff --git a/src/test/data/jvm/ksp/DripCoffeeModule.kt b/src/test/data/jvm/ksp/DripCoffeeModule.kt new file mode 100644 index 000000000..40937bc36 --- /dev/null +++ b/src/test/data/jvm/ksp/DripCoffeeModule.kt @@ -0,0 +1,48 @@ +/* + * Copyright 2018 The Bazel Authors. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package src.test.data.jvm.ksp + +import dagger.Module +import dagger.Provides +import javax.inject.Singleton + +@Module +internal class DripCoffeeModule { + @Provides + @Singleton + fun provideHeater(): Heater { + return ElectricHeater() + } +} + +internal interface Heater { + val isHot: Boolean + fun on() + fun off() +} + +internal class ElectricHeater : Heater { + override var isHot: Boolean = false + + override fun on() { + println("~ ~ ~ heating ~ ~ ~") + this.isHot = true + } + + override fun off() { + this.isHot = false + } +} diff --git a/src/test/kotlin/io/bazel/kotlin/KotlinJvmKspAssertionTest.kt b/src/test/kotlin/io/bazel/kotlin/KotlinJvmKspAssertionTest.kt index 4966df3bd..94204ddf8 100644 --- a/src/test/kotlin/io/bazel/kotlin/KotlinJvmKspAssertionTest.kt +++ b/src/test/kotlin/io/bazel/kotlin/KotlinJvmKspAssertionTest.kt @@ -8,37 +8,117 @@ import org.junit.runners.JUnit4 class KotlinJvmKspAssertionTest: KotlinAssertionTestCase("src/test/data/jvm/ksp") { @Test - fun testKSPCopiesAllFilesFromMetaINF() { - jarTestCase("coffee_lib.jar", description = "Generated jar with ksp plugin contains meta-inf contents") { + fun testKotlinOnlyKSP() { + jarTestCase( + name = "ksp_kotlin_resources.jar", + description = "KSP should work", + ) { + assertContainsEntries( + "src/test/data/jvm/ksp/CoffeeAppModelJsonAdapter.class", + ) + } + jarTestCase( + "ksp_kotlin_resources_missing_plugin.jar", + description = "KSP should not generate files" + ) { + assertDoesNotContainEntries( + "src/test/data/jvm/ksp/CoffeeAppModelJsonAdapter.class", + ) + } + } + + @Test + fun testMixedModeKSP() { + jarTestCase( + name = "ksp_mixed_resources.jar", + description = "KSP should work for mixed mode targets", + ) { assertContainsExactEntries( + "META-INF/", + "META-INF/MANIFEST.MF", + "META-INF/src_test_data_jvm_ksp-ksp_mixed_resources.kotlin_module", "src/", "src/test/", "src/test/data/", "src/test/data/jvm/", "src/test/data/jvm/ksp/", - "src/test/data/jvm/ksp/CoffeeAppService.class", - "META-INF/", - "META-INF/MANIFEST.MF" + "src/test/data/jvm/ksp/CoffeeApp.class", + "src/test/data/jvm/ksp/CoffeeApp\$CoffeeShop.class", + "src/test/data/jvm/ksp/CoffeeApp\$Companion.class", + "src/test/data/jvm/ksp/CoffeeBean.class", + "src/test/data/jvm/ksp/CoffeeMaker.class", + "src/test/data/jvm/ksp/CoffeeMaker_Factory.class", + "src/test/data/jvm/ksp/DaggerCoffeeApp_CoffeeShop.class", + "src/test/data/jvm/ksp/DaggerCoffeeApp_CoffeeShop\$1.class", + "src/test/data/jvm/ksp/DaggerCoffeeApp_CoffeeShop\$Builder.class", + "src/test/data/jvm/ksp/DaggerCoffeeApp_CoffeeShop\$CoffeeShopImpl.class", + "src/test/data/jvm/ksp/DripCoffeeModule.class", + "src/test/data/jvm/ksp/DripCoffeeModule_ProvideHeaterFactory.class", + "src/test/data/jvm/ksp/ElectricHeater.class", + "src/test/data/jvm/ksp/Heater.class", + ) + } + } + + @Test + fun testKSPGeneratesJavaOnlyWithPluginGeneratesJavaFlagEnabled() { + jarTestCase( + name = "ksp_kotlin_resources_multiple_plugins.jar", + description = "KSP should generate java", + ) { + assertContainsEntries( + "src/test/data/jvm/ksp/CoffeeAppModelJsonAdapter.class", + "src/test/data/jvm/ksp/DripCoffeeModule_ProvideHeaterFactory.class", + ) + } + jarTestCase( + "ksp_kotlin_resources_multiple_plugins_no_java_gen.jar", + description = "KSP should not generate java files" + ) { + assertContainsEntries( + "src/test/data/jvm/ksp/CoffeeAppModelJsonAdapter.class", + ) + assertDoesNotContainEntries( + "src/test/data/jvm/ksp/DripCoffeeModule_ProvideHeaterFactory.class", ) } } @Test - fun testKSPCopiesAllFilesFromMetaINFInMoshiLib() { - jarTestCase("moshi_lib.jar", description = "Generated jar with ksp plugin contains meta-inf contents") { + fun testKSPCopiesAllFilesFromMetaINF() { + jarTestCase( + name = "ksp_mixed_resources_multiple_plugins.jar", + description = "Generated jar with ksp plugins contains all meta-inf contents", + ) { assertContainsExactEntries( + "META-INF/", + "META-INF/MANIFEST.MF", + "META-INF/proguard/", + "META-INF/proguard/moshi-src.test.data.jvm.ksp.CoffeeAppModel.pro", + "META-INF/services/", + "META-INF/services/java.lang.Object", + "META-INF/src_test_data_jvm_ksp-ksp_mixed_resources_multiple_plugins.kotlin_module", "src/", "src/test/", "src/test/data/", "src/test/data/jvm/", "src/test/data/jvm/ksp/", + "src/test/data/jvm/ksp/CoffeeApp.class", "src/test/data/jvm/ksp/CoffeeAppModel.class", "src/test/data/jvm/ksp/CoffeeAppModelJsonAdapter.class", - "META-INF/", - "META-INF/MANIFEST.MF", - "META-INF/proguard/", - "META-INF/proguard/moshi-src.test.data.jvm.ksp.CoffeeAppModel.pro", - "META-INF/src_test_data_jvm_ksp-moshi_lib.kotlin_module" + "src/test/data/jvm/ksp/CoffeeAppService.class", + "src/test/data/jvm/ksp/CoffeeApp\$CoffeeShop.class", + "src/test/data/jvm/ksp/CoffeeApp\$Companion.class", + "src/test/data/jvm/ksp/CoffeeMaker.class", + "src/test/data/jvm/ksp/CoffeeMaker_Factory.class", + "src/test/data/jvm/ksp/DaggerCoffeeApp_CoffeeShop.class", + "src/test/data/jvm/ksp/DaggerCoffeeApp_CoffeeShop\$1.class", + "src/test/data/jvm/ksp/DaggerCoffeeApp_CoffeeShop\$Builder.class", + "src/test/data/jvm/ksp/DaggerCoffeeApp_CoffeeShop\$CoffeeShopImpl.class", + "src/test/data/jvm/ksp/DripCoffeeModule.class", + "src/test/data/jvm/ksp/DripCoffeeModule_ProvideHeaterFactory.class", + "src/test/data/jvm/ksp/ElectricHeater.class", + "src/test/data/jvm/ksp/Heater.class", ) } }