[fir2ir] Allow non-cached type parameters

In the IDE, there might come declarations from other files/modules
that we link against, but not compile. Type parameters are one of such
declaration kinds.
This commit is contained in:
Yan Zhulanow
2023-06-01 16:27:20 +09:00
committed by Space Team
parent 14f83566d0
commit 7d88ade005
12 changed files with 54 additions and 5 deletions
@@ -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(
@@ -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),
@@ -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,
@@ -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(
@@ -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 {
@@ -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,
)
@@ -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()
@@ -171,6 +171,7 @@ fun ModuleCompilerAnalyzedOutput.convertToJsIr(
evaluatedConstTracker = configuration
.putIfAbsent(CommonConfigurationKeys.EVALUATED_CONST_TRACKER, EvaluatedConstTracker.create()),
inlineConstTracker = null,
allowNonCachedDeclarations = false,
)
return convertToIr(
@@ -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,
@@ -167,6 +167,7 @@ fun ModuleCompilerAnalyzedOutput.convertToWasmIr(
evaluatedConstTracker = configuration
.putIfAbsent(CommonConfigurationKeys.EVALUATED_CONST_TRACKER, EvaluatedConstTracker.create()),
inlineConstTracker = null,
allowNonCachedDeclarations = false
)
return convertToIr(
@@ -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())
@@ -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,