IC: Compute symbols impacted by classpath changes (#5111)
IC: Compute symbols impacted by classpath changes
Incremental compilation has 4 key steps:
1. Compile changed/impacted files
2. Detect symbols that have changed after compiling
3. Detect symbols that are impacted by the changed symbols
4. Based on the changed-or-impacted symbols, identify files that need
to be recompiled. Go back to step 1.
Normally, step 2 and 3 are done together when the changed symbols
and impacted symbols are in the same module.
However, if the changed symbols and impacted symbols are in different
modules (e.g., a `Subclass` in lib1 extends a `Superclass` in lib2),
we currently do not compute symbols in the current module that are
impacted by changes in another module (step 3 above).
This is the case for both the new IC and the old IC.
In this commit, we will compute impacted symbols for the new IC. We can
fix the old IC later if necessary (they can't be fixed together easily).
Test: Added BaseIncrementalCompilationMultiProjectIT.testChangeInterfaceInLib
^KT-56197 Fixed
This commit is contained in:
@@ -34,9 +34,6 @@ import org.jetbrains.kotlin.resolve.sam.SAM_LOOKUP_NAME
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.flattenTo
|
||||
import java.io.File
|
||||
import java.nio.file.Files
|
||||
import java.util.*
|
||||
import kotlin.collections.HashSet
|
||||
import kotlin.collections.LinkedHashSet
|
||||
|
||||
const val DELETE_MODULE_FILE_PROPERTY = "kotlin.delete.module.file.after.build"
|
||||
|
||||
@@ -143,7 +140,34 @@ data class DirtyData(
|
||||
val dirtyClassesFqNamesForceRecompile: Collection<FqName> = emptyList()
|
||||
)
|
||||
|
||||
fun ChangesCollector.getDirtyData(
|
||||
/**
|
||||
* Returns changed symbols from the changes collected by this [ChangesCollector].
|
||||
*
|
||||
* If impacted symbols are also needed, use [getChangedAndImpactedSymbols].
|
||||
*/
|
||||
fun ChangesCollector.getChangedSymbols(reporter: ICReporter): DirtyData {
|
||||
// Caches are used to compute impacted symbols. Set `caches = emptyList()` so that we get changed symbols only, not impacted ones.
|
||||
return changes().getChangedAndImpactedSymbols(caches = emptyList(), reporter)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns changed and impacted symbols from the changes collected by this [ChangesCollector].
|
||||
*
|
||||
* For example, if `Subclass` extends `Superclass` and `Superclass` has changed, `Subclass` will be impacted.
|
||||
*/
|
||||
fun ChangesCollector.getChangedAndImpactedSymbols(
|
||||
caches: Iterable<IncrementalCacheCommon>,
|
||||
reporter: ICReporter
|
||||
): DirtyData {
|
||||
return changes().getChangedAndImpactedSymbols(caches, reporter)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns changed and impacted symbols from this list of changes.
|
||||
*
|
||||
* For example, if `Subclass` extends `Superclass` and `Superclass` has changed, `Subclass` will be impacted.
|
||||
*/
|
||||
fun List<ChangeInfo>.getChangedAndImpactedSymbols(
|
||||
caches: Iterable<IncrementalCacheCommon>,
|
||||
reporter: ICReporter
|
||||
): DirtyData {
|
||||
@@ -152,7 +176,7 @@ fun ChangesCollector.getDirtyData(
|
||||
|
||||
val sealedParents = HashSet<FqName>()
|
||||
|
||||
for (change in changes()) {
|
||||
for (change in this) {
|
||||
reporter.debug { "Process $change" }
|
||||
|
||||
if (change is ChangeInfo.SignatureChanged) {
|
||||
|
||||
Reference in New Issue
Block a user