[IC] Baseline fix for common sources getting access to platform declarations
K2-only issue. In an incremental build, sourceSet boundary isn't preserved in certain conditions: SourceSet A depends on SourceSet B A and B overload a function, for example: A -> fun foo(p: Parent) // (1) B -> fun foo(c: Child) // (2) If some source file in A is calling foo(..), only (1) is supposed to be visible for that call site. However, if a) it is an incremental build, b) the declaration of (1) is not a part of the compilation set, and c) call to foo(c: Child) is applicable, then (2) would be called from the generated code. So, the build result is not consistent between the full build and an incremental build. As a workaround, we fallback to a non-incremental build, if any source from A needs to be compiled. To enable "risky" incremental builds, use Gradle property kotlin.internal.incremental.enableUnsafeOptimizationsForMultiplatform=true ^KT-62686 ^KT-63837 Fixed Merge-request: KT-MR-13695 Merged-by: Evgenii Mazhukin <evgenii.mazhukin@jetbrains.com>
This commit is contained in:
committed by
Space Team
parent
ad6513e247
commit
de4953adf6
+26
-5
@@ -91,6 +91,7 @@ abstract class IncrementalCompilerRunner<
|
||||
private fun createIncrementalCompilationContext(
|
||||
fileLocations: FileLocations?,
|
||||
transaction: CompilationTransaction,
|
||||
fragmentContext: FragmentContext? = null,
|
||||
) = IncrementalCompilationContext(
|
||||
pathConverterForSourceFiles = fileLocations?.let { it.getRelocatablePathConverterForSourceFiles() } ?: BasicFileToPathConverter,
|
||||
pathConverterForOutputFiles = fileLocations?.let { it.getRelocatablePathConverterForOutputFiles() } ?: BasicFileToPathConverter,
|
||||
@@ -99,6 +100,7 @@ abstract class IncrementalCompilerRunner<
|
||||
trackChangesInLookupCache = shouldTrackChangesInLookupCache,
|
||||
storeFullFqNamesInLookupCache = shouldStoreFullFqNamesInLookupCache,
|
||||
icFeatures = icFeatures,
|
||||
fragmentContext = fragmentContext,
|
||||
)
|
||||
|
||||
protected abstract val shouldTrackChangesInLookupCache: Boolean
|
||||
@@ -165,6 +167,9 @@ abstract class IncrementalCompilerRunner<
|
||||
class Failed(val reason: BuildAttribute, val cause: Throwable) : ICResult
|
||||
}
|
||||
|
||||
// Be aware that [tryCompileIncrementally] catches a lot of exceptions internally.
|
||||
// So this transformer should be used for very specific things, like cache closing, that are
|
||||
// related to the transaction as a whole rather than any compilation step.
|
||||
private fun incrementalCompilationExceptionTransformer(t: Throwable): ICResult = when (t) {
|
||||
is CachesManagerCloseException -> ICResult.Failed(IC_FAILED_TO_CLOSE_CACHES, t)
|
||||
else -> throw t
|
||||
@@ -186,10 +191,19 @@ abstract class IncrementalCompilerRunner<
|
||||
if (changedFiles is ChangedFiles.Unknown) {
|
||||
return ICResult.RequiresRebuild(UNKNOWN_CHANGES_IN_GRADLE_INPUTS)
|
||||
}
|
||||
changedFiles as ChangedFiles.Known?
|
||||
|
||||
val fragmentContext = if (!icFeatures.enableUnsafeIncrementalCompilationForMultiplatform) { //see KT-62686
|
||||
FragmentContext.fromCompilerArguments(args)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
return createTransaction().runWithin(::incrementalCompilationExceptionTransformer) { transaction ->
|
||||
val icContext = createIncrementalCompilationContext(fileLocations, transaction)
|
||||
val icContext = createIncrementalCompilationContext(
|
||||
fileLocations,
|
||||
transaction,
|
||||
fragmentContext
|
||||
)
|
||||
val caches = createCacheManager(icContext, args).also {
|
||||
// this way we make the transaction to be responsible for closing the caches manager
|
||||
transaction.cachesManager = it
|
||||
@@ -198,7 +212,7 @@ abstract class IncrementalCompilerRunner<
|
||||
fun compile(): ICResult {
|
||||
// Step 1: Get changed files
|
||||
val knownChangedFiles: ChangedFiles.Known = try {
|
||||
getChangedFiles(changedFiles, allSourceFiles, caches)
|
||||
getChangedFiles(changedFiles as ChangedFiles.Known?, allSourceFiles, caches)
|
||||
} catch (e: Throwable) {
|
||||
return ICResult.Failed(IC_FAILED_TO_GET_CHANGED_FILES, e)
|
||||
}
|
||||
@@ -241,6 +255,8 @@ abstract class IncrementalCompilerRunner<
|
||||
abiSnapshotData,
|
||||
messageCollector,
|
||||
)
|
||||
} catch (e: RequireRebuildForCorrectnessInKMPException) {
|
||||
return ICResult.RequiresRebuild(UNSAFE_INCREMENTAL_CHANGE_KT_62686)
|
||||
} catch (e: Throwable) {
|
||||
return ICResult.Failed(IC_FAILED_TO_COMPILE_INCREMENTALLY, e)
|
||||
}
|
||||
@@ -463,9 +479,14 @@ abstract class IncrementalCompilerRunner<
|
||||
|
||||
val lookupTracker = LookupTrackerImpl(getLookupTrackerDelegate())
|
||||
val expectActualTracker = ExpectActualTrackerImpl()
|
||||
//TODO(valtman) sourceToCompile calculate based on abiSnapshot
|
||||
val (sourcesToCompile, removedKotlinSources) = dirtySources.partition { it.exists() && allKotlinSources.contains(it) }
|
||||
|
||||
icContext.fragmentContext?.let {
|
||||
if (it.dirtySetTouchesNonLeafFragments(sourcesToCompile)) {
|
||||
throw RequireRebuildForCorrectnessInKMPException()
|
||||
}
|
||||
}
|
||||
|
||||
val services = makeServices(
|
||||
args, lookupTracker, expectActualTracker, caches,
|
||||
dirtySources.toSet(), compilationMode is CompilationMode.Incremental
|
||||
@@ -686,4 +707,4 @@ fun extractKotlinSourcesFromFreeCompilerArguments(
|
||||
}
|
||||
compilerArguments.freeArgs = freeArgs
|
||||
return allKotlinFiles
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user