Fir2Ir: enable IR-based fake override builder

Invert the logic of IR/FIR2IR-based generators: change the CLI argument
to -Xuse-fir-fake-override-builder, test directive to
USE_FIR_BASED_FAKE_OVERRIDE_GENERATOR, etc.

The changes in test data caused by using IR fake override builder by
default are in the subsequent commit.

 #KT-61514
This commit is contained in:
Alexander Udalov
2024-02-26 16:19:04 +01:00
committed by Space Team
parent 09db7dbd22
commit f98a22e8e4
30 changed files with 72 additions and 81 deletions
@@ -107,12 +107,12 @@ fun FirResult.convertToIrAndActualize(
),
actualizerTypeContextProvider(irModuleFragment.irBuiltins),
fir2IrConfiguration.expectActualTracker,
fir2IrConfiguration.useIrFakeOverrideBuilder,
fir2IrConfiguration.useFirBasedFakeOverrideGenerator,
irModuleFragment,
allIrModules.dropLast(1),
)
if (fir2IrConfiguration.useIrFakeOverrideBuilder) {
if (!fir2IrConfiguration.useFirBasedFakeOverrideGenerator) {
// actualizeCallablesAndMergeModules call below in fact can also actualize classifiers.
// So to avoid even more changes, when this mode is disabled, we don't run classifiers
// actualization separately. This should go away, after useIrFakeOverrideBuilder becomes
@@ -122,7 +122,7 @@ fun FirResult.convertToIrAndActualize(
components.fakeOverrideBuilder.buildForAll(allIrModules, temporaryResolver)
}
val expectActualMap = irActualizer?.actualizeCallablesAndMergeModules() ?: emptyMap()
if (components.configuration.useIrFakeOverrideBuilder) {
if (!components.configuration.useFirBasedFakeOverrideGenerator) {
val fakeOverrideResolver = SpecialFakeOverrideSymbolsResolver(expectActualMap)
irModuleFragment.acceptVoid(SpecialFakeOverrideSymbolsResolverVisitor(fakeOverrideResolver))
@OptIn(Fir2IrSymbolsMappingForLazyClasses.SymbolRemapperInternals::class)
@@ -21,7 +21,6 @@ import org.jetbrains.kotlin.constant.EvaluatedConstTracker
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
import org.jetbrains.kotlin.incremental.components.InlineConstTracker
import org.jetbrains.kotlin.ir.util.SymbolTable
/**
* @param allowNonCachedDeclarations
@@ -30,8 +29,9 @@ import org.jetbrains.kotlin.ir.util.SymbolTable
* 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.
*
* @param useIrFakeOverrideBuilder Enables creation of fake-overrides using the IR f/o generator instead of the FIR2IR one.
* See [KT-61514](https://youtrack.jetbrains.com/issue/KT-61514).
* @param useFirBasedFakeOverrideGenerator
* Generate all fake overrides via FIR2IR instead of IR, i.e. revert to behavior before
* [KT-61514](https://youtrack.jetbrains.com/issue/KT-61514) was resolved.
*/
class Fir2IrConfiguration private constructor(
val languageVersionSettings: LanguageVersionSettings,
@@ -40,9 +40,8 @@ class Fir2IrConfiguration private constructor(
val inlineConstTracker: InlineConstTracker?,
val expectActualTracker: ExpectActualTracker?,
val allowNonCachedDeclarations: Boolean,
val useIrFakeOverrideBuilder: Boolean,
val useFirBasedFakeOverrideGenerator: Boolean,
) {
companion object {
fun forJvmCompilation(
compilerConfiguration: CompilerConfiguration,
@@ -58,7 +57,7 @@ class Fir2IrConfiguration private constructor(
inlineConstTracker = compilerConfiguration[CommonConfigurationKeys.INLINE_CONST_TRACKER],
expectActualTracker = compilerConfiguration[CommonConfigurationKeys.EXPECT_ACTUAL_TRACKER],
allowNonCachedDeclarations = false,
useIrFakeOverrideBuilder = compilerConfiguration.getBoolean(CommonConfigurationKeys.USE_IR_FAKE_OVERRIDE_BUILDER),
useFirBasedFakeOverrideGenerator = compilerConfiguration.getBoolean(CommonConfigurationKeys.USE_FIR_BASED_FAKE_OVERRIDE_GENERATOR),
)
fun forKlibCompilation(
@@ -75,7 +74,7 @@ class Fir2IrConfiguration private constructor(
inlineConstTracker = null,
expectActualTracker = compilerConfiguration[CommonConfigurationKeys.EXPECT_ACTUAL_TRACKER],
allowNonCachedDeclarations = false,
useIrFakeOverrideBuilder = true,
useFirBasedFakeOverrideGenerator = false,
)
fun forAnalysisApi(
@@ -93,7 +92,7 @@ class Fir2IrConfiguration private constructor(
inlineConstTracker = compilerConfiguration[CommonConfigurationKeys.INLINE_CONST_TRACKER],
expectActualTracker = compilerConfiguration[CommonConfigurationKeys.EXPECT_ACTUAL_TRACKER],
allowNonCachedDeclarations = true,
useIrFakeOverrideBuilder = compilerConfiguration.getBoolean(CommonConfigurationKeys.USE_IR_FAKE_OVERRIDE_BUILDER),
useFirBasedFakeOverrideGenerator = compilerConfiguration.getBoolean(CommonConfigurationKeys.USE_FIR_BASED_FAKE_OVERRIDE_GENERATOR),
)
}
}
@@ -93,8 +93,8 @@ class Fir2IrConverter(
processFileAndClassMembers(firFile)
}
// 4. Override processing which sets overridden symbols for everything inside non-local regular classes
@OptIn(FirBasedFakeOverrideGenerator::class) // checked for useIrFakeOverrideBuilder
if (!configuration.useIrFakeOverrideBuilder) {
@OptIn(FirBasedFakeOverrideGenerator::class)
if (configuration.useFirBasedFakeOverrideGenerator) {
for (firFile in allFirFiles) {
bindFakeOverridesInFile(firFile)
}
@@ -119,7 +119,7 @@ class Fir2IrConverter(
}
if (
!configuration.useIrFakeOverrideBuilder &&
configuration.useFirBasedFakeOverrideGenerator &&
components.session.languageVersionSettings.supportsFeature(LanguageFeature.MultiPlatformProjects)
) {
// See the comment to generateUnboundFakeOverrides function itself
@@ -287,8 +287,8 @@ class Fir2IrConverter(
declarationStorage.leaveScope(irConstructor.symbol)
}
if (!configuration.useIrFakeOverrideBuilder) {
@OptIn(FirBasedFakeOverrideGenerator::class) // checked for useIrFakeOverrideBuilder
if (configuration.useFirBasedFakeOverrideGenerator) {
@OptIn(FirBasedFakeOverrideGenerator::class)
fakeOverrideGenerator.computeFakeOverrides(klass, irClass, allDeclarations)
}
@@ -392,10 +392,9 @@ class Fir2IrConverter(
}
// `irClass` is a source class and definitely is not a lazy class
// checked for useIrFakeOverrideBuilder
@OptIn(UnsafeDuringIrConstructionAPI::class, FirBasedFakeOverrideGenerator::class)
fun bindFakeOverridesInClass(klass: IrClass) {
if (configuration.useIrFakeOverrideBuilder) return
if (!configuration.useFirBasedFakeOverrideGenerator) return
require(klass !is Fir2IrLazyClass)
fakeOverrideGenerator.bindOverriddenSymbols(klass.declarations)
delegatedMemberGenerator.bindDelegatedMembersOverriddenSymbols(klass)
@@ -395,7 +395,7 @@ class Fir2IrDeclarationStorage(
parentIsExternal: Boolean
): IrSimpleFunctionSymbol {
if (
!configuration.useIrFakeOverrideBuilder ||
configuration.useFirBasedFakeOverrideGenerator ||
parentIsExternal ||
function !is FirSimpleFunction ||
!function.isFakeOverride(fakeOverrideOwnerLookupTag)
@@ -592,7 +592,7 @@ class Fir2IrDeclarationStorage(
parentIsExternal: Boolean
): PropertySymbols {
if (
configuration.useIrFakeOverrideBuilder &&
!configuration.useFirBasedFakeOverrideGenerator &&
!parentIsExternal &&
property.isFakeOverride(fakeOverrideOwnerLookupTag)
) {
@@ -1189,7 +1189,7 @@ class Fir2IrDeclarationStorage(
)
irForFirSessionDependantDeclarationMap[key] = cachedInSymbolTable
}
configuration.useIrFakeOverrideBuilder -> {
!configuration.useFirBasedFakeOverrideGenerator -> {
/*
* If IR fake override builder is used for building fake-overrides, they are generated bypassing Fir2IrDeclarationStorage,
* and are written directly to SymbolTable. So in this case it is normal to save the result from symbol table into
@@ -215,7 +215,7 @@ internal class ClassMemberGenerator(
* In useIrFakeOverrideBuilder it would be dropped anyway, as [org.jetbrains.kotlin.ir.overrides.IrFakeOverrideBuilder.buildFakeOverridesForClass]
* recalculates this value from scratch. Also, it's quite meaningless in non-platform modules anyway.
*/
if (!configuration.useIrFakeOverrideBuilder) {
if (configuration.useFirBasedFakeOverrideGenerator) {
@OptIn(FirBasedFakeOverrideGenerator::class)
irFunction.overriddenSymbols = firFunction.generateOverriddenFunctionSymbols(containingClass)
}
@@ -234,7 +234,7 @@ internal class ClassMemberGenerator(
* In useIrFakeOverrideBuilder it would be dropped anyway, as [org.jetbrains.kotlin.ir.overrides.IrFakeOverrideBuilder.buildFakeOverridesForClass]
* recalculates this value from scratch. Also, it's quite meaningless in non-platform modules anyway.
*/
if (!configuration.useIrFakeOverrideBuilder) {
if (configuration.useFirBasedFakeOverrideGenerator) {
@OptIn(FirBasedFakeOverrideGenerator::class) // checked for useIrFakeOverrideBuilder
irProperty.overriddenSymbols = property.generateOverriddenPropertySymbols(containingClass)
}
@@ -349,8 +349,8 @@ internal class ClassMemberGenerator(
declarationStorage.leaveScope(this.symbol)
}
}
if (containingClass != null && !components.configuration.useIrFakeOverrideBuilder) {
@OptIn(FirBasedFakeOverrideGenerator::class) // checked for useIrFakeOverrideBuilder
if (containingClass != null && components.configuration.useFirBasedFakeOverrideGenerator) {
@OptIn(FirBasedFakeOverrideGenerator::class)
this.overriddenSymbols = property.generateOverriddenAccessorSymbols(containingClass, isGetter)
}
@@ -197,9 +197,9 @@ class DelegatedMemberGenerator(private val components: Fir2IrComponents) : Fir2I
return result
}
@OptIn(FirBasedFakeOverrideGenerator::class) // checked for useIrFakeOverrideBuilder
@OptIn(FirBasedFakeOverrideGenerator::class)
fun bindDelegatedMembersOverriddenSymbols(irClass: IrClass) {
if (components.configuration.useIrFakeOverrideBuilder) return
if (!components.configuration.useFirBasedFakeOverrideGenerator) return
val superClasses by lazy(LazyThreadSafetyMode.NONE) {
irClass.superTypes.mapNotNullTo(mutableSetOf()) {
// All class symbols should be already bound at this moment
@@ -233,9 +233,9 @@ class Fir2IrLazyProperty(
}
override var overriddenSymbols: List<IrPropertySymbol> by symbolsMappingForLazyClasses.lazyMappedPropertyListVar(lock) {
when (configuration.useIrFakeOverrideBuilder) {
true -> computeOverriddenSymbolsForIrFakeOverrideGenerator()
false -> computeOverriddenUsingFir2IrFakeOverrideGenerator()
when (configuration.useFirBasedFakeOverrideGenerator) {
true -> computeOverriddenUsingFir2IrFakeOverrideGenerator()
false -> computeOverriddenSymbolsForIrFakeOverrideGenerator()
}
}
@@ -96,13 +96,12 @@ class Fir2IrLazySimpleFunction(
}
override var overriddenSymbols: List<IrSimpleFunctionSymbol> by symbolsMappingForLazyClasses.lazyMappedFunctionListVar(lock) {
when (configuration.useIrFakeOverrideBuilder) {
true -> computeOverriddenSymbolsForIrFakeOverrideGenerator()
false -> computeOverriddenUsingFir2IrFakeOverrideGenerator()
when (configuration.useFirBasedFakeOverrideGenerator) {
true -> computeOverriddenUsingFir2IrFakeOverrideGenerator()
false -> computeOverriddenSymbolsForIrFakeOverrideGenerator()
}
}
// TODO: drop this function after migration to IR f/o generator will be complete (KT-64202)
private fun computeOverriddenUsingFir2IrFakeOverrideGenerator(): List<IrSimpleFunctionSymbol> {
if (firParent == null) return emptyList()
@@ -20,7 +20,7 @@ import java.util.regex.Pattern;
@SuppressWarnings("all")
@TestMetadata("compiler/testData/codegen/box")
@TestDataPath("$PROJECT_ROOT")
public class FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated extends AbstractFirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTest {
public class FirLightTreeBlackBoxCodegenWithFir2IrFakeOverrideGeneratorTestGenerated extends AbstractFirLightTreeBlackBoxCodegenWithFir2IrFakeOverrideGeneratorTest {
@Test
public void testAllFilesPresentInBox() {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true, "script");