From ee3119e9d2423595a931301b4fc601eaa7d73937 Mon Sep 17 00:00:00 2001 From: Evgenii Mazhukin Date: Wed, 27 Dec 2023 13:43:54 +0000 Subject: [PATCH] [KGP] Introduce Incremental Compilation Feature Toggles Makes it easier to introduce a Gradle property for configuring IncrementalCompilerRunner. ^KT-64513 Fixed ^KT-63837 In Progress Merge-request: KT-MR-13671 Merged-by: Evgenii Mazhukin --- .../IncrementalCompilationContext.kt | 11 ++-- .../IncrementalCompilationFeatures.kt | 58 +++++++++++++++++++ .../kotlin/incremental/storage/LazyStorage.kt | 4 +- .../storage/InMemoryStorageTest.kt | 5 +- .../internal/CompilationServiceImpl.kt | 5 +- .../internal/configurationAdapters.kt | 25 ++++++++ .../buildtools/internal/daemonAdapters.kt | 4 +- .../daemon/common/CompilationOptions.kt | 8 +-- .../kotlin/daemon/CompileServiceImpl.kt | 8 +-- .../incremental/IncrementalCompilerRunner.kt | 24 ++++---- .../IncrementalJsCompilerRunner.kt | 12 ++-- .../IncrementalJvmCompilerRunner.kt | 12 ++-- .../IncrementalJvmCompilerTestRunner.kt | 4 +- .../GradleKotlinCompilerWork.kt | 6 +- .../IncrementalCompilationEnvironment.kt | 7 +-- .../btapi/BuildToolsApiCompilationWork.kt | 6 +- .../gradle/tasks/AbstractKotlinCompile.kt | 13 ++++- .../kotlin/gradle/tasks/Kotlin2JsCompile.kt | 3 +- .../kotlin/gradle/tasks/KotlinCompile.kt | 12 +++- 19 files changed, 157 insertions(+), 70 deletions(-) create mode 100644 build-common/src/org/jetbrains/kotlin/incremental/IncrementalCompilationFeatures.kt create mode 100644 compiler/build-tools/kotlin-build-tools-impl/src/main/kotlin/org/jetbrains/kotlin/buildtools/internal/configurationAdapters.kt diff --git a/build-common/src/org/jetbrains/kotlin/incremental/IncrementalCompilationContext.kt b/build-common/src/org/jetbrains/kotlin/incremental/IncrementalCompilationContext.kt index f967402017a..a493697957c 100644 --- a/build-common/src/org/jetbrains/kotlin/incremental/IncrementalCompilationContext.kt +++ b/build-common/src/org/jetbrains/kotlin/incremental/IncrementalCompilationContext.kt @@ -23,12 +23,7 @@ class IncrementalCompilationContext( * Controls whether changes in lookup cache should be tracked. Required for the classpath snapshots based IC approach */ val trackChangesInLookupCache: Boolean = false, - /** - * Controls whether any changes should be propagated to FS until we decide that the compilation is successful or not - * - * Required for optimizing Gradle side outputs backup - */ - val keepIncrementalCompilationCachesInMemory: Boolean = false, + val icFeatures: IncrementalCompilationFeatures = IncrementalCompilationFeatures.DEFAULT_CONFIGURATION, ) { @Deprecated("This constructor is scheduled to be removed. KSP is using it") constructor( @@ -45,7 +40,9 @@ class IncrementalCompilationContext( transaction, reporter, trackChangesInLookupCache, - keepIncrementalCompilationCachesInMemory + IncrementalCompilationFeatures.DEFAULT_CONFIGURATION.copy( + keepIncrementalCompilationCachesInMemory = keepIncrementalCompilationCachesInMemory + ), ) val fileDescriptorForSourceFiles: KeyDescriptor = pathConverterForSourceFiles.getFileDescriptor() diff --git a/build-common/src/org/jetbrains/kotlin/incremental/IncrementalCompilationFeatures.kt b/build-common/src/org/jetbrains/kotlin/incremental/IncrementalCompilationFeatures.kt new file mode 100644 index 00000000000..a5059cebd02 --- /dev/null +++ b/build-common/src/org/jetbrains/kotlin/incremental/IncrementalCompilationFeatures.kt @@ -0,0 +1,58 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.incremental + +import java.io.Serializable + +/** + * Lists configurable feature toggles for Incremental Compilation. + * Obsolete features might be removed, so it's not recommended + * to use this outside of Kotlin repository. + * + * It's intended to be used across all build systems and target platforms. + * Then, for example, if we're ready to port a feature from one platform to another, + * we just have to initialize the build system-dependent property, and the value + * would be available at the use site without any additional boilerplate. + * + * To add a new feature toggle, consider this checklist: + * + * 1. Gradle input: see [AbstractKotlinCompile.getIncrementalCompilationFeatures]. + * Platform-agnostic properties should be the default, but you can extend one of the subclasses, if needed. + * If new property might affect the result of compilation, annotate it with @Input. + * 2. Gradle.properties support: declare the property in [org.jetbrains.kotlin.gradle.plugin.PropertiesProvider]. + * Add its use in [org.jetbrains.kotlin.gradle.tasks.configuration.AbstractKotlinCompileConfig] or one of its subclasses (see step 1). + * 3. Build Tools Api, KGP to Interface part: see [BuildToolsApiCompilationWork.performCompilation] + * You need to update both the interface [IncrementalJvmCompilationConfiguration] and its implementation(s). + * 4. Build Tools Api, Interface to Implementation part: see [ICConfiguration.extractIncrementalCompilationFeatures] and its uses. + * Most likely you just need to update the `extract` method. + * 5. Maven - TODO(emazhukin) will do and describe in KT-63837 + * 6. Gradle Integration Tests - add new option to [org.jetbrains.kotlin.gradle.testbase.BuildOptions] + */ +data class IncrementalCompilationFeatures( + /** + * Snapshot-based cross-module IC if true, BuildHistory-based if false. + * Snapshot-based IC is only available in JVM. + */ + val withAbiSnapshot: Boolean = false, + /** + * Enables [RecoverableCompilationTransaction] for better restoration of build outputs + * in case of a build error. + */ + val preciseCompilationResultsBackup: Boolean = false, + /** + * If enabled, IC caches are flushed to FS only when the compilation is successful. + * Optimizes outputs backup on Gradle side. + * Requires [preciseCompilationResultsBackup] + */ + val keepIncrementalCompilationCachesInMemory: Boolean = false, +) : Serializable { + + companion object { + val DEFAULT_CONFIGURATION = IncrementalCompilationFeatures() + + const val serialVersionUID: Long = 0 + } +} \ No newline at end of file diff --git a/build-common/src/org/jetbrains/kotlin/incremental/storage/LazyStorage.kt b/build-common/src/org/jetbrains/kotlin/incremental/storage/LazyStorage.kt index 9a55f371762..7b7c2055b94 100644 --- a/build-common/src/org/jetbrains/kotlin/incremental/storage/LazyStorage.kt +++ b/build-common/src/org/jetbrains/kotlin/incremental/storage/LazyStorage.kt @@ -153,7 +153,7 @@ fun createPersistentStorage( icContext: IncrementalCompilationContext, ): PersistentStorage { return LazyStorage(storageFile, keyDescriptor, valueExternalizer).let { storage -> - if (icContext.keepIncrementalCompilationCachesInMemory) { + if (icContext.icFeatures.keepIncrementalCompilationCachesInMemory) { InMemoryStorage(storage).also { icContext.transaction.registerInMemoryStorageWrapper(it) } @@ -170,7 +170,7 @@ fun createAppendablePersistentStorage( icContext: IncrementalCompilationContext, ): AppendablePersistentStorage { return AppendableLazyStorage(storageFile, keyDescriptor, elementExternalizer).let { storage -> - if (icContext.keepIncrementalCompilationCachesInMemory) { + if (icContext.icFeatures.keepIncrementalCompilationCachesInMemory) { AppendableInMemoryStorage(storage).also { icContext.transaction.registerInMemoryStorageWrapper(it) } diff --git a/build-common/test/org/jetbrains/kotlin/incremental/storage/InMemoryStorageTest.kt b/build-common/test/org/jetbrains/kotlin/incremental/storage/InMemoryStorageTest.kt index b87c577b90d..635d050f1f7 100644 --- a/build-common/test/org/jetbrains/kotlin/incremental/storage/InMemoryStorageTest.kt +++ b/build-common/test/org/jetbrains/kotlin/incremental/storage/InMemoryStorageTest.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.incremental.storage import org.jetbrains.kotlin.incremental.IncrementalCompilationContext +import org.jetbrains.kotlin.incremental.IncrementalCompilationFeatures import org.jetbrains.kotlin.incremental.runWithin import org.jetbrains.kotlin.incremental.testingUtils.assertEqualDirectories import org.junit.jupiter.api.Assertions.* @@ -126,7 +127,9 @@ class InMemoryStorageTest { val fileToPathConverter = RelativeFileToPathConverter(storageFile) val icContext = IncrementalCompilationContext( pathConverterForSourceFiles = fileToPathConverter, - keepIncrementalCompilationCachesInMemory = useInMemoryWrapper + icFeatures = IncrementalCompilationFeatures( + keepIncrementalCompilationCachesInMemory = useInMemoryWrapper, + ), ) icContext.transaction.runWithin { transaction -> val lookupMap = LookupMap(storageFile, icContext) diff --git a/compiler/build-tools/kotlin-build-tools-impl/src/main/kotlin/org/jetbrains/kotlin/buildtools/internal/CompilationServiceImpl.kt b/compiler/build-tools/kotlin-build-tools-impl/src/main/kotlin/org/jetbrains/kotlin/buildtools/internal/CompilationServiceImpl.kt index 90b720d79f8..9d390303e1c 100644 --- a/compiler/build-tools/kotlin-build-tools-impl/src/main/kotlin/org/jetbrains/kotlin/buildtools/internal/CompilationServiceImpl.kt +++ b/compiler/build-tools/kotlin-build-tools-impl/src/main/kotlin/org/jetbrains/kotlin/buildtools/internal/CompilationServiceImpl.kt @@ -29,6 +29,7 @@ import org.jetbrains.kotlin.daemon.client.BasicCompilerServicesWithResultsFacade import org.jetbrains.kotlin.daemon.common.CompilerId import org.jetbrains.kotlin.daemon.common.configureDaemonJVMOptions import org.jetbrains.kotlin.daemon.common.filterExtractProps +import org.jetbrains.kotlin.incremental.IncrementalCompilationFeatures import org.jetbrains.kotlin.incremental.IncrementalJvmCompilerRunner import org.jetbrains.kotlin.incremental.classpathDiff.ClasspathEntrySnapshotter import org.jetbrains.kotlin.incremental.extractKotlinSourcesFromFreeCompilerArguments @@ -153,9 +154,7 @@ internal object CompilationServiceImpl : CompilationService { outputDirs = options.outputDirs, kotlinSourceFilesExtensions = kotlinFilenameExtensions, classpathChanges = classpathChanges, - withAbiSnapshot = false, - preciseCompilationResultsBackup = options.preciseCompilationResultsBackupEnabled, - keepIncrementalCompilationCachesInMemory = options.incrementalCompilationCachesKeptInMemory + icFeatures = options.extractIncrementalCompilationFeatures(), ) val rootProjectDir = options.rootProjectDir val buildDir = options.buildDir diff --git a/compiler/build-tools/kotlin-build-tools-impl/src/main/kotlin/org/jetbrains/kotlin/buildtools/internal/configurationAdapters.kt b/compiler/build-tools/kotlin-build-tools-impl/src/main/kotlin/org/jetbrains/kotlin/buildtools/internal/configurationAdapters.kt new file mode 100644 index 00000000000..910aa9f36eb --- /dev/null +++ b/compiler/build-tools/kotlin-build-tools-impl/src/main/kotlin/org/jetbrains/kotlin/buildtools/internal/configurationAdapters.kt @@ -0,0 +1,25 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.buildtools.internal + +import org.jetbrains.kotlin.buildtools.api.jvm.IncrementalJvmCompilationConfiguration +import org.jetbrains.kotlin.incremental.IncrementalCompilationFeatures + +private typealias ICConfiguration = IncrementalJvmCompilationConfiguration<*> + +/** + * IncrementalJvmCompilationConfiguration provides single-property API for forward-compatibility. + * + * configurationAdapters are there to regroup the properties and work with higher-level interfaces. + */ + +internal fun ICConfiguration.extractIncrementalCompilationFeatures(): IncrementalCompilationFeatures { + return IncrementalCompilationFeatures( + withAbiSnapshot = false, + preciseCompilationResultsBackup = preciseCompilationResultsBackupEnabled, + keepIncrementalCompilationCachesInMemory = incrementalCompilationCachesKeptInMemory, + ) +} diff --git a/compiler/build-tools/kotlin-build-tools-impl/src/main/kotlin/org/jetbrains/kotlin/buildtools/internal/daemonAdapters.kt b/compiler/build-tools/kotlin-build-tools-impl/src/main/kotlin/org/jetbrains/kotlin/buildtools/internal/daemonAdapters.kt index a58a288dfa7..acb53d49a0d 100644 --- a/compiler/build-tools/kotlin-build-tools-impl/src/main/kotlin/org/jetbrains/kotlin/buildtools/internal/daemonAdapters.kt +++ b/compiler/build-tools/kotlin-build-tools-impl/src/main/kotlin/org/jetbrains/kotlin/buildtools/internal/daemonAdapters.kt @@ -53,9 +53,7 @@ internal val JvmCompilationConfigurationImpl.asDaemonCompilationOptions: Compila rootProjectDir = options.rootProjectDir, buildDir = options.buildDir, kotlinScriptExtensions = ktsExtensionsAsArray, - withAbiSnapshot = false, - preciseCompilationResultsBackup = options.preciseCompilationResultsBackupEnabled, - keepIncrementalCompilationCachesInMemory = options.incrementalCompilationCachesKeptInMemory, + icFeatures = options.extractIncrementalCompilationFeatures(), ) } else -> CompilationOptions( diff --git a/compiler/daemon/daemon-common/src/org/jetbrains/kotlin/daemon/common/CompilationOptions.kt b/compiler/daemon/daemon-common/src/org/jetbrains/kotlin/daemon/common/CompilationOptions.kt index cbc830835e9..43bcc6f665f 100644 --- a/compiler/daemon/daemon-common/src/org/jetbrains/kotlin/daemon/common/CompilationOptions.kt +++ b/compiler/daemon/daemon-common/src/org/jetbrains/kotlin/daemon/common/CompilationOptions.kt @@ -17,6 +17,7 @@ package org.jetbrains.kotlin.daemon.common import org.jetbrains.kotlin.incremental.ClasspathChanges +import org.jetbrains.kotlin.incremental.IncrementalCompilationFeatures import org.jetbrains.kotlin.incremental.IncrementalModuleInfo import java.io.File import java.io.Serializable @@ -76,9 +77,7 @@ class IncrementalCompilationOptions( val buildDir: File?, kotlinScriptExtensions: Array? = null, - val withAbiSnapshot: Boolean = false, - val preciseCompilationResultsBackup: Boolean = false, - val keepIncrementalCompilationCachesInMemory: Boolean = false, + val icFeatures: IncrementalCompilationFeatures = IncrementalCompilationFeatures.DEFAULT_CONFIGURATION, ) : CompilationOptions( compilerMode, targetPlatform, @@ -88,7 +87,7 @@ class IncrementalCompilationOptions( kotlinScriptExtensions ) { companion object { - const val serialVersionUID: Long = 3 + const val serialVersionUID: Long = 4 } override fun toString(): String { @@ -101,6 +100,7 @@ class IncrementalCompilationOptions( "workingDir=$workingDir, " + "multiModuleICSettings=$multiModuleICSettings, " + "usePreciseJavaTracking=$usePreciseJavaTracking, " + + "icFeatures=$icFeatures, " + "outputFiles=$outputFiles" + ")" } diff --git a/compiler/daemon/src/org/jetbrains/kotlin/daemon/CompileServiceImpl.kt b/compiler/daemon/src/org/jetbrains/kotlin/daemon/CompileServiceImpl.kt index c7877236afd..f47495d560f 100644 --- a/compiler/daemon/src/org/jetbrains/kotlin/daemon/CompileServiceImpl.kt +++ b/compiler/daemon/src/org/jetbrains/kotlin/daemon/CompileServiceImpl.kt @@ -614,9 +614,7 @@ abstract class CompileServiceImplBase( buildHistoryFile = incrementalCompilationOptions.multiModuleICSettings?.buildHistoryFile, scopeExpansion = if (args.isIrBackendEnabled()) CompileScopeExpansionMode.ALWAYS else CompileScopeExpansionMode.NEVER, modulesApiHistory = modulesApiHistory, - withAbiSnapshot = incrementalCompilationOptions.withAbiSnapshot, - preciseCompilationResultsBackup = incrementalCompilationOptions.preciseCompilationResultsBackup, - keepIncrementalCompilationCachesInMemory = incrementalCompilationOptions.keepIncrementalCompilationCachesInMemory, + icFeatures = incrementalCompilationOptions.icFeatures, ) return try { compiler.compile(allKotlinFiles, args, compilerMessageCollector, changedFiles) @@ -683,9 +681,7 @@ abstract class CompileServiceImplBase( modulesApiHistory = modulesApiHistory, kotlinSourceFilesExtensions = allKotlinExtensions, classpathChanges = incrementalCompilationOptions.classpathChanges, - withAbiSnapshot = incrementalCompilationOptions.withAbiSnapshot, - preciseCompilationResultsBackup = incrementalCompilationOptions.preciseCompilationResultsBackup, - keepIncrementalCompilationCachesInMemory = incrementalCompilationOptions.keepIncrementalCompilationCachesInMemory, + icFeatures = incrementalCompilationOptions.icFeatures, ) return try { compiler.compile( diff --git a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalCompilerRunner.kt b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalCompilerRunner.kt index ac82e630b87..b18e9c4f155 100644 --- a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalCompilerRunner.kt +++ b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalCompilerRunner.kt @@ -72,9 +72,11 @@ abstract class IncrementalCompilerRunner< */ private val outputDirs: Collection?, - protected val withAbiSnapshot: Boolean = false, - private val preciseCompilationResultsBackup: Boolean = false, - private val keepIncrementalCompilationCachesInMemory: Boolean = false, + /** + * Various options. Boolean flags, both stable and experimental, should be added there. + * Non-trivial configuration should NOT be added there. + */ + protected val icFeatures: IncrementalCompilationFeatures, ) { protected val cacheDirectory = File(workingDir, cacheDirName) @@ -96,7 +98,7 @@ abstract class IncrementalCompilerRunner< reporter = reporter, trackChangesInLookupCache = shouldTrackChangesInLookupCache, storeFullFqNamesInLookupCache = shouldStoreFullFqNamesInLookupCache, - keepIncrementalCompilationCachesInMemory = keepIncrementalCompilationCachesInMemory, + icFeatures = icFeatures, ) protected abstract val shouldTrackChangesInLookupCache: Boolean @@ -201,7 +203,7 @@ abstract class IncrementalCompilerRunner< return ICResult.Failed(IC_FAILED_TO_GET_CHANGED_FILES, e) } - val classpathAbiSnapshot = if (withAbiSnapshot) getClasspathAbiSnapshot(args) else null + val classpathAbiSnapshot = if (icFeatures.withAbiSnapshot) getClasspathAbiSnapshot(args) else null // Step 2: Compute files to recompile val compilationMode = try { @@ -216,7 +218,7 @@ abstract class IncrementalCompilerRunner< return ICResult.RequiresRebuild(compilationMode.reason) } - val abiSnapshotData = if (withAbiSnapshot) { + val abiSnapshotData = if (icFeatures.withAbiSnapshot) { if (!abiSnapshotFile.exists()) { reporter.debug { "Jar snapshot file does not exist: ${abiSnapshotFile.path}" } return ICResult.RequiresRebuild(NO_ABI_SNAPSHOT) @@ -276,7 +278,7 @@ abstract class IncrementalCompilerRunner< if (trackChangedFiles) { caches.inputsCache.sourceSnapshotMap.compareAndUpdate(allSourceFiles) } - val abiSnapshotData = if (withAbiSnapshot) { + val abiSnapshotData = if (icFeatures.withAbiSnapshot) { AbiSnapshotData(snapshot = AbiSnapshotImpl(mutableMapOf()), classpathAbiSnapshot = getClasspathAbiSnapshot(args)) } else null @@ -405,7 +407,7 @@ abstract class IncrementalCompilerRunner< return exitCode } - private fun createTransaction() = if (preciseCompilationResultsBackup) { + private fun createTransaction() = if (icFeatures.preciseCompilationResultsBackup) { RecoverableCompilationTransaction(reporter, Files.createTempDirectory("kotlin-backups")) } else { NonRecoverableCompilationTransaction() @@ -519,7 +521,7 @@ abstract class IncrementalCompilerRunner< updateCaches(services, caches, generatedFiles, changesCollector) } if (compilationMode is CompilationMode.Rebuild) { - if (withAbiSnapshot) { + if (icFeatures.withAbiSnapshot) { abiSnapshotData!!.snapshot.protos.putAll(changesCollector.protoDataChanges()) } break @@ -552,7 +554,7 @@ abstract class IncrementalCompilerRunner< buildDirtyFqNames.addAll(dirtyClassFqNames) //update - if (withAbiSnapshot) { + if (icFeatures.withAbiSnapshot) { //TODO(valtman) check method/ kts class remove changesCollector.protoDataRemoved().forEach { abiSnapshotData!!.snapshot.protos.remove(it) } abiSnapshotData!!.snapshot.protos.putAll(changesCollector.protoDataChanges()) @@ -564,7 +566,7 @@ abstract class IncrementalCompilerRunner< BuildInfo.write(icContext, currentBuildInfo, lastBuildInfoFile) //write abi snapshot - if (withAbiSnapshot) { + if (icFeatures.withAbiSnapshot) { //TODO(valtman) check method/class remove AbiSnapshotImpl.write(icContext, abiSnapshotData!!.snapshot, abiSnapshotFile) } diff --git a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJsCompilerRunner.kt b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJsCompilerRunner.kt index 81120d88e56..8a343fb6b07 100644 --- a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJsCompilerRunner.kt +++ b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJsCompilerRunner.kt @@ -89,24 +89,20 @@ class IncrementalJsCompilerRunner( buildHistoryFile: File?, private val modulesApiHistory: ModulesApiHistory, private val scopeExpansion: CompileScopeExpansionMode = CompileScopeExpansionMode.NEVER, - withAbiSnapshot: Boolean = false, - preciseCompilationResultsBackup: Boolean = false, - keepIncrementalCompilationCachesInMemory: Boolean = false, + icFeatures: IncrementalCompilationFeatures = IncrementalCompilationFeatures.DEFAULT_CONFIGURATION, ) : IncrementalCompilerRunner( workingDir, "caches-js", reporter, buildHistoryFile = buildHistoryFile, outputDirs = null, - withAbiSnapshot = withAbiSnapshot, - preciseCompilationResultsBackup = preciseCompilationResultsBackup, - keepIncrementalCompilationCachesInMemory = keepIncrementalCompilationCachesInMemory, + icFeatures = icFeatures, ) { override val shouldTrackChangesInLookupCache get() = false override val shouldStoreFullFqNamesInLookupCache - get() = withAbiSnapshot + get() = icFeatures.withAbiSnapshot override fun createCacheManager(icContext: IncrementalCompilationContext, args: K2JSCompilerArguments) = IncrementalJsCachesManager(icContext, if (!args.isIrBackendEnabled()) JsSerializerProtocol else KlibMetadataSerializerProtocol, cacheDirectory) @@ -128,7 +124,7 @@ class IncrementalJsCompilerRunner( if (buildHistoryFile == null) { error("The build is configured to use the build-history based IC approach, but doesn't specify the buildHistoryFile") } - if (!withAbiSnapshot && !buildHistoryFile.isFile) { + if (!icFeatures.withAbiSnapshot && !buildHistoryFile.isFile) { return CompilationMode.Rebuild(BuildAttribute.NO_BUILD_HISTORY) } val lastBuildInfo = BuildInfo.read(lastBuildInfoFile, messageCollector) ?: return CompilationMode.Rebuild(BuildAttribute.INVALID_LAST_BUILD_INFO) diff --git a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJvmCompilerRunner.kt b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJvmCompilerRunner.kt index afd32d8c683..6f2acd73212 100644 --- a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJvmCompilerRunner.kt +++ b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJvmCompilerRunner.kt @@ -68,24 +68,20 @@ open class IncrementalJvmCompilerRunner( private val modulesApiHistory: ModulesApiHistory, override val kotlinSourceFilesExtensions: Set = DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS, private val classpathChanges: ClasspathChanges, - withAbiSnapshot: Boolean = false, - preciseCompilationResultsBackup: Boolean = false, - keepIncrementalCompilationCachesInMemory: Boolean = false, + icFeatures: IncrementalCompilationFeatures = IncrementalCompilationFeatures.DEFAULT_CONFIGURATION, ) : IncrementalCompilerRunner( workingDir, "caches-jvm", reporter, buildHistoryFile = buildHistoryFile, outputDirs = outputDirs, - withAbiSnapshot = withAbiSnapshot, - preciseCompilationResultsBackup = preciseCompilationResultsBackup, - keepIncrementalCompilationCachesInMemory = keepIncrementalCompilationCachesInMemory, + icFeatures = icFeatures, ) { override val shouldTrackChangesInLookupCache get() = classpathChanges is ClasspathChanges.ClasspathSnapshotEnabled.IncrementalRun override val shouldStoreFullFqNamesInLookupCache - get() = withAbiSnapshot || classpathChanges is ClasspathChanges.ClasspathSnapshotEnabled + get() = icFeatures.withAbiSnapshot || classpathChanges is ClasspathChanges.ClasspathSnapshotEnabled override fun createCacheManager(icContext: IncrementalCompilationContext, args: K2JVMCompilerArguments) = IncrementalJvmCachesManager(icContext, args.destination?.let { File(it) }, cacheDirectory) @@ -133,7 +129,7 @@ open class IncrementalJvmCompilerRunner( classpathAbiSnapshots: Map ): CompilationMode { return try { - calculateSourcesToCompileImpl(caches, changedFiles, args, messageCollector, classpathAbiSnapshots, withAbiSnapshot) + calculateSourcesToCompileImpl(caches, changedFiles, args, messageCollector, classpathAbiSnapshots, icFeatures.withAbiSnapshot) } finally { this.messageCollector.flush(messageCollector) this.messageCollector.clear() diff --git a/compiler/incremental-compilation-impl/test/org/jetbrains/kotlin/incremental/IncrementalJvmCompilerTestRunner.kt b/compiler/incremental-compilation-impl/test/org/jetbrains/kotlin/incremental/IncrementalJvmCompilerTestRunner.kt index bbba3092f0a..1fe2949eef4 100644 --- a/compiler/incremental-compilation-impl/test/org/jetbrains/kotlin/incremental/IncrementalJvmCompilerTestRunner.kt +++ b/compiler/incremental-compilation-impl/test/org/jetbrains/kotlin/incremental/IncrementalJvmCompilerTestRunner.kt @@ -32,7 +32,9 @@ class IncrementalJvmCompilerTestRunner( modulesApiHistory, kotlinSourceFilesExtensions, classpathChanges, - withAbiSnapshot + icFeatures = IncrementalCompilationFeatures( + withAbiSnapshot = withAbiSnapshot + ), ) { override fun createCacheManager(icContext: IncrementalCompilationContext, args: K2JVMCompilerArguments): IncrementalJvmCachesManager = object : IncrementalJvmCachesManager( diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerWork.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerWork.kt index b2cffc5e6c2..f1dd4b8d3dc 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerWork.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerWork.kt @@ -132,7 +132,7 @@ internal class GradleKotlinCompilerWork @Inject constructor( private fun collectStatTags(): Set { val statTags = HashSet() - config.incrementalCompilationEnvironment?.withAbiSnapshot?.ifTrue { statTags.add(StatTag.ABI_SNAPSHOT) } + config.incrementalCompilationEnvironment?.icFeatures?.withAbiSnapshot?.ifTrue { statTags.add(StatTag.ABI_SNAPSHOT) } if (config.incrementalCompilationEnvironment?.classpathChanges is ClasspathChanges.ClasspathSnapshotEnabled) { statTags.add(StatTag.ARTIFACT_TRANSFORM) } @@ -320,9 +320,7 @@ internal class GradleKotlinCompilerWork @Inject constructor( rootProjectDir = icEnv.rootProjectDir, buildDir = icEnv.buildDir, kotlinScriptExtensions = config.kotlinScriptExtensions, - withAbiSnapshot = icEnv.withAbiSnapshot, - preciseCompilationResultsBackup = icEnv.preciseCompilationResultsBackup, - keepIncrementalCompilationCachesInMemory = icEnv.keepIncrementalCompilationCachesInMemory + icFeatures = icEnv.icFeatures, ) log.info("Options for KOTLIN DAEMON: $compilationOptions") diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/IncrementalCompilationEnvironment.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/IncrementalCompilationEnvironment.kt index 21234340733..ef633e90691 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/IncrementalCompilationEnvironment.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/IncrementalCompilationEnvironment.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.compilerRunner import org.jetbrains.kotlin.buildtools.api.SourcesChanges import org.jetbrains.kotlin.daemon.common.MultiModuleICSettings import org.jetbrains.kotlin.incremental.ClasspathChanges +import org.jetbrains.kotlin.incremental.IncrementalCompilationFeatures import java.io.File import java.io.Serializable @@ -20,11 +21,9 @@ internal class IncrementalCompilationEnvironment( val usePreciseJavaTracking: Boolean = false, val disableMultiModuleIC: Boolean = false, val multiModuleICSettings: MultiModuleICSettings, - val withAbiSnapshot: Boolean = false, - val preciseCompilationResultsBackup: Boolean = false, - val keepIncrementalCompilationCachesInMemory: Boolean = false, + val icFeatures: IncrementalCompilationFeatures = IncrementalCompilationFeatures.DEFAULT_CONFIGURATION, ) : Serializable { companion object { - const val serialVersionUID: Long = 3 + const val serialVersionUID: Long = 4 } } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/btapi/BuildToolsApiCompilationWork.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/btapi/BuildToolsApiCompilationWork.kt index da72ab93063..9d155e5dae2 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/btapi/BuildToolsApiCompilationWork.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/btapi/BuildToolsApiCompilationWork.kt @@ -86,12 +86,14 @@ internal abstract class BuildToolsApiCompilationWork @Inject constructor( val icEnv = workArguments.incrementalCompilationEnvironment val classpathChanges = icEnv?.classpathChanges if (classpathChanges is ClasspathChanges.ClasspathSnapshotEnabled) { + // important detail: by using primitive-type single-field setters, + // we maintain compatibility of this KGP code with future BuildToolsApi implementations val classpathSnapshotsConfig = jvmCompilationConfig.makeClasspathSnapshotBasedIncrementalCompilationConfiguration() .setRootProjectDir(icEnv.rootProjectDir) .setBuildDir(icEnv.buildDir) .usePreciseJavaTracking(icEnv.usePreciseJavaTracking) - .usePreciseCompilationResultsBackup(icEnv.preciseCompilationResultsBackup) - .keepIncrementalCompilationCachesInMemory(icEnv.keepIncrementalCompilationCachesInMemory) + .usePreciseCompilationResultsBackup(icEnv.icFeatures.preciseCompilationResultsBackup) + .keepIncrementalCompilationCachesInMemory(icEnv.icFeatures.keepIncrementalCompilationCachesInMemory) .useOutputDirs(workArguments.outputFiles) .forceNonIncrementalMode(classpathChanges !is ClasspathChanges.ClasspathSnapshotEnabled.IncrementalRun) val classpathSnapshotsParameters = ClasspathSnapshotBasedIncrementalCompilationApproachParameters( diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/AbstractKotlinCompile.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/AbstractKotlinCompile.kt index 81120280783..641a3867c5e 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/AbstractKotlinCompile.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/AbstractKotlinCompile.kt @@ -6,7 +6,6 @@ package org.jetbrains.kotlin.gradle.tasks import org.gradle.api.file.* -import org.gradle.api.logging.Logging import org.gradle.api.model.ObjectFactory import org.gradle.api.provider.Property import org.gradle.api.provider.Provider @@ -38,6 +37,7 @@ import org.jetbrains.kotlin.gradle.plugin.internal.UsesBuildIdProviderService import org.jetbrains.kotlin.gradle.plugin.statistics.UsesBuildFusService import org.jetbrains.kotlin.gradle.report.* import org.jetbrains.kotlin.gradle.utils.* +import org.jetbrains.kotlin.incremental.IncrementalCompilationFeatures import org.jetbrains.kotlin.statistics.metrics.BooleanMetrics import org.jetbrains.kotlin.statistics.metrics.StringMetrics import java.io.File @@ -294,6 +294,17 @@ abstract class AbstractKotlinCompile @Inject constr commonSourceSet ) + /** + * Entry point for getting IC feature toggles in Gradle. Child classes should override it + * if they have a platform-specific Input. + */ + protected open fun makeIncrementalCompilationFeatures(): IncrementalCompilationFeatures { + return IncrementalCompilationFeatures( + preciseCompilationResultsBackup = preciseCompilationResultsBackup.get(), + keepIncrementalCompilationCachesInMemory = keepIncrementalCompilationCachesInMemory.get(), + ) + } + private fun executeImpl( inputChanges: InputChanges, taskOutputsBackup: TaskOutputsBackup? diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/Kotlin2JsCompile.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/Kotlin2JsCompile.kt index 715c7fdb393..64ef861414e 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/Kotlin2JsCompile.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/Kotlin2JsCompile.kt @@ -267,8 +267,7 @@ abstract class Kotlin2JsCompile @Inject constructor( rootProjectDir = rootProjectDir, buildDir = projectLayout.buildDirectory.getFile(), multiModuleICSettings = multiModuleICSettings, - preciseCompilationResultsBackup = preciseCompilationResultsBackup.get(), - keepIncrementalCompilationCachesInMemory = keepIncrementalCompilationCachesInMemory.get(), + icFeatures = makeIncrementalCompilationFeatures(), ) } else null diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/KotlinCompile.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/KotlinCompile.kt index f2630d60f5b..69e7bc6807f 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/KotlinCompile.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/KotlinCompile.kt @@ -48,6 +48,7 @@ import org.jetbrains.kotlin.incremental.ClasspathChanges.ClasspathSnapshotEnable import org.jetbrains.kotlin.incremental.ClasspathChanges.ClasspathSnapshotEnabled.NotAvailableDueToMissingClasspathSnapshot import org.jetbrains.kotlin.incremental.ClasspathChanges.ClasspathSnapshotEnabled.NotAvailableForNonIncrementalRun import org.jetbrains.kotlin.incremental.ClasspathSnapshotFiles +import org.jetbrains.kotlin.incremental.IncrementalCompilationFeatures import org.jetbrains.kotlin.utils.addToStdlib.cast import javax.inject.Inject @@ -326,9 +327,7 @@ abstract class KotlinCompile @Inject constructor( usePreciseJavaTracking = usePreciseJavaTracking, disableMultiModuleIC = disableMultiModuleIC, multiModuleICSettings = multiModuleICSettings, - withAbiSnapshot = useKotlinAbiSnapshot.get(), - preciseCompilationResultsBackup = preciseCompilationResultsBackup.get(), - keepIncrementalCompilationCachesInMemory = keepIncrementalCompilationCachesInMemory.get(), + icFeatures = makeIncrementalCompilationFeatures(), ) } else null @@ -466,6 +465,13 @@ abstract class KotlinCompile @Inject constructor( super.setSource(*sources) } + // override incremental compilation features, while withAbiSnapshot is JVM-only + override fun makeIncrementalCompilationFeatures(): IncrementalCompilationFeatures { + return super.makeIncrementalCompilationFeatures().copy( + withAbiSnapshot = useKotlinAbiSnapshot.get(), + ) + } + private fun getClasspathChanges(inputChanges: InputChanges): ClasspathChanges = when { !classpathSnapshotProperties.useClasspathSnapshot.get() -> ClasspathSnapshotDisabled else -> {