Files
kotlin-fork/analysis/low-level-api-fir/build.gradle.kts
T
Yan Zhulanow 91c3ebac27 [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.
2023-06-30 14:26:43 +00:00

92 lines
3.5 KiB
Kotlin

plugins {
kotlin("jvm")
id("jps-compatible")
}
dependencies {
api(project(":compiler:psi"))
implementation(project(":analysis:project-structure"))
api(project(":compiler:fir:fir2ir"))
api(project(":compiler:fir:fir2ir:jvm-backend"))
api(project(":compiler:ir.serialization.common"))
api(project(":compiler:fir:resolve"))
api(project(":compiler:fir:providers"))
api(project(":compiler:fir:semantics"))
api(project(":compiler:fir:checkers"))
api(project(":compiler:fir:checkers:checkers.jvm"))
api(project(":compiler:fir:checkers:checkers.js"))
api(project(":compiler:fir:checkers:checkers.native"))
api(project(":compiler:fir:java"))
api(project(":compiler:backend.common.jvm"))
api(project(":analysis:analysis-api-impl-barebone"))
api(project(":js:js.config"))
api(project(":compiler:cli-common"))
testImplementation(project(":analysis:analysis-api-fir"))
implementation(project(":compiler:frontend.common"))
implementation(project(":compiler:fir:entrypoint"))
implementation(project(":analysis:analysis-api-providers"))
implementation(project(":analysis:analysis-api"))
implementation(project(":analysis:analysis-internal-utils"))
implementation(project(":analysis:analysis-api-standalone:analysis-api-standalone-base"))
implementation(project(":kotlin-scripting-compiler"))
implementation(project(":kotlin-scripting-common"))
// We cannot use the latest version `3.1.5` because it doesn't support Java 8.
implementation("com.github.ben-manes.caffeine:caffeine:2.9.3")
api(intellijCore())
testApi(projectTests(":compiler:test-infrastructure-utils"))
testApi(projectTests(":compiler:test-infrastructure"))
testImplementation(projectTests(":compiler:tests-common-new"))
testImplementation("org.opentest4j:opentest4j:1.2.0")
testImplementation(project(":analysis:analysis-api-standalone:analysis-api-fir-standalone-base"))
testImplementation(toolsJar())
testImplementation(projectTests(":compiler:tests-common"))
testImplementation(projectTests(":compiler:fir:analysis-tests:legacy-fir-tests"))
testImplementation(projectTests(":analysis:analysis-api-impl-barebone"))
testImplementation(projectTests(":analysis:analysis-test-framework"))
testImplementation(projectTests(":analysis:analysis-api-impl-base"))
testImplementation(project(":kotlin-test:kotlin-test-junit"))
testApiJUnit5()
testImplementation(project(":analysis:symbol-light-classes"))
testRuntimeOnly(project(":core:descriptors.runtime"))
// We use 'api' instead of 'implementation' because other modules might be using these jars indirectly
testApi(project(":plugins:fir-plugin-prototype"))
testApi(projectTests(":plugins:fir-plugin-prototype"))
}
sourceSets {
"main" { projectDefault() }
"test" { projectDefault() }
}
kotlin {
compilerOptions {
freeCompilerArgs.add("-Xcontext-receivers")
}
}
projectTest(jUnitMode = JUnitMode.JUnit5) {
dependsOn(":dist")
workingDir = rootDir
useJUnitPlatform()
}
allprojects {
tasks.withType<org.jetbrains.kotlin.gradle.dsl.KotlinCompile<*>> {
kotlinOptions {
freeCompilerArgs += "-opt-in=org.jetbrains.kotlin.fir.symbols.SymbolInternals"
freeCompilerArgs += "-opt-in=org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirInternals"
freeCompilerArgs += "-opt-in=org.jetbrains.kotlin.analysis.api.KtAnalysisApiInternals"
}
}
}
testsJar()