diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirCompilerFacility.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirCompilerFacility.kt index 20f97c1988f..63f59d57d1e 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirCompilerFacility.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirCompilerFacility.kt @@ -90,7 +90,8 @@ internal class KtFirCompilerFacility( diagnosticsReporter, linkViaSignatures = false, effectiveConfiguration[CommonConfigurationKeys.EVALUATED_CONST_TRACKER] ?: EvaluatedConstTracker.create(), - effectiveConfiguration[CommonConfigurationKeys.INLINE_CONST_TRACKER] + effectiveConfiguration[CommonConfigurationKeys.INLINE_CONST_TRACKER], + allowNonCachedDeclarations = true ) val fir2IrResult = Fir2IrConverter.createModuleFragmentWithSignaturesIfNeeded( diff --git a/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/klib/compilerPipeline.kt b/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/klib/compilerPipeline.kt index d2eefd04121..5b1c62a9cd6 100644 --- a/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/klib/compilerPipeline.kt +++ b/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/klib/compilerPipeline.kt @@ -234,6 +234,7 @@ fun transformFirToIr( evaluatedConstTracker = moduleStructure.compilerConfiguration .putIfAbsent(CommonConfigurationKeys.EVALUATED_CONST_TRACKER, EvaluatedConstTracker.create()), inlineConstTracker = null, + allowNonCachedDeclarations = false, ), IrGenerationExtension.getInstances(moduleStructure.project), signatureComposer = DescriptorSignatureComposerStub(JsManglerDesc), diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/FirKotlinToJvmBytecodeCompiler.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/FirKotlinToJvmBytecodeCompiler.kt index 5acf71fbd31..c021fbc154a 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/FirKotlinToJvmBytecodeCompiler.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/FirKotlinToJvmBytecodeCompiler.kt @@ -160,6 +160,7 @@ object FirKotlinToJvmBytecodeCompiler { evaluatedConstTracker = moduleConfiguration .putIfAbsent(CommonConfigurationKeys.EVALUATED_CONST_TRACKER, EvaluatedConstTracker.create()), inlineConstTracker = moduleConfiguration[CommonConfigurationKeys.INLINE_CONST_TRACKER], + allowNonCachedDeclarations = false, ) val fir2IrAndIrActualizerResult = firResult.convertToIrAndActualizeForJvm( fir2IrExtensions, diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/pipeline/compilerPipeline.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/pipeline/compilerPipeline.kt index 54bf85bb583..c358fb6914f 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/pipeline/compilerPipeline.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/pipeline/compilerPipeline.kt @@ -185,6 +185,7 @@ fun convertAnalyzedFirToIr( evaluatedConstTracker = input.configuration .putIfAbsent(CommonConfigurationKeys.EVALUATED_CONST_TRACKER, EvaluatedConstTracker.create()), inlineConstTracker = input.configuration[CommonConfigurationKeys.INLINE_CONST_TRACKER], + allowNonCachedDeclarations = false, ) val (irModuleFragment, components, pluginContext, irActualizedResult) = analysisResults.convertToIrAndActualizeForJvm( diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrClassifierStorage.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrClassifierStorage.kt index 7f73ea8675d..71796a10cd0 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrClassifierStorage.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrClassifierStorage.kt @@ -665,10 +665,41 @@ class Fir2IrClassifierStorage( typeOrigin: ConversionTypeOrigin ): IrTypeParameterSymbol { val firTypeParameter = firTypeParameterSymbol.fir - return getCachedIrTypeParameter(firTypeParameter, typeOrigin)?.symbol - // We can try to use default cache because setter can use parent type parameters - ?: typeParameterCache[firTypeParameter]?.symbol - ?: error("Cannot find cached type parameter by FIR symbol: ${firTypeParameterSymbol.name} of the owner: ${firTypeParameter.containingDeclarationSymbol}") + + val cachedSymbol = getCachedIrTypeParameter(firTypeParameter, typeOrigin)?.symbol + ?: typeParameterCache[firTypeParameter]?.symbol // We can try to use default cache because setter can use parent type parameters + + if (cachedSymbol != null) { + return cachedSymbol + } + + if (components.configuration.allowNonCachedDeclarations) { + val firTypeParameterOwnerSymbol = firTypeParameter.containingDeclarationSymbol + + val firTypeParameterOwner = firTypeParameterOwnerSymbol.fir as FirTypeParameterRefsOwner + val index = firTypeParameterOwner.typeParameters.indexOf(firTypeParameter).also { check(it >= 0) } + + with(firTypeParameter) { + val symbol = IrTypeParameterSymbolImpl() + convertWithOffsets { startOffset, endOffset -> + irFactory.createTypeParameter( + startOffset, endOffset, + firTypeParameter.computeIrOrigin(), + name, + symbol, + variance, + if (index < 0) 0 else index, + isReified + ).apply { + superTypes = firTypeParameter.bounds.map { it.toIrType(typeConverter) } + } + } + + return symbol + } + } + + error("Cannot find cached type parameter by FIR symbol: ${firTypeParameterSymbol.name} of the owner: ${firTypeParameter.containingDeclarationSymbol}") } private val temporaryParent by lazy { diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConfiguration.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConfiguration.kt index 00478cb35d9..044b0602e16 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConfiguration.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConfiguration.kt @@ -21,10 +21,18 @@ import org.jetbrains.kotlin.constant.EvaluatedConstTracker import org.jetbrains.kotlin.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.incremental.components.InlineConstTracker +/** + * @param allowNonCachedDeclarations + * Normally, FIR-to-IR caches all declarations it meets in a compiled module. + * It means asking for an IR element of a non-cached declaration is a sign of inconsistent state. + * Code generation in the IDE is trickier, though, as declarations from any module can be potentially referenced. + * For such a scenario, there is a flag that relaxes consistency checks. + */ data class Fir2IrConfiguration( val languageVersionSettings: LanguageVersionSettings, val diagnosticReporter: DiagnosticReporter, val linkViaSignatures: Boolean, val evaluatedConstTracker: EvaluatedConstTracker, val inlineConstTracker: InlineConstTracker?, + val allowNonCachedDeclarations: Boolean, ) diff --git a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalFirJvmCompilerRunner.kt b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalFirJvmCompilerRunner.kt index ad01aaf060c..16dd7a35287 100644 --- a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalFirJvmCompilerRunner.kt +++ b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalFirJvmCompilerRunner.kt @@ -281,6 +281,7 @@ open class IncrementalFirJvmCompilerRunner( evaluatedConstTracker = configuration .putIfAbsent(CommonConfigurationKeys.EVALUATED_CONST_TRACKER, EvaluatedConstTracker.create()), inlineConstTracker = configuration[CommonConfigurationKeys.INLINE_CONST_TRACKER], + allowNonCachedDeclarations = false, ) val irGenerationExtensions = (projectEnvironment as? VfsBasedProjectEnvironment)?.project?.let { IrGenerationExtension.getInstances(it) }.orEmpty() diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/Fir2IrJsResultsConverter.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/Fir2IrJsResultsConverter.kt index cce28df642a..d4bb99fe7a8 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/Fir2IrJsResultsConverter.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/Fir2IrJsResultsConverter.kt @@ -171,6 +171,7 @@ fun ModuleCompilerAnalyzedOutput.convertToJsIr( evaluatedConstTracker = configuration .putIfAbsent(CommonConfigurationKeys.EVALUATED_CONST_TRACKER, EvaluatedConstTracker.create()), inlineConstTracker = null, + allowNonCachedDeclarations = false, ) return convertToIr( diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/Fir2IrJvmResultsConverter.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/Fir2IrJvmResultsConverter.kt index 90f4ea75205..b3ba59dfdc1 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/Fir2IrJvmResultsConverter.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/Fir2IrJvmResultsConverter.kt @@ -104,6 +104,7 @@ class Fir2IrJvmResultsConverter( evaluatedConstTracker = compilerConfiguration .putIfAbsent(CommonConfigurationKeys.EVALUATED_CONST_TRACKER, EvaluatedConstTracker.create()), inlineConstTracker = compilerConfiguration[CommonConfigurationKeys.INLINE_CONST_TRACKER], + allowNonCachedDeclarations = false ) val (irModuleFragment, components, pluginContext) = firOutputPart.firAnalyzerFacade.result.outputs.single().convertToIr( fir2IrExtensions, diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/Fir2IrWasmResultsConverter.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/Fir2IrWasmResultsConverter.kt index 28e611b811b..86ee7d55cfa 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/Fir2IrWasmResultsConverter.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/Fir2IrWasmResultsConverter.kt @@ -167,6 +167,7 @@ fun ModuleCompilerAnalyzedOutput.convertToWasmIr( evaluatedConstTracker = configuration .putIfAbsent(CommonConfigurationKeys.EVALUATED_CONST_TRACKER, EvaluatedConstTracker.create()), inlineConstTracker = null, + allowNonCachedDeclarations = false ) return convertToIr( diff --git a/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/codegen/GenerationUtils.kt b/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/codegen/GenerationUtils.kt index 6f3c3e1dc5a..63399c4f09c 100644 --- a/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/codegen/GenerationUtils.kt +++ b/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/codegen/GenerationUtils.kt @@ -136,6 +136,7 @@ object GenerationUtils { evaluatedConstTracker = configuration .putIfAbsent(CommonConfigurationKeys.EVALUATED_CONST_TRACKER, EvaluatedConstTracker.create()), inlineConstTracker = configuration[CommonConfigurationKeys.INLINE_CONST_TRACKER], + allowNonCachedDeclarations = false ) val commonMemberStorage = Fir2IrCommonMemberStorage(signatureComposerForJvmFir2Ir(linkViaSignatures), FirJvmKotlinMangler()) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Fir2Ir.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Fir2Ir.kt index 5925efe640f..eda3e91509b 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Fir2Ir.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Fir2Ir.kt @@ -79,6 +79,7 @@ internal fun PhaseContext.fir2Ir( evaluatedConstTracker = configuration .putIfAbsent(CommonConfigurationKeys.EVALUATED_CONST_TRACKER, EvaluatedConstTracker.create()), inlineConstTracker = null, + allowNonCachedDeclarations = false, ) val (irModuleFragment, components, pluginContext, irActualizedResult) = input.firResult.convertToIrAndActualize( fir2IrExtensions,