aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTing-Yuan Huang <laszio@google.com>2022-11-18 14:47:47 -0800
committerlaszio <ting-yuan@users.noreply.github.com>2022-11-27 17:26:57 -0800
commit76ac8de5cd4769b2cfd7c80ad156309c5f27d52a (patch)
treea56f5d46494f4c13f04cfcc43fa5021e2c44b844
parent2448662c81cd923cfcf139d2288b483f2d191819 (diff)
downloadksp-76ac8de5cd4769b2cfd7c80ad156309c5f27d52a.tar.gz
Configure KSP tasks with modern KGP APIs
and minimize customizations in subclasses.
-rw-r--r--gradle-plugin/src/main/kotlin/com/google/devtools/ksp/gradle/KspSubplugin.kt505
-rw-r--r--integration-tests/src/test/kotlin/com/google/devtools/ksp/test/PlaygroundIT.kt5
2 files changed, 128 insertions, 382 deletions
diff --git a/gradle-plugin/src/main/kotlin/com/google/devtools/ksp/gradle/KspSubplugin.kt b/gradle-plugin/src/main/kotlin/com/google/devtools/ksp/gradle/KspSubplugin.kt
index 8b81699e..2715caad 100644
--- a/gradle-plugin/src/main/kotlin/com/google/devtools/ksp/gradle/KspSubplugin.kt
+++ b/gradle-plugin/src/main/kotlin/com/google/devtools/ksp/gradle/KspSubplugin.kt
@@ -31,7 +31,6 @@ import org.gradle.api.file.FileCollection
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.MapProperty
-import org.gradle.api.provider.Property
import org.gradle.api.provider.Provider
import org.gradle.api.provider.ProviderFactory
import org.gradle.api.tasks.*
@@ -48,18 +47,16 @@ import org.gradle.workers.WorkerExecutor
import org.jetbrains.kotlin.cli.common.arguments.*
import org.jetbrains.kotlin.config.ApiVersion
import org.jetbrains.kotlin.gradle.dsl.*
-import org.jetbrains.kotlin.gradle.internal.CompilerArgumentsContributor
-import org.jetbrains.kotlin.gradle.internal.compilerArgumentsConfigurationFlags
import org.jetbrains.kotlin.gradle.internal.kapt.incremental.*
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.mpp.*
import org.jetbrains.kotlin.gradle.targets.js.ir.*
import org.jetbrains.kotlin.gradle.tasks.*
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
-import org.jetbrains.kotlin.gradle.tasks.configuration.AbstractKotlinCompileConfig
-import org.jetbrains.kotlin.gradle.utils.klibModuleName
+import org.jetbrains.kotlin.gradle.tasks.configuration.BaseKotlin2JsCompileConfig
+import org.jetbrains.kotlin.gradle.tasks.configuration.KotlinCompileCommonConfig
+import org.jetbrains.kotlin.gradle.tasks.configuration.KotlinCompileConfig
import org.jetbrains.kotlin.incremental.ChangedFiles
-import org.jetbrains.kotlin.incremental.destinationAsFile
import org.jetbrains.kotlin.incremental.isJavaFile
import org.jetbrains.kotlin.incremental.isKotlinFile
import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty
@@ -67,82 +64,6 @@ import java.io.File
import java.nio.file.Paths
import java.util.concurrent.Callable
import javax.inject.Inject
-import kotlin.reflect.KProperty1
-
-@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER", "EXPOSED_PARAMETER_TYPE")
-internal class Configurator : AbstractKotlinCompileConfig<AbstractKotlinCompile<*>> {
- constructor (
- compilation: KotlinCompilation<*>,
- kotlinCompile: AbstractKotlinCompile<*>
- ) : super(KotlinCompilationInfo(compilation)) {
- configureTask { task ->
- if (task is KspTaskJvm) {
- // Assign ownModuleName different from kotlin compilation to
- // work around https://github.com/google/ksp/issues/647
- // This will not be necessary once https://youtrack.jetbrains.com/issue/KT-45777 lands
- task.ownModuleName.value(kotlinCompile.ownModuleName.map { "$it-ksp" })
- (compilation.compilerOptions.options as? KotlinJvmCompilerOptions)?.let {
- task.compilerOptions.noJdk.value(it.noJdk)
- }
- }
- if (task is KspTaskJS) {
- val libraryCacheService = project.rootProject.gradle.sharedServices.registerIfAbsent(
- Kotlin2JsCompile.LibraryFilterCachingService::class.java.canonicalName +
- "_${Kotlin2JsCompile.LibraryFilterCachingService::class.java.classLoader.hashCode()}",
- Kotlin2JsCompile.LibraryFilterCachingService::class.java
- ) {}
- task.compilerOptions.moduleName.convention(kotlinCompile.ownModuleName.map { "$it-ksp" })
- task.libraryCache.set(libraryCacheService).also { task.libraryCache.disallowChanges() }
- task.pluginClasspath.setFrom(objectFactory.fileCollection())
- task.outputFileProperty.value(
- task.destinationDirectory.flatMap { dir ->
- if (task.compilerOptions.outputFile.orNull != null) {
- task.compilerOptions.outputFile.map { File(it) }
- } else {
- task.compilerOptions.moduleName.map { name ->
- dir.file(name + compilation.platformType.fileExtension).asFile
- }
- }
- }
- )
- task.enhancedFreeCompilerArgs.value(
- (kotlinCompile as Kotlin2JsCompile).compilerOptions.freeCompilerArgs.map { freeArgs ->
- freeArgs.toMutableList().apply {
- commonJsAdditionalCompilerFlags(compilation)
- }
- }
- ).disallowChanges()
- }
- }
- }
-
- // copied from upstream.
- protected fun MutableList<String>.commonJsAdditionalCompilerFlags(
- compilation: KotlinCompilation<*>
- ) {
- if (contains(DISABLE_PRE_IR) &&
- !contains(PRODUCE_UNZIPPED_KLIB) &&
- !contains(PRODUCE_ZIPPED_KLIB)
- ) {
- add(PRODUCE_UNZIPPED_KLIB)
- }
-
- if (contains(PRODUCE_JS) ||
- contains(PRODUCE_UNZIPPED_KLIB) ||
- contains(PRODUCE_ZIPPED_KLIB)
- ) {
- // Configure FQ module name to avoid cyclic dependencies in klib manifests (see KT-36721).
- val baseName = if (compilation.isMain()) {
- project.name
- } else {
- "${project.name}_${compilation.compilationName}"
- }
- if (none { it.startsWith(KLIB_MODULE_NAME) }) {
- add("$KLIB_MODULE_NAME=${project.klibModuleName(baseName)}")
- }
- }
- }
-}
class KspGradleSubplugin @Inject internal constructor(private val registry: ToolingModelBuilderRegistry) :
KotlinCompilerPluginSupportPlugin {
@@ -189,21 +110,21 @@ class KspGradleSubplugin @Inject internal constructor(private val registry: Tool
commandLineArgumentProviders: ListProperty<CommandLineArgumentProvider>,
): List<SubpluginOption> {
val options = mutableListOf<SubpluginOption>()
- options += SubpluginOption("classOutputDir", getKspClassOutputDir(project, sourceSetName, target).path)
- options += SubpluginOption("javaOutputDir", getKspJavaOutputDir(project, sourceSetName, target).path)
- options += SubpluginOption("kotlinOutputDir", getKspKotlinOutputDir(project, sourceSetName, target).path)
- options += SubpluginOption(
+ options += InternalSubpluginOption("classOutputDir", getKspClassOutputDir(project, sourceSetName, target).path)
+ options += InternalSubpluginOption("javaOutputDir", getKspJavaOutputDir(project, sourceSetName, target).path)
+ options += InternalSubpluginOption("kotlinOutputDir", getKspKotlinOutputDir(project, sourceSetName, target).path)
+ options += InternalSubpluginOption(
"resourceOutputDir",
getKspResourceOutputDir(project, sourceSetName, target).path
)
- options += SubpluginOption("cachesDir", getKspCachesDir(project, sourceSetName, target).path)
- options += SubpluginOption("kspOutputDir", getKspOutputDir(project, sourceSetName, target).path)
+ options += InternalSubpluginOption("cachesDir", getKspCachesDir(project, sourceSetName, target).path)
+ options += InternalSubpluginOption("kspOutputDir", getKspOutputDir(project, sourceSetName, target).path)
options += SubpluginOption("incremental", isIncremental.toString())
options += SubpluginOption(
"incrementalLog",
project.findProperty("ksp.incremental.log")?.toString() ?: "false"
)
- options += SubpluginOption("projectBaseDir", project.project.projectDir.canonicalPath)
+ options += InternalSubpluginOption("projectBaseDir", project.project.projectDir.canonicalPath)
options += SubpluginOption("allWarningsAsErrors", allWarningsAsErrors.toString())
options += FilesSubpluginOption("apclasspath", classpath.toList())
// Turn this on by default to work KT-30172 around. It is off by default in the compiler plugin.
@@ -328,13 +249,9 @@ class KspGradleSubplugin @Inject internal constructor(private val registry: Tool
}
)
kspTask.destination = kspOutputDir
- kspTask.blockOtherCompilerPlugins = kspExtension.blockOtherCompilerPlugins
kspTask.apOptions.value(kspExtension.arguments).disallowChanges()
kspTask.kspCacheDir.fileValue(getKspCachesDir(project, sourceSetName, target)).disallowChanges()
- if (kspExtension.blockOtherCompilerPlugins) {
- kspTask.overridePluginClasspath.from(kspClasspathCfg)
- }
kspTask.isKspIncremental = isIncremental
}
@@ -365,69 +282,131 @@ class KspGradleSubplugin @Inject internal constructor(private val registry: Tool
kspTask.setSource(kotlinCompilation.defaultSourceSet.kotlin)
}
}
+ kspTask.exclude { kspOutputDir.isParentOf(it.file) }
- // Don't support binary generation for non-JVM platforms yet.
- // FIXME: figure out how to add user generated libraries.
- if (kspTask is KspTaskJvm) {
- kotlinCompilation.output.classesDirs.from(classOutputDir)
+ // kotlinc's incremental compilation isn't compatible with symbol processing in a few ways:
+ // * It doesn't consider private / internal changes when computing dirty sets.
+ // * It compiles iteratively; Sources can be compiled in different rounds.
+ (kspTask as? AbstractKotlinCompile<*>)?.incremental = false
+ }
+
+ fun maybeBlockOtherPlugins(kspTask: BaseKotlinCompile) {
+ if (kspExtension.blockOtherCompilerPlugins) {
+ kspTask.pluginClasspath.setFrom(kspClasspathCfg)
+ kspTask.pluginOptions.set(emptyList())
}
}
- val kspTaskProvider = when (kotlinCompileTask) {
- is AbstractKotlinCompile<*> -> {
- val kspTaskClass = when (kotlinCompileTask) {
- is KotlinCompile -> KspTaskJvm::class.java
- is Kotlin2JsCompile -> KspTaskJS::class.java
- is KotlinCompileCommon -> KspTaskMetadata::class.java
- else -> return project.provider { emptyList() }
+ fun configurePluginOptions(kspTask: BaseKotlinCompile) {
+ kspTask.pluginOptions.add(
+ project.provider {
+ CompilerPluginConfig().apply {
+ (kspTask as KspTask).options.get().forEach {
+ addPluginArgument(KSP_PLUGIN_ID, it)
+ }
+ }
}
- val isIncremental = project.findProperty("ksp.incremental")?.toString()?.toBoolean() ?: true
- project.tasks.register(kspTaskName, kspTaskClass) { kspTask ->
- configureAsKspTask(kspTask, isIncremental)
- configureAsAbstractKotlinCompileTool(kspTask)
+ )
+ }
+
+ // Create KSP tasks and configure later.
+ val kspTaskProvider = when (kotlinCompileTask) {
+ is KotlinCompile ->
+ project.tasks.register(kspTaskName, KspTaskJvm::class.java)
+ is Kotlin2JsCompile ->
+ project.tasks.register(kspTaskName, KspTaskJS::class.java)
+ is KotlinCompileCommon ->
+ project.tasks.register(kspTaskName, KspTaskMetadata::class.java)
+ is KotlinNativeCompile ->
+ project.tasks.register(kspTaskName, KspTaskNative::class.java, kotlinCompileTask.compilation)
+ else -> return project.provider { emptyList() }
+ }
+
+ val isIncremental = project.findProperty("ksp.incremental")?.toString()?.toBoolean() ?: true
+ // Configure KSP tasks
+ when (kotlinCompileTask) {
+ is KotlinCompile -> {
+ kspTaskProvider.configure { kspTask ->
kspTask.libraries.setFrom(kotlinCompileTask.project.files(Callable { kotlinCompileTask.libraries }))
- kspTask.configureCompilation(
- kotlinCompilation,
- kotlinCompileTask,
- )
+ }
+ KotlinCompileConfig(KotlinCompilationInfo(kotlinCompilation))
+ .execute(kspTaskProvider as TaskProvider<KotlinCompile>)
+ kspTaskProvider.configure { kspTask ->
+ kspTask as KspTaskJvm
+ maybeBlockOtherPlugins(kspTask as BaseKotlinCompile)
+ configureAsKspTask(kspTask as KspTask, isIncremental)
+ configureAsAbstractKotlinCompileTool(kspTask as AbstractKotlinCompileTool<*>)
+ configurePluginOptions(kspTask)
+ kspTask.configureClasspathSnapshot()
+ kspTask.compilerOptions.noJdk.value(kotlinCompileTask.compilerOptions.noJdk)
+ kspTask.compilerOptions.useK2.value(false)
+ kspTask.compilerOptions.moduleName.convention(kotlinCompileTask.moduleName.map { "$it-ksp" })
+ kspTask.moduleName.value(kotlinCompileTask.moduleName.get())
+ }
+ // Don't support binary generation for non-JVM platforms yet.
+ // FIXME: figure out how to add user generated libraries.
+ kotlinCompilation.output.classesDirs.from(classOutputDir)
+ }
+ is Kotlin2JsCompile -> {
+ kspTaskProvider.configure { kspTask ->
+ kspTask.libraries.setFrom(kotlinCompileTask.project.files(Callable { kotlinCompileTask.libraries }))
+ kspTask.compilerOptions.freeCompilerArgs.value(kotlinCompileTask.compilerOptions.freeCompilerArgs)
+ }
+ BaseKotlin2JsCompileConfig<Kotlin2JsCompile>(KotlinCompilationInfo(kotlinCompilation))
+ .execute(kspTaskProvider as TaskProvider<Kotlin2JsCompile>)
+ kspTaskProvider.configure { kspTask ->
+ kspTask as KspTaskJS
+ maybeBlockOtherPlugins(kspTask as BaseKotlinCompile)
+ configureAsKspTask(kspTask as KspTask, isIncremental)
+ configureAsAbstractKotlinCompileTool(kspTask as AbstractKotlinCompileTool<*>)
+ configurePluginOptions(kspTask)
+ kspTask.compilerOptions.useK2.value(false)
+ kspTask.compilerOptions.moduleName.convention(kotlinCompileTask.moduleName.map { "$it-ksp" })
+ (kspTask as KspTaskJS).incrementalJsKlib = false
+ }
+ }
+ is KotlinCompileCommon -> {
+ kspTaskProvider.configure { kspTask ->
+ kspTask.libraries.setFrom(kotlinCompileTask.project.files(Callable { kotlinCompileTask.libraries }))
+ }
+ KotlinCompileCommonConfig(KotlinCompilationInfo(kotlinCompilation))
+ .execute(kspTaskProvider as TaskProvider<KotlinCompileCommon>)
+ kspTaskProvider.configure { kspTask ->
+ maybeBlockOtherPlugins(kspTask as BaseKotlinCompile)
+ configureAsKspTask(kspTask as KspTask, isIncremental)
+ configureAsAbstractKotlinCompileTool(kspTask as AbstractKotlinCompileTool<*>)
+ configurePluginOptions(kspTask)
+ kspTask.compilerOptions.useK2.value(false)
}
}
is KotlinNativeCompile -> {
- val kspTaskClass = KspTaskNative::class.java
- project.tasks.register(kspTaskName, kspTaskClass, kotlinCompileTask.compilation).apply {
- configure { kspTask ->
- kspTask.onlyIf {
- kspTask.konanTarget.enabledOnCurrentHost
- }
- configureAsKspTask(kspTask, false)
- configureAsAbstractKotlinCompileTool(kspTask)
-
- // KotlinNativeCompile computes -Xplugin=... from compilerPluginClasspath.
- if (kspExtension.blockOtherCompilerPlugins) {
- kspTask.compilerPluginClasspath = kspClasspathCfg
- } else {
- kspTask.compilerPluginClasspath =
- kspClasspathCfg + kotlinCompileTask.compilerPluginClasspath!!
- kspTask.compilerPluginOptions.addPluginArgument(kotlinCompileTask.compilerPluginOptions)
- }
- kspTask.commonSources.from(kotlinCompileTask.commonSources)
- val kspOptions = kspTask.options.get().flatMap { listOf("-P", it.toArg()) }
- kspTask.compilerOptions.freeCompilerArgs.value(
- kspOptions + kotlinCompileTask.compilerOptions.freeCompilerArgs.get()
- )
- kspTask.doFirst {
- kspOutputDir.deleteRecursively()
- }
+ kspTaskProvider.configure { kspTask ->
+ kspTask as KspTaskNative
+ kspTask.onlyIf {
+ kspTask.konanTarget.enabledOnCurrentHost
+ }
+ configureAsKspTask(kspTask, false)
+ configureAsAbstractKotlinCompileTool(kspTask)
+
+ // KotlinNativeCompile computes -Xplugin=... from compilerPluginClasspath.
+ if (kspExtension.blockOtherCompilerPlugins) {
+ kspTask.compilerPluginClasspath = kspClasspathCfg
+ } else {
+ kspTask.compilerPluginClasspath =
+ kspClasspathCfg + kotlinCompileTask.compilerPluginClasspath!!
+ kspTask.compilerPluginOptions.addPluginArgument(kotlinCompileTask.compilerPluginOptions)
+ }
+ kspTask.commonSources.from(kotlinCompileTask.commonSources)
+ val kspOptions = kspTask.options.get().flatMap { listOf("-P", it.toArg()) }
+ kspTask.compilerOptions.freeCompilerArgs.value(
+ kspOptions + kotlinCompileTask.compilerOptions.freeCompilerArgs.get()
+ )
+ kspTask.doFirst {
+ kspOutputDir.deleteRecursively()
}
}
}
- else -> return project.provider { emptyList() }
- }
-
- (kotlinCompileTask as? AbstractKotlinCompile<*>)?.let {
- Configurator(kotlinCompilation, kotlinCompileTask as AbstractKotlinCompile<*>)
- .execute(kspTaskProvider as TaskProvider<AbstractKotlinCompile<*>>)
}
kotlinCompileProvider.configure { kotlinCompile ->
@@ -509,13 +488,6 @@ interface KspTask : Task {
@get:OutputDirectory
var destination: File
- @get:Optional
- @get:Classpath
- val overridePluginClasspath: ConfigurableFileCollection
-
- @get:Input
- var blockOtherCompilerPlugins: Boolean
-
@get:Input
val apOptions: MapProperty<String, String>
@@ -530,11 +502,6 @@ interface KspTask : Task {
@get:Input
var isKspIncremental: Boolean
-
- fun configureCompilation(
- kotlinCompilation: KotlinCompilation<*>,
- kotlinCompile: AbstractKotlinCompile<*>,
- )
}
@CacheableTask
@@ -556,24 +523,13 @@ abstract class KspTaskJvm @Inject constructor(
@get:Input
var isIntermoduleIncremental: Boolean = false
- override fun configureCompilation(
- kotlinCompilation: KotlinCompilation<*>,
- kotlinCompile: AbstractKotlinCompile<*>,
- ) {
- kotlinCompile as KotlinCompile
- val providerFactory = kotlinCompile.project.providers
- compileKotlinArgumentsContributor.set(
- providerFactory.provider {
- kotlinCompile.compilerArgumentsContributor
- }
- )
-
+ fun configureClasspathSnapshot() {
isIntermoduleIncremental =
(project.findProperty("ksp.incremental.intermodule")?.toString()?.toBoolean() ?: true) &&
isKspIncremental
if (isIntermoduleIncremental) {
val classStructureIfIncremental = project.configurations.detachedConfiguration(
- project.dependencies.create(project.files(project.provider { kotlinCompile.libraries }))
+ project.dependencies.create(project.files(project.provider { libraries }))
)
maybeRegisterTransform(project)
@@ -582,13 +538,7 @@ abstract class KspTaskJvm @Inject constructor(
viewConfig.attributes.attribute(artifactType, CLASS_STRUCTURE_ARTIFACT_TYPE)
}.files
).disallowChanges()
- classpathSnapshotProperties.useClasspathSnapshot.value(true).disallowChanges()
- } else {
- classpathSnapshotProperties.useClasspathSnapshot.value(false).disallowChanges()
}
-
- // Used only in incremental compilation and is not applicable to KSP.
- useKotlinAbiSnapshot.value(false)
}
private fun maybeRegisterTransform(project: Project) {
@@ -661,44 +611,12 @@ abstract class KspTaskJvm @Inject constructor(
return classpathChanges
}
- @get:Internal
- internal abstract val compileKotlinArgumentsContributor:
- Property<CompilerArgumentsContributor<K2JVMCompilerArguments>>
-
init {
- // kotlinc's incremental compilation isn't compatible with symbol processing in a few ways:
- // * It doesn't consider private / internal changes when computing dirty sets.
- // * It compiles iteratively; Sources can be compiled in different rounds.
- incremental = false
-
// Mute a warning from ScriptingGradleSubplugin, which tries to get `sourceSetName` before this task is
// configured.
sourceSetName.set("main")
}
- override fun setupCompilerArgs(
- args: K2JVMCompilerArguments,
- defaultsOnly: Boolean,
- ignoreClasspathResolutionErrors: Boolean,
- ) {
- // Start with / copy from kotlinCompile.
- compileKotlinArgumentsContributor.get().contributeArguments(
- args,
- compilerArgumentsConfigurationFlags(
- defaultsOnly,
- ignoreClasspathResolutionErrors
- )
- )
- (compilerOptions as KotlinJvmCompilerOptionsDefault).fillCompilerArguments(args)
- if (blockOtherCompilerPlugins) {
- args.blockOtherPlugins(overridePluginClasspath)
- }
- args.addPluginOptions(options.get())
- args.destinationAsFile = destination
- args.allowNoSourceFiles = true
- args.useK2 = false
- }
-
// Overrding an internal function is hacky.
// TODO: Ask upstream to open it.
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER", "EXPOSED_PARAMETER_TYPE")
@@ -725,6 +643,7 @@ abstract class KspTaskJvm @Inject constructor(
clearIncCache()
}
args.addChangedFiles(changedFiles)
+ args.allowNoSourceFiles = true
super.callCompilerAsync(args, kotlinSources, inputChanges, taskOutputsBackup)
}
@@ -743,14 +662,6 @@ abstract class KspTaskJvm @Inject constructor(
@get:SkipWhenEmpty
@get:IgnoreEmptyDirectories
@get:PathSensitive(PathSensitivity.RELATIVE)
- override val sources: FileCollection = super.sources.filter {
- !destination.isParentOf(it)
- }
-
- @get:InputFiles
- @get:SkipWhenEmpty
- @get:IgnoreEmptyDirectories
- @get:PathSensitive(PathSensitivity.RELATIVE)
override val javaSources: FileCollection = super.javaSources.filter {
!destination.isParentOf(it)
}
@@ -766,60 +677,6 @@ abstract class KspTaskJS @Inject constructor(
workerExecutor
),
KspTask {
- private val backendSelectionArgs = listOf(
- "-Xir-only",
- "-Xir-produce-js",
- "-Xir-produce-klib-dir",
- "-Xir-produce-klib-file"
- )
-
- override fun configureCompilation(
- kotlinCompilation: KotlinCompilation<*>,
- kotlinCompile: AbstractKotlinCompile<*>,
- ) {
- kotlinCompile as Kotlin2JsCompile
-
- val providerFactory = kotlinCompile.project.providers
- compileKotlinArgumentsContributor.set(
- providerFactory.provider {
- kotlinCompile.abstractKotlinCompileArgumentsContributor
- }
- )
- }
-
- @get:Internal
- internal abstract val compileKotlinArgumentsContributor:
- Property<CompilerArgumentsContributor<K2JSCompilerArguments>>
-
- init {
- // kotlinc's incremental compilation isn't compatible with symbol processing in a few ways:
- // * It doesn't consider private / internal changes when computing dirty sets.
- // * It compiles iteratively; Sources can be compiled in different rounds.
- incremental = false
- }
-
- override fun setupCompilerArgs(
- args: K2JSCompilerArguments,
- defaultsOnly: Boolean,
- ignoreClasspathResolutionErrors: Boolean,
- ) {
- // Start with / copy from kotlinCompile.
- compileKotlinArgumentsContributor.get().contributeArguments(
- args,
- compilerArgumentsConfigurationFlags(
- defaultsOnly,
- ignoreClasspathResolutionErrors
- )
- )
- (compilerOptions as KotlinJsCompilerOptionsDefault).fillCompilerArguments(args)
- if (blockOtherCompilerPlugins) {
- args.blockOtherPlugins(overridePluginClasspath)
- }
- args.addPluginOptions(options.get())
- args.outputFile = File(destination, "dummyOutput.js").canonicalPath
- args.useK2 = false
- args.outputDir = destination.canonicalPath
- }
// Overrding an internal function is hacky.
// TODO: Ask upstream to open it.
@@ -836,22 +693,8 @@ abstract class KspTaskJS @Inject constructor(
} else {
args.addChangedFiles(changedFiles)
}
- args.freeArgs = enhancedFreeCompilerArgs.get()
super.callCompilerAsync(args, kotlinSources, inputChanges, taskOutputsBackup)
}
-
- // Overrding an internal function is hacky.
- // TODO: Ask upstream to open it.
- @Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER", "EXPOSED_PARAMETER_TYPE")
- fun `isIncrementalCompilationEnabled$kotlin_gradle_plugin_common`(): Boolean = false
-
- @get:InputFiles
- @get:SkipWhenEmpty
- @get:IgnoreEmptyDirectories
- @get:PathSensitive(PathSensitivity.RELATIVE)
- override val sources: FileCollection = super.sources.filter {
- !destination.isParentOf(it)
- }
}
@CacheableTask
@@ -864,56 +707,6 @@ abstract class KspTaskMetadata @Inject constructor(
objectFactory
),
KspTask {
- override fun configureCompilation(
- kotlinCompilation: KotlinCompilation<*>,
- kotlinCompile: AbstractKotlinCompile<*>,
- ) {
- kotlinCompile as KotlinCompileCommon
- val providerFactory = kotlinCompile.project.providers
- compileKotlinArgumentsContributor.set(
- providerFactory.provider {
- kotlinCompile.abstractKotlinCompileArgumentsContributor
- }
- )
- }
-
- @get:Internal
- internal abstract val compileKotlinArgumentsContributor:
- Property<CompilerArgumentsContributor<K2MetadataCompilerArguments>>
-
- init {
- // kotlinc's incremental compilation isn't compatible with symbol processing in a few ways:
- // * It doesn't consider private / internal changes when computing dirty sets.
- // * It compiles iteratively; Sources can be compiled in different rounds.
- incremental = false
- }
-
- override fun setupCompilerArgs(
- args: K2MetadataCompilerArguments,
- defaultsOnly: Boolean,
- ignoreClasspathResolutionErrors: Boolean,
- ) {
- // Start with / copy from kotlinCompile.
- compileKotlinArgumentsContributor.get().contributeArguments(
- args,
- compilerArgumentsConfigurationFlags(
- defaultsOnly,
- ignoreClasspathResolutionErrors
- )
- )
- (compilerOptions as KotlinMultiplatformCommonCompilerOptionsDefault).fillCompilerArguments(args)
- if (blockOtherCompilerPlugins) {
- args.blockOtherPlugins(overridePluginClasspath)
- }
- args.addPluginOptions(options.get())
- args.destination = destination.canonicalPath
- val classpathList = libraries.files.filter { it.exists() }.toMutableList()
- args.classpath = classpathList.joinToString(File.pathSeparator)
- args.friendPaths = friendPaths.files.map { it.absolutePath }.toTypedArray()
- args.refinesPaths = refinesMetadataPaths.map { it.absolutePath }.toTypedArray()
- args.expectActualLinker = true
- args.useK2 = false
- }
// Overrding an internal function is hacky.
// TODO: Ask upstream to open it.
@@ -930,16 +723,9 @@ abstract class KspTaskMetadata @Inject constructor(
} else {
args.addChangedFiles(changedFiles)
}
+ args.expectActualLinker = true
super.callCompilerAsync(args, kotlinSources, inputChanges, taskOutputsBackup)
}
-
- @get:InputFiles
- @get:SkipWhenEmpty
- @get:IgnoreEmptyDirectories
- @get:PathSensitive(PathSensitivity.RELATIVE)
- override val sources: FileCollection = super.sources.filter {
- !destination.isParentOf(it)
- }
}
@CacheableTask
@@ -952,19 +738,6 @@ abstract class KspTaskNative @Inject internal constructor(
override val compilerOptions: KotlinCommonCompilerOptions =
objectFactory.newInstance(KotlinMultiplatformCommonCompilerOptionsDefault::class.java)
-
- override fun configureCompilation(
- kotlinCompilation: KotlinCompilation<*>,
- kotlinCompile: AbstractKotlinCompile<*>,
- ) = Unit
-
- @get:InputFiles
- @get:SkipWhenEmpty
- @get:IgnoreEmptyDirectories
- @get:PathSensitive(PathSensitivity.RELATIVE)
- override val sources: FileCollection = super.sources.filter {
- !destination.isParentOf(it)
- }
}
// This forces rebuild.
@@ -1008,32 +781,6 @@ fun CommonCompilerArguments.addChangedFiles(changedFiles: ChangedFiles) {
}
}
-private fun CommonCompilerArguments.blockOtherPlugins(kspPluginClasspath: FileCollection) {
- pluginClasspaths = kspPluginClasspath.map { it.canonicalPath }.toTypedArray()
- pluginOptions = arrayOf()
-}
-
-// TODO: Move into dumpArgs after the compiler supports local function in inline functions.
-private inline fun <reified T : CommonCompilerArguments> T.toPair(property: KProperty1<T, *>): Pair<String, String> {
- @Suppress("UNCHECKED_CAST")
- val value = (property as KProperty1<T, *>).get(this)
- return property.name to if (value is Array<*>)
- value.asList().toString()
- else
- value.toString()
-}
-
-@Suppress("unused")
-internal inline fun <reified T : CommonCompilerArguments> dumpArgs(args: T): Map<String, String> {
- @Suppress("UNCHECKED_CAST")
- val argumentProperties =
- args::class.members.mapNotNull { member ->
- (member as? KProperty1<T, *>)?.takeIf { it.annotations.any { ann -> ann is Argument } }
- }
-
- return argumentProperties.associate(args::toPair).toSortedMap()
-}
-
internal fun File.isParentOf(childCandidate: File): Boolean {
val parentPath = Paths.get(this.absolutePath).normalize()
val childCandidatePath = Paths.get(childCandidate.absolutePath).normalize()
diff --git a/integration-tests/src/test/kotlin/com/google/devtools/ksp/test/PlaygroundIT.kt b/integration-tests/src/test/kotlin/com/google/devtools/ksp/test/PlaygroundIT.kt
index 912ae97f..0a6a806d 100644
--- a/integration-tests/src/test/kotlin/com/google/devtools/ksp/test/PlaygroundIT.kt
+++ b/integration-tests/src/test/kotlin/com/google/devtools/ksp/test/PlaygroundIT.kt
@@ -97,9 +97,8 @@ class PlaygroundIT {
@Test
fun testBuildCache() {
val gradleRunner = GradleRunner.create().withProjectDir(project.root)
- gradleRunner.buildAndCheck("--build-cache", ":workload:clean", "build") {
- Assert.assertEquals(TaskOutcome.SUCCESS, it.task(":workload:kspKotlin")?.outcome)
- }
+ // The first build can be FROM_CACHE or SUCCESS, and we only care about the second build.
+ gradleRunner.buildAndCheck("--build-cache", ":workload:clean", "build")
gradleRunner.buildAndCheck("--build-cache", ":workload:clean", "build") {
Assert.assertEquals(TaskOutcome.FROM_CACHE, it.task(":workload:kspKotlin")?.outcome)
}