diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 05247d67..0444ffb7 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -21,7 +21,7 @@ kotlinCompileTesting = "1.4.3" kotlin = "1.5.30" jvmTarget = "1.8" kotlinpoet = "1.9.0" -ksp = "1.5.30-1.0.0-beta08" +ksp = "1.5.30-1.0.0-beta09" ktlint = "0.41.0" moshi = "1.12.0" okhttp = "4.9.1" @@ -31,8 +31,8 @@ retrofit = "2.9.0" dokka = { id = "org.jetbrains.dokka", version = "1.5.0" } ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } mavenPublish = { id = "com.vanniktech.maven.publish", version = "0.17.0" } -spotless = { id = "com.diffplug.spotless", version = "5.14.2" } -kotlinBinaryCompatibilityValidator = { id = "org.jetbrains.kotlinx.binary-compatibility-validator", version = "0.7.0" } +spotless = { id = "com.diffplug.spotless", version = "5.14.3" } +kotlinBinaryCompatibilityValidator = { id = "org.jetbrains.kotlinx.binary-compatibility-validator", version = "0.7.1" } [libraries] asm = { module = "org.ow2.asm:asm", version = "9.2" } diff --git a/moshi-ksp/moshi-ksp/build.gradle.kts b/moshi-ksp/moshi-ksp/build.gradle.kts index 958b25e8..cc3d30e3 100644 --- a/moshi-ksp/moshi-ksp/build.gradle.kts +++ b/moshi-ksp/moshi-ksp/build.gradle.kts @@ -46,8 +46,7 @@ dependencies { testImplementation(libs.truth) testImplementation(libs.junit) testImplementation(libs.kotlin.reflect) - // TODO re-enable with new release -// testImplementation(Dependencies.Testing.kspCompileTesting) testImplementation(libs.kotlinCompileTesting) + testImplementation(libs.kotlinCompileTesting.ksp) testImplementation(libs.kotlin.compilerEmbeddable) } diff --git a/moshi-ksp/moshi-ksp/src/test/kotlin/com/tschuchort/compiletesting/symbolProcessors.kt b/moshi-ksp/moshi-ksp/src/test/kotlin/com/tschuchort/compiletesting/symbolProcessors.kt deleted file mode 100644 index bcd9be38..00000000 --- a/moshi-ksp/moshi-ksp/src/test/kotlin/com/tschuchort/compiletesting/symbolProcessors.kt +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright (C) 2021 Zac Sweers - * - * 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 - * - * https://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 com.tschuchort.compiletesting - -import com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension -import com.google.devtools.ksp.KspOptions -import com.google.devtools.ksp.processing.KSPLogger -import com.google.devtools.ksp.processing.SymbolProcessorProvider -import com.google.devtools.ksp.processing.impl.MessageCollectorBasedKSPLogger -import org.jetbrains.kotlin.cli.common.messages.MessageRenderer -import org.jetbrains.kotlin.cli.common.messages.PrintingMessageCollector -import org.jetbrains.kotlin.com.intellij.mock.MockProject -import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar -import org.jetbrains.kotlin.config.CompilerConfiguration -import org.jetbrains.kotlin.resolve.jvm.extensions.AnalysisHandlerExtension -import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull -import java.io.File - -/** - * The list of symbol processors for the kotlin compilation. - * https://goo.gle/ksp - */ -var KotlinCompilation.symbolProcessorProviders: List - get() = getKspRegistrar().processorProviders - set(value) { - val registrar = getKspRegistrar() - registrar.processorProviders = value - } - -/** - * The directory where generated KSP sources are written - */ -val KotlinCompilation.kspSourcesDir: File - get() = kspWorkingDir.resolve("sources") - -/** - * Arbitrary arguments to be passed to ksp - */ -var KotlinCompilation.kspArgs: MutableMap - get() = getKspRegistrar().options - set(value) { - val registrar = getKspRegistrar() - registrar.options = value - } - -/** - * Controls for enabling incremental processing in KSP. - */ -var KotlinCompilation.kspIncremental: Boolean - get() = getKspRegistrar().incremental - set(value) { - val registrar = getKspRegistrar() - registrar.incremental = value - } - -/** - * Controls for enabling incremental processing logs in KSP. - */ -var KotlinCompilation.kspIncrementalLog: Boolean - get() = getKspRegistrar().incrementalLog - set(value) { - val registrar = getKspRegistrar() - registrar.incrementalLog = value - } - -private val KotlinCompilation.kspJavaSourceDir: File - get() = kspSourcesDir.resolve("java") - -private val KotlinCompilation.kspKotlinSourceDir: File - get() = kspSourcesDir.resolve("kotlin") - -private val KotlinCompilation.kspResources: File - get() = kspSourcesDir.resolve("resources") - -/** - * The working directory for KSP - */ -private val KotlinCompilation.kspWorkingDir: File - get() = workingDir.resolve("ksp") - -/** - * The directory where compiled KSP classes are written - */ -// TODO this seems to be ignored by KSP and it is putting classes into regular classes directory -// but we still need to provide it in the KSP options builder as it is required -// once it works, we should make the property public. -private val KotlinCompilation.kspClassesDir: File - get() = kspWorkingDir.resolve("classes") - -/** - * The directory where compiled KSP caches are written - */ -private val KotlinCompilation.kspCachesDir: File - get() = kspWorkingDir.resolve("caches") - -/** - * Custom subclass of [AbstractKotlinSymbolProcessingExtension] where processors are pre-defined instead of being - * loaded via ServiceLocator. - */ -private class KspTestExtension( - options: KspOptions, - private val testProcessorProviders: List, - logger: KSPLogger -) : AbstractKotlinSymbolProcessingExtension( - options = options, - logger = logger, - testMode = false -) { - override fun loadProviders() = testProcessorProviders -} - -/** - * Registers the [KspTestExtension] to load the given list of processors. - */ -private class KspCompileTestingComponentRegistrar( - private val compilation: KotlinCompilation -) : ComponentRegistrar { - var processorProviders = emptyList() - - var options: MutableMap = mutableMapOf() - - var incremental: Boolean = false - var incrementalLog: Boolean = false - - override fun registerProjectComponents(project: MockProject, configuration: CompilerConfiguration) { - if (processorProviders.isEmpty()) { - return - } - val options = KspOptions.Builder().apply { - this.projectBaseDir = compilation.kspWorkingDir - - this.processingOptions.putAll(compilation.kspArgs) - - this.incremental = this@KspCompileTestingComponentRegistrar.incremental - this.incrementalLog = this@KspCompileTestingComponentRegistrar.incrementalLog - - this.cachesDir = compilation.kspCachesDir.also { - it.deleteRecursively() - it.mkdirs() - } - this.kspOutputDir = compilation.kspSourcesDir.also { - it.deleteRecursively() - it.mkdirs() - } - this.classOutputDir = compilation.kspClassesDir.also { - it.deleteRecursively() - it.mkdirs() - } - this.javaOutputDir = compilation.kspJavaSourceDir.also { - it.deleteRecursively() - it.mkdirs() - } - this.kotlinOutputDir = compilation.kspKotlinSourceDir.also { - it.deleteRecursively() - it.mkdirs() - } - this.resourceOutputDir = compilation.kspResources.also { - it.deleteRecursively() - it.mkdirs() - } - }.build() - - // Temporary until friend-paths is fully supported https://youtrack.jetbrains.com/issue/KT-34102 - @Suppress("invisible_member") - val messageCollectorBasedKSPLogger = MessageCollectorBasedKSPLogger( - PrintingMessageCollector( - compilation.internalMessageStreamAccess, - MessageRenderer.GRADLE_STYLE, - compilation.verbose - ) - ) - val registrar = KspTestExtension(options, processorProviders, messageCollectorBasedKSPLogger) - AnalysisHandlerExtension.registerExtension(project, registrar) - } -} - -/** - * Gets the test registrar from the plugin list or adds if it does not exist. - */ -private fun KotlinCompilation.getKspRegistrar(): KspCompileTestingComponentRegistrar { - compilerPlugins.firstIsInstanceOrNull()?.let { - return it - } - val kspRegistrar = KspCompileTestingComponentRegistrar(this) - compilerPlugins = compilerPlugins + kspRegistrar - return kspRegistrar -} diff --git a/moshi-ksp/moshi-ksp/src/test/kotlin/dev/zacsweers/moshix/ksp/JsonClassSymbolProcessorTest.kt b/moshi-ksp/moshi-ksp/src/test/kotlin/dev/zacsweers/moshix/ksp/JsonClassSymbolProcessorTest.kt index 36b9e374..82f52b91 100644 --- a/moshi-ksp/moshi-ksp/src/test/kotlin/dev/zacsweers/moshix/ksp/JsonClassSymbolProcessorTest.kt +++ b/moshi-ksp/moshi-ksp/src/test/kotlin/dev/zacsweers/moshix/ksp/JsonClassSymbolProcessorTest.kt @@ -41,7 +41,6 @@ import kotlin.reflect.KVariance.INVARIANT import kotlin.reflect.full.createType /** Execute kotlinc to confirm that either files are generated or errors are printed. */ -@Ignore("https://github.com/google/ksp/issues/427") @RunWith(Parameterized::class) class JsonClassSymbolProcessorTest(private val incremental: Boolean) { @@ -326,7 +325,7 @@ class JsonClassSymbolProcessorTest(private val incremental: Boolean) { ) assertThat(result.exitCode).isEqualTo(KotlinCompilation.ExitCode.COMPILATION_ERROR) assertThat(result.messages).contains( - "@JsonClass can't be applied to expression: must be a Kotlin class" + "@JsonClass can't be applied to test.expression: must be a Kotlin class" ) } diff --git a/moshi-sealed/codegen-ksp/build.gradle.kts b/moshi-sealed/codegen-ksp/build.gradle.kts index 464116f4..08c82bd1 100644 --- a/moshi-sealed/codegen-ksp/build.gradle.kts +++ b/moshi-sealed/codegen-ksp/build.gradle.kts @@ -37,8 +37,7 @@ dependencies { testImplementation(libs.ksp) testImplementation(libs.truth) testImplementation(libs.junit) - // TODO re-enable with new release -// testImplementation(Dependencies.Testing.kspCompileTesting) testImplementation(libs.kotlinCompileTesting) + testImplementation(libs.kotlinCompileTesting.ksp) testImplementation(libs.kotlin.compilerEmbeddable) } diff --git a/moshi-sealed/codegen-ksp/src/test/kotlin/com/tschuchort/compiletesting/symbolProcessors.kt b/moshi-sealed/codegen-ksp/src/test/kotlin/com/tschuchort/compiletesting/symbolProcessors.kt deleted file mode 100644 index bcd9be38..00000000 --- a/moshi-sealed/codegen-ksp/src/test/kotlin/com/tschuchort/compiletesting/symbolProcessors.kt +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright (C) 2021 Zac Sweers - * - * 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 - * - * https://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 com.tschuchort.compiletesting - -import com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension -import com.google.devtools.ksp.KspOptions -import com.google.devtools.ksp.processing.KSPLogger -import com.google.devtools.ksp.processing.SymbolProcessorProvider -import com.google.devtools.ksp.processing.impl.MessageCollectorBasedKSPLogger -import org.jetbrains.kotlin.cli.common.messages.MessageRenderer -import org.jetbrains.kotlin.cli.common.messages.PrintingMessageCollector -import org.jetbrains.kotlin.com.intellij.mock.MockProject -import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar -import org.jetbrains.kotlin.config.CompilerConfiguration -import org.jetbrains.kotlin.resolve.jvm.extensions.AnalysisHandlerExtension -import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull -import java.io.File - -/** - * The list of symbol processors for the kotlin compilation. - * https://goo.gle/ksp - */ -var KotlinCompilation.symbolProcessorProviders: List - get() = getKspRegistrar().processorProviders - set(value) { - val registrar = getKspRegistrar() - registrar.processorProviders = value - } - -/** - * The directory where generated KSP sources are written - */ -val KotlinCompilation.kspSourcesDir: File - get() = kspWorkingDir.resolve("sources") - -/** - * Arbitrary arguments to be passed to ksp - */ -var KotlinCompilation.kspArgs: MutableMap - get() = getKspRegistrar().options - set(value) { - val registrar = getKspRegistrar() - registrar.options = value - } - -/** - * Controls for enabling incremental processing in KSP. - */ -var KotlinCompilation.kspIncremental: Boolean - get() = getKspRegistrar().incremental - set(value) { - val registrar = getKspRegistrar() - registrar.incremental = value - } - -/** - * Controls for enabling incremental processing logs in KSP. - */ -var KotlinCompilation.kspIncrementalLog: Boolean - get() = getKspRegistrar().incrementalLog - set(value) { - val registrar = getKspRegistrar() - registrar.incrementalLog = value - } - -private val KotlinCompilation.kspJavaSourceDir: File - get() = kspSourcesDir.resolve("java") - -private val KotlinCompilation.kspKotlinSourceDir: File - get() = kspSourcesDir.resolve("kotlin") - -private val KotlinCompilation.kspResources: File - get() = kspSourcesDir.resolve("resources") - -/** - * The working directory for KSP - */ -private val KotlinCompilation.kspWorkingDir: File - get() = workingDir.resolve("ksp") - -/** - * The directory where compiled KSP classes are written - */ -// TODO this seems to be ignored by KSP and it is putting classes into regular classes directory -// but we still need to provide it in the KSP options builder as it is required -// once it works, we should make the property public. -private val KotlinCompilation.kspClassesDir: File - get() = kspWorkingDir.resolve("classes") - -/** - * The directory where compiled KSP caches are written - */ -private val KotlinCompilation.kspCachesDir: File - get() = kspWorkingDir.resolve("caches") - -/** - * Custom subclass of [AbstractKotlinSymbolProcessingExtension] where processors are pre-defined instead of being - * loaded via ServiceLocator. - */ -private class KspTestExtension( - options: KspOptions, - private val testProcessorProviders: List, - logger: KSPLogger -) : AbstractKotlinSymbolProcessingExtension( - options = options, - logger = logger, - testMode = false -) { - override fun loadProviders() = testProcessorProviders -} - -/** - * Registers the [KspTestExtension] to load the given list of processors. - */ -private class KspCompileTestingComponentRegistrar( - private val compilation: KotlinCompilation -) : ComponentRegistrar { - var processorProviders = emptyList() - - var options: MutableMap = mutableMapOf() - - var incremental: Boolean = false - var incrementalLog: Boolean = false - - override fun registerProjectComponents(project: MockProject, configuration: CompilerConfiguration) { - if (processorProviders.isEmpty()) { - return - } - val options = KspOptions.Builder().apply { - this.projectBaseDir = compilation.kspWorkingDir - - this.processingOptions.putAll(compilation.kspArgs) - - this.incremental = this@KspCompileTestingComponentRegistrar.incremental - this.incrementalLog = this@KspCompileTestingComponentRegistrar.incrementalLog - - this.cachesDir = compilation.kspCachesDir.also { - it.deleteRecursively() - it.mkdirs() - } - this.kspOutputDir = compilation.kspSourcesDir.also { - it.deleteRecursively() - it.mkdirs() - } - this.classOutputDir = compilation.kspClassesDir.also { - it.deleteRecursively() - it.mkdirs() - } - this.javaOutputDir = compilation.kspJavaSourceDir.also { - it.deleteRecursively() - it.mkdirs() - } - this.kotlinOutputDir = compilation.kspKotlinSourceDir.also { - it.deleteRecursively() - it.mkdirs() - } - this.resourceOutputDir = compilation.kspResources.also { - it.deleteRecursively() - it.mkdirs() - } - }.build() - - // Temporary until friend-paths is fully supported https://youtrack.jetbrains.com/issue/KT-34102 - @Suppress("invisible_member") - val messageCollectorBasedKSPLogger = MessageCollectorBasedKSPLogger( - PrintingMessageCollector( - compilation.internalMessageStreamAccess, - MessageRenderer.GRADLE_STYLE, - compilation.verbose - ) - ) - val registrar = KspTestExtension(options, processorProviders, messageCollectorBasedKSPLogger) - AnalysisHandlerExtension.registerExtension(project, registrar) - } -} - -/** - * Gets the test registrar from the plugin list or adds if it does not exist. - */ -private fun KotlinCompilation.getKspRegistrar(): KspCompileTestingComponentRegistrar { - compilerPlugins.firstIsInstanceOrNull()?.let { - return it - } - val kspRegistrar = KspCompileTestingComponentRegistrar(this) - compilerPlugins = compilerPlugins + kspRegistrar - return kspRegistrar -} diff --git a/moshi-sealed/codegen-ksp/src/test/kotlin/dev/zacsweers/moshix/sealed/codegen/ksp/MoshiSealedSymbolProcessorTest.kt b/moshi-sealed/codegen-ksp/src/test/kotlin/dev/zacsweers/moshix/sealed/codegen/ksp/MoshiSealedSymbolProcessorTest.kt index 1f3b7c28..2f3faf9f 100644 --- a/moshi-sealed/codegen-ksp/src/test/kotlin/dev/zacsweers/moshix/sealed/codegen/ksp/MoshiSealedSymbolProcessorTest.kt +++ b/moshi-sealed/codegen-ksp/src/test/kotlin/dev/zacsweers/moshix/sealed/codegen/ksp/MoshiSealedSymbolProcessorTest.kt @@ -24,13 +24,11 @@ import com.tschuchort.compiletesting.kspIncremental import com.tschuchort.compiletesting.kspSourcesDir import com.tschuchort.compiletesting.symbolProcessorProviders import dev.zacsweers.moshix.sealed.codegen.ksp.MoshiSealedSymbolProcessorProvider.Companion.OPTION_GENERATE_PROGUARD_RULES -import org.junit.Ignore import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.Parameterized import java.io.File -@Ignore("https://github.com/google/ksp/issues/427") @RunWith(Parameterized::class) class MoshiSealedSymbolProcessorProviderTest(private val incremental: Boolean) { @@ -106,8 +104,8 @@ class MoshiSealedSymbolProcessorProviderTest(private val incremental: Boolean) { public override fun fromJson(reader: JsonReader): BaseType? = runtimeAdapter.fromJson(reader) - public override fun toJson(writer: JsonWriter, value: BaseType?): Unit { - runtimeAdapter.toJson(writer, value) + public override fun toJson(writer: JsonWriter, value_: BaseType?): Unit { + runtimeAdapter.toJson(writer, value_) } } """.trimIndent() @@ -280,8 +278,8 @@ class MoshiSealedSymbolProcessorProviderTest(private val incremental: Boolean) { } val result = compilation.compile() assertThat(result.exitCode).isEqualTo(ExitCode.OK) - val generatedSourcesDir = compilation.kaptSourceDir - val generatedFile = File(generatedSourcesDir, "test/BaseTypeJsonAdapter.kt") + val generatedSourcesDir = compilation.kspSourcesDir + val generatedFile = File(generatedSourcesDir, "kotlin/test/BaseTypeJsonAdapter.kt") assertThat(generatedFile.exists()).isTrue() //language=kotlin assertThat(generatedFile.readText().trim()).isEqualTo(