[Frontend] Make DiagnosticSuppressor a project-level extension

Originally it was an application-level component, which caused non-trivial
  logic and cognitive load to carefully handle those extensions to avoid
  memory leaks.

6740a596 introduced a way to easily register `DiagnosticSuppressor` to
  project, and this commit continues this work, making it a proper
  project-level extension

A lot of changes caused by the fact, that this extension is needed to be
  obtained from `BindingContext` (see `BindingContextSuppressCache` and
  its usages), so almost all changes are introducing `Project` to
  `BindingContext`

^KT-66449 Fixed
This commit is contained in:
Dmitriy Novozhilov
2024-03-08 08:52:28 +02:00
committed by Space Team
parent a552238874
commit d352cc9d96
45 changed files with 165 additions and 127 deletions
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.cli.jvm.compiler
import com.intellij.openapi.project.Project
import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.config.JvmTarget
import org.jetbrains.kotlin.config.LanguageVersionSettings
@@ -19,7 +20,7 @@ import org.jetbrains.kotlin.resolve.lazy.KotlinCodeAnalyzer
import org.jetbrains.kotlin.util.slicedMap.ReadOnlySlice
import org.jetbrains.kotlin.util.slicedMap.WritableSlice
class CliTraceHolder : JvmCodeAnalyzerInitializer() {
class CliTraceHolder(val project: Project) : JvmCodeAnalyzerInitializer() {
lateinit var bindingContext: BindingContext
private set
lateinit var module: ModuleDescriptor
@@ -34,7 +35,7 @@ class CliTraceHolder : JvmCodeAnalyzerInitializer() {
module: ModuleDescriptor,
codeAnalyzer: KotlinCodeAnalyzer,
languageVersionSettings: LanguageVersionSettings,
jvmTarget: JvmTarget
jvmTarget: JvmTarget,
) {
this.bindingContext = trace.bindingContext
this.module = module
@@ -49,13 +50,13 @@ class CliTraceHolder : JvmCodeAnalyzerInitializer() {
}
override fun createTrace(): BindingTraceContext {
return NoScopeRecordCliBindingTrace()
return NoScopeRecordCliBindingTrace(project)
}
}
// TODO: needs better name + list of keys to skip somewhere
class NoScopeRecordCliBindingTrace : CliBindingTrace() {
class NoScopeRecordCliBindingTrace(project: Project) : CliBindingTrace(project) {
override fun <K, V> record(slice: WritableSlice<K, V>, key: K, value: V) {
if (slice == BindingContext.LEXICAL_SCOPE || slice == BindingContext.DATA_FLOW_INFO_BEFORE) {
// In the compiler there's no need to keep scopes
@@ -69,7 +70,7 @@ class NoScopeRecordCliBindingTrace : CliBindingTrace() {
}
}
open class CliBindingTrace @TestOnly constructor() : BindingTraceContext() {
open class CliBindingTrace @TestOnly constructor(project: Project) : BindingTraceContext(project) {
private var kotlinCodeAnalyzer: KotlinCodeAnalyzer? = null
override fun toString(): String {
@@ -90,6 +90,7 @@ import org.jetbrains.kotlin.parsing.KotlinParserDefinition
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.CodeAnalyzerInitializer
import org.jetbrains.kotlin.resolve.ModuleAnnotationsResolver
import org.jetbrains.kotlin.resolve.diagnostics.DiagnosticSuppressor
import org.jetbrains.kotlin.resolve.extensions.AssignResolutionAltererExtension
import org.jetbrains.kotlin.resolve.extensions.ExtraImportsProviderExtension
import org.jetbrains.kotlin.resolve.extensions.SyntheticResolveExtension
@@ -726,6 +727,7 @@ class KotlinCoreEnvironment private constructor(
TypeAttributeTranslatorExtension.registerExtensionPoint(project)
AssignResolutionAltererExtension.registerExtensionPoint(project)
FirAnalysisHandlerExtension.registerExtensionPoint(project)
DiagnosticSuppressor.registerExtensionPoint(project)
}
internal fun registerExtensionsFromPlugins(project: MockProject, configuration: CompilerConfiguration) {
@@ -820,7 +822,7 @@ class KotlinCoreEnvironment private constructor(
@JvmStatic
fun registerKotlinLightClassSupport(project: MockProject) {
with(project) {
val traceHolder = CliTraceHolder()
val traceHolder = CliTraceHolder(project)
val cliLightClassGenerationSupport = CliLightClassGenerationSupport(traceHolder, project)
val kotlinAsJavaSupport = CliKotlinAsJavaSupport(project, traceHolder)
registerService(LightClassGenerationSupport::class.java, cliLightClassGenerationSupport)
@@ -16,7 +16,7 @@
area="IDEA_PROJECT"/>
<extensionPoint qualifiedName="org.jetbrains.kotlin.diagnosticSuppressor"
interface="org.jetbrains.kotlin.resolve.diagnostics.DiagnosticSuppressor"
dynamic="true"/>
area="IDEA_PROJECT" dynamic="true"/>
<extensionPoint qualifiedName="org.jetbrains.kotlin.expressionCodegenExtension"
interface="org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension"
area="IDEA_PROJECT" dynamic="true"/>
@@ -186,7 +186,7 @@ object KotlinToJVMBytecodeCompiler {
factory,
input,
fir2IrAndIrActualizerResult.irModuleFragment.descriptor,
NoScopeRecordCliBindingTrace().bindingContext,
NoScopeRecordCliBindingTrace(project).bindingContext,
FirJvmBackendClassResolver(fir2IrAndIrActualizerResult.components),
FirJvmBackendExtension(
fir2IrAndIrActualizerResult.components,
@@ -383,7 +383,7 @@ object KotlinToJVMBytecodeCompiler {
TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(
project,
sourceFiles,
NoScopeRecordCliBindingTrace(),
NoScopeRecordCliBindingTrace(project),
environment.configuration,
environment::createPackagePartProvider,
sourceModuleSearchScope = scope,
@@ -209,10 +209,12 @@ fun generateCodeFromIr(
input.configuration,
input.configuration.get(CLIConfigurationKeys.PHASE_CONFIG),
)
val dummyBindingContext = NoScopeRecordCliBindingTrace().bindingContext
val project = (environment.projectEnvironment as VfsBasedProjectEnvironment).project
val dummyBindingContext = NoScopeRecordCliBindingTrace(project).bindingContext
val generationState = GenerationState.Builder(
(environment.projectEnvironment as VfsBasedProjectEnvironment).project, ClassBuilderFactories.BINARIES,
project, ClassBuilderFactories.BINARIES,
input.irModuleFragment.descriptor, dummyBindingContext, input.configuration
).targetId(
input.targetId