[LL API] Replace whole-session invalidation with granular FIR guards

^KT-59297 Fixed

'ProcessCancelledException's are commonly thrown during code analysis,
yet not every place is ready for them. As a FIR tree is a mutable data
structure with no transaction support, sporadic halts during its
mutation might easily leave it in an inconsistent state.

Before this change, whole module sessions (with all dependents) were
invalidated if an exception occurred during their analysis. Not only it
was very ineffective, it also resulted into a concurrency problem.

'ProcessCancelledException's are thrown when an underlying progress
indicator is invalidated. As analysis in each thread might have its own
progress indicator, invalidation in one thread should not stop
analysis in others. However, it is impossible in the current state,
as all threads share the same FIR tree structure.

The change introduces 'FIR guards' – a set of instructions defining
preservation and restoration rules for individual state items. As each
resolution phase is supposed to modify only a (sort of) known subset
of tree elements, restoration of potentially changed state on a failure
effectively returns the tree consistency.

Note that guards are not defined for certain phase transformers. The
reason is that the transformers already update the tree content safely.
E.g., the type reference is updated once it is resolved, and already
resolved type references are either resolved the same way again, or
just skipped on consequent phase runs.
This commit is contained in:
Yan Zhulanow
2023-05-25 20:39:00 +09:00
committed by Space Team
parent d386dd1f7b
commit 91c3ebac27
13 changed files with 861 additions and 157 deletions
@@ -65,6 +65,12 @@ sourceSets {
"test" { projectDefault() }
}
kotlin {
compilerOptions {
freeCompilerArgs.add("-Xcontext-receivers")
}
}
projectTest(jUnitMode = JUnitMode.JUnit5) {
dependsOn(":dist")
workingDir = rootDir