[Fir2IR] Don't use FIR f/o builder when IR f/o builder is enabled

Before this commit, fir f/o builder was inconsistently
disabled in some places, while it should work only for lazy declarations

Attempt to use it for non-lazy declarations, without maintaining
invariant, that it would also be used for super classes
led to unpredictable results.

This commit introduces opt-in, and marks all related API to three types
* Propagate error to user
* Fine to use, as it's checked if ir f/o builder is enabled
* Fine to use, as it is definitely a lazy class.

Several cases of missing checks was fixed.

^KT-65707
This commit is contained in:
Pavel Kunyavskiy
2024-02-09 16:07:45 +01:00
committed by Space Team
parent 74193aefb4
commit 9532172a22
23 changed files with 126 additions and 8 deletions
@@ -19388,6 +19388,12 @@ public class LLFirBlackBoxCodegenBasedTestGenerated extends AbstractLLFirBlackBo
runTest("compiler/testData/codegen/box/fakeOverride/kt65695.kt");
}
@Test
@TestMetadata("kt65707.kt")
public void testKt65707() throws Exception {
runTest("compiler/testData/codegen/box/fakeOverride/kt65707.kt");
}
@Test
@TestMetadata("methodOfAnyFromInterface.kt")
public void testMethodOfAnyFromInterface() throws Exception {
@@ -19388,6 +19388,12 @@ public class LLFirReversedBlackBoxCodegenBasedTestGenerated extends AbstractLLFi
runTest("compiler/testData/codegen/box/fakeOverride/kt65695.kt");
}
@Test
@TestMetadata("kt65707.kt")
public void testKt65707() throws Exception {
runTest("compiler/testData/codegen/box/fakeOverride/kt65707.kt");
}
@Test
@TestMetadata("methodOfAnyFromInterface.kt")
public void testMethodOfAnyFromInterface() throws Exception {
@@ -51,6 +51,7 @@ interface Fir2IrComponents {
val annotationGenerator: AnnotationGenerator
val callGenerator: CallAndReferenceGenerator
@FirBasedFakeOverrideGenerator
val fakeOverrideGenerator: FakeOverrideGenerator
val delegatedMemberGenerator: DelegatedMemberGenerator
val fakeOverrideBuilder: IrFakeOverrideBuilder
@@ -66,6 +66,7 @@ class Fir2IrComponentsStorage(
override val annotationGenerator: AnnotationGenerator = AnnotationGenerator(this)
override val callGenerator: CallAndReferenceGenerator = CallAndReferenceGenerator(this, fir2IrVisitor, conversionScope)
@FirBasedFakeOverrideGenerator
override val fakeOverrideGenerator: FakeOverrideGenerator = FakeOverrideGenerator(this, conversionScope)
override val delegatedMemberGenerator: DelegatedMemberGenerator = DelegatedMemberGenerator(this)
override val symbolsMappingForLazyClasses: Fir2IrSymbolsMappingForLazyClasses = Fir2IrSymbolsMappingForLazyClasses()
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol
import org.jetbrains.kotlin.fir.backend.generators.DataClassMembersGenerator
import org.jetbrains.kotlin.fir.backend.generators.FirBasedFakeOverrideGenerator
import org.jetbrains.kotlin.fir.backend.generators.addDeclarationToParent
import org.jetbrains.kotlin.fir.backend.generators.setParent
import org.jetbrains.kotlin.fir.declarations.*
@@ -67,6 +68,7 @@ class Fir2IrConverter(
private val generatorExtensions = session.extensionService.declarationGenerators
@FirBasedFakeOverrideGenerator
private var wereSourcesFakeOverridesBound = false
private val postponedDeclarationsForFakeOverridesBinding = mutableListOf<IrDeclaration>()
@@ -91,13 +93,18 @@ class Fir2IrConverter(
processFileAndClassMembers(firFile)
}
// 4. Override processing which sets overridden symbols for everything inside non-local regular classes
for (firFile in allFirFiles) {
bindFakeOverridesInFile(firFile)
}
@OptIn(FirBasedFakeOverrideGenerator::class) // checked for useIrFakeOverrideBuilder
if (!configuration.useIrFakeOverrideBuilder) {
for (firFile in allFirFiles) {
bindFakeOverridesInFile(firFile)
}
wereSourcesFakeOverridesBound = true
fakeOverrideGenerator.bindOverriddenSymbols(postponedDeclarationsForFakeOverridesBinding)
postponedDeclarationsForFakeOverridesBinding.clear()
wereSourcesFakeOverridesBound = true
fakeOverrideGenerator.bindOverriddenSymbols(postponedDeclarationsForFakeOverridesBinding)
postponedDeclarationsForFakeOverridesBinding.clear()
} else {
require(postponedDeclarationsForFakeOverridesBinding.isEmpty())
}
// Do (3) and (4) for local classes encountered during (3)
classifierStorage.processMembersOfClassesCreatedOnTheFly()
@@ -127,6 +134,7 @@ class Fir2IrConverter(
}
}
@FirBasedFakeOverrideGenerator
fun bindFakeOverridesOrPostpone(declarations: List<IrDeclaration>) {
// Do not run binding for lazy classes until all sources declarations are processed
if (wereSourcesFakeOverridesBound) {
@@ -280,6 +288,7 @@ class Fir2IrConverter(
}
if (!configuration.useIrFakeOverrideBuilder) {
@OptIn(FirBasedFakeOverrideGenerator::class) // checked for useIrFakeOverrideBuilder
fakeOverrideGenerator.computeFakeOverrides(klass, irClass, allDeclarations)
}
@@ -372,6 +381,7 @@ class Fir2IrConverter(
return irClass
}
@FirBasedFakeOverrideGenerator
private fun bindFakeOverridesInFile(file: FirFile) {
val irFile = declarationStorage.getIrFile(file)
// `irFile` definitely is not a lazy class
@@ -384,8 +394,10 @@ class Fir2IrConverter(
}
// `irClass` is a source class and definitely is not a lazy class
@OptIn(UnsafeDuringIrConstructionAPI::class)
// checked for useIrFakeOverrideBuilder
@OptIn(UnsafeDuringIrConstructionAPI::class, FirBasedFakeOverrideGenerator::class)
fun bindFakeOverridesInClass(klass: IrClass) {
if (configuration.useIrFakeOverrideBuilder) return
require(klass !is Fir2IrLazyClass)
fakeOverrideGenerator.bindOverriddenSymbols(klass.declarations)
delegatedMemberGenerator.bindDelegatedMembersOverriddenSymbols(klass)
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClassSymbol
import org.jetbrains.kotlin.fir.analysis.checkers.isVisibleInClass
import org.jetbrains.kotlin.fir.backend.generators.FirBasedFakeOverrideGenerator
import org.jetbrains.kotlin.fir.backend.generators.isExternalParent
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.builder.buildProperty
@@ -705,6 +706,7 @@ class Fir2IrDeclarationStorage(
val irParent = findIrParent(property, fakeOverrideOwnerLookupTag)
if (irParent?.isExternalParent() == true) {
val symbols = createPropertySymbols(property, fakeOverrideOwnerLookupTag, parentIsExternal = true)
@OptIn(FirBasedFakeOverrideGenerator::class) // only for lazy
val firForLazyProperty = calculateFirForLazyDeclaration(
property, fakeOverrideOwnerLookupTag, irParent,
fakeOverrideGenerator::createFirPropertyFakeOverrideIfNeeded
@@ -1085,6 +1087,7 @@ class Fir2IrDeclarationStorage(
val irParent = findIrParent(function, fakeOverrideOwnerLookupTag)
if (irParent?.isExternalParent() == true) {
val symbol = createMemberFunctionSymbol(function, fakeOverrideOwnerLookupTag, parentIsExternal = true)
@OptIn(FirBasedFakeOverrideGenerator::class) // only for lazy
val firForLazyFunction = calculateFirForLazyDeclaration(
function, fakeOverrideOwnerLookupTag, irParent,
fakeOverrideGenerator::createFirFunctionFakeOverrideIfNeeded
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.backend
import org.jetbrains.kotlin.backend.common.serialization.encodings.BinarySymbolData.SymbolKind
import org.jetbrains.kotlin.backend.common.serialization.kind
import org.jetbrains.kotlin.fir.backend.generators.FakeOverrideGenerator
import org.jetbrains.kotlin.fir.backend.generators.FirBasedFakeOverrideGenerator
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.classId
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
@@ -26,6 +27,7 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.utils.addToStdlib.shouldNotBeCalled
@OptIn(FirBasedFakeOverrideGenerator::class) // only for lazy
class FirIrProvider(val components: Fir2IrComponents) : IrProvider {
private val symbolProvider = components.session.symbolProvider
private val declarationStorage = components.declarationStorage
@@ -216,6 +216,7 @@ internal class ClassMemberGenerator(
* recalculates this value from scratch. Also, it's quite meaningless in non-platform modules anyway.
*/
if (!configuration.useIrFakeOverrideBuilder) {
@OptIn(FirBasedFakeOverrideGenerator::class)
irFunction.overriddenSymbols = firFunction.generateOverriddenFunctionSymbols(containingClass)
}
}
@@ -234,6 +235,7 @@ internal class ClassMemberGenerator(
* recalculates this value from scratch. Also, it's quite meaningless in non-platform modules anyway.
*/
if (!configuration.useIrFakeOverrideBuilder) {
@OptIn(FirBasedFakeOverrideGenerator::class) // checked for useIrFakeOverrideBuilder
irProperty.overriddenSymbols = property.generateOverriddenPropertySymbols(containingClass)
}
}
@@ -348,6 +350,7 @@ internal class ClassMemberGenerator(
}
}
if (containingClass != null && !components.configuration.useIrFakeOverrideBuilder) {
@OptIn(FirBasedFakeOverrideGenerator::class) // checked for useIrFakeOverrideBuilder
this.overriddenSymbols = property.generateOverriddenAccessorSymbols(containingClass, isGetter)
}
@@ -197,7 +197,9 @@ class DelegatedMemberGenerator(private val components: Fir2IrComponents) : Fir2I
return result
}
@OptIn(FirBasedFakeOverrideGenerator::class) // checked for useIrFakeOverrideBuilder
fun bindDelegatedMembersOverriddenSymbols(irClass: IrClass) {
if (components.configuration.useIrFakeOverrideBuilder) return
val superClasses by lazy(LazyThreadSafetyMode.NONE) {
irClass.superTypes.mapNotNullTo(mutableSetOf()) {
// All class symbols should be already bound at this moment
@@ -31,6 +31,13 @@ import org.jetbrains.kotlin.ir.util.parentAsClass
import org.jetbrains.kotlin.name.CallableId
import org.jetbrains.kotlin.name.Name
@RequiresOptIn(
level = RequiresOptIn.Level.ERROR,
message = "This api is planned for deprecation. Make sure, you don't use it with useIrFakeOverrideBuilder=true and non-lazy classes"
)
annotation class FirBasedFakeOverrideGenerator
@FirBasedFakeOverrideGenerator
class FakeOverrideGenerator(
private val components: Fir2IrComponents,
private val conversionScope: Fir2IrConversionScope
@@ -574,6 +581,7 @@ class FakeOverrideGenerator(
}
context(Fir2IrComponents)
@FirBasedFakeOverrideGenerator
internal fun FirProperty.generateOverriddenAccessorSymbols(containingClass: FirClass, isGetter: Boolean): List<IrSimpleFunctionSymbol> {
val scope = containingClass.unsubstitutedScope()
scope.processPropertiesByName(name) {}
@@ -603,6 +611,7 @@ internal fun FirProperty.generateOverriddenAccessorSymbols(containingClass: FirC
}
context(Fir2IrComponents)
@FirBasedFakeOverrideGenerator
internal fun FirProperty.generateOverriddenPropertySymbols(containingClass: FirClass): List<IrPropertySymbol> {
val superClasses = containingClass.getSuperTypesAsIrClasses()
val overriddenSet = mutableSetOf<IrPropertySymbol>()
@@ -618,6 +627,7 @@ internal fun FirProperty.generateOverriddenPropertySymbols(containingClass: FirC
}
context(Fir2IrComponents)
@FirBasedFakeOverrideGenerator
internal fun FirSimpleFunction.generateOverriddenFunctionSymbols(containingClass: FirClass): List<IrSimpleFunctionSymbol> {
val superClasses = containingClass.getSuperTypesAsIrClasses()
val overriddenSet = mutableSetOf<IrSimpleFunctionSymbol>()
@@ -22,7 +22,6 @@ import org.jetbrains.kotlin.fir.expressions.impl.FirExpressionStub
import org.jetbrains.kotlin.fir.java.declarations.FirJavaField
import org.jetbrains.kotlin.fir.java.hasJvmFieldAnnotation
import org.jetbrains.kotlin.fir.lazy.Fir2IrLazyClass
import org.jetbrains.kotlin.fir.lazy.Fir2IrLazyConstructor
import org.jetbrains.kotlin.fir.lazy.Fir2IrLazyProperty
import org.jetbrains.kotlin.fir.references.toResolvedBaseSymbol
import org.jetbrains.kotlin.fir.resolve.calls.FirSimpleSyntheticPropertySymbol
@@ -472,6 +471,7 @@ class Fir2IrCallableDeclarationsGenerator(val components: Fir2IrComponents) : Fi
)
}
if (correspondingProperty is Fir2IrLazyProperty && correspondingProperty.containingClass != null && !isFakeOverride && dispatchReceiverType != null) {
@OptIn(FirBasedFakeOverrideGenerator::class) // for lazy
this.overriddenSymbols = correspondingProperty.fir.generateOverriddenAccessorSymbols(
correspondingProperty.containingClass, !isSetter
)
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.lazy
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.backend.*
import org.jetbrains.kotlin.fir.backend.generators.FirBasedFakeOverrideGenerator
import org.jetbrains.kotlin.fir.backend.generators.isFakeOverride
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.*
@@ -30,6 +31,7 @@ import org.jetbrains.kotlin.ir.util.isEnumClass
import org.jetbrains.kotlin.ir.util.isObject
import org.jetbrains.kotlin.name.Name
@OptIn(FirBasedFakeOverrideGenerator::class) // only for lazy
class Fir2IrLazyClass(
components: Fir2IrComponents,
override val startOffset: Int,
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.isAnnotationClass
import org.jetbrains.kotlin.fir.backend.*
import org.jetbrains.kotlin.fir.backend.generators.FirBasedFakeOverrideGenerator
import org.jetbrains.kotlin.fir.backend.generators.generateOverriddenPropertySymbols
import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
@@ -30,6 +31,7 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.NameUtils
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
@OptIn(FirBasedFakeOverrideGenerator::class)
class Fir2IrLazyProperty(
private val components: Fir2IrComponents,
override val startOffset: Int,
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.lazy
import org.jetbrains.kotlin.fir.backend.Fir2IrComponents
import org.jetbrains.kotlin.fir.backend.contextReceiversForFunctionOrContainingProperty
import org.jetbrains.kotlin.fir.backend.generators.Fir2IrCallableDeclarationsGenerator
import org.jetbrains.kotlin.fir.backend.generators.FirBasedFakeOverrideGenerator
import org.jetbrains.kotlin.fir.backend.generators.generateOverriddenFunctionSymbols
import org.jetbrains.kotlin.fir.backend.lazyMappedFunctionListVar
import org.jetbrains.kotlin.fir.backend.toIrType
@@ -24,6 +25,7 @@ import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
@OptIn(FirBasedFakeOverrideGenerator::class) // only for lazy
@Suppress("DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE") // K2 warning suppression, TODO: KT-62472
class Fir2IrLazySimpleFunction(
components: Fir2IrComponents,
@@ -19377,6 +19377,12 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr
runTest("compiler/testData/codegen/box/fakeOverride/kt65695.kt");
}
@Test
@TestMetadata("kt65707.kt")
public void testKt65707() throws Exception {
runTest("compiler/testData/codegen/box/fakeOverride/kt65707.kt");
}
@Test
@TestMetadata("methodOfAnyFromInterface.kt")
public void testMethodOfAnyFromInterface() throws Exception {
@@ -19377,6 +19377,12 @@ public class FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated
runTest("compiler/testData/codegen/box/fakeOverride/kt65695.kt");
}
@Test
@TestMetadata("kt65707.kt")
public void testKt65707() throws Exception {
runTest("compiler/testData/codegen/box/fakeOverride/kt65707.kt");
}
@Test
@TestMetadata("methodOfAnyFromInterface.kt")
public void testMethodOfAnyFromInterface() throws Exception {
@@ -19377,6 +19377,12 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo
runTest("compiler/testData/codegen/box/fakeOverride/kt65695.kt");
}
@Test
@TestMetadata("kt65707.kt")
public void testKt65707() throws Exception {
runTest("compiler/testData/codegen/box/fakeOverride/kt65707.kt");
}
@Test
@TestMetadata("methodOfAnyFromInterface.kt")
public void testMethodOfAnyFromInterface() throws Exception {
+19
View File
@@ -0,0 +1,19 @@
// TARGET_BACKEND: JVM
// FILE: A.java
public interface A {
String f();
}
// FILE: B.kt
interface B : A
// FILE: C.java
public interface C extends B { }
// FILE: CImpl.kt
class CImpl(p: C) : C by p
// FILE: box.kt
fun g(c: C): String = c.f()
fun box(): String = g(CImpl { "OK" })
@@ -19377,6 +19377,12 @@ public class JvmAbiConsistencyTestBoxGenerated extends AbstractJvmAbiConsistency
runTest("compiler/testData/codegen/box/fakeOverride/kt65695.kt");
}
@Test
@TestMetadata("kt65707.kt")
public void testKt65707() throws Exception {
runTest("compiler/testData/codegen/box/fakeOverride/kt65707.kt");
}
@Test
@TestMetadata("methodOfAnyFromInterface.kt")
public void testMethodOfAnyFromInterface() throws Exception {
@@ -18513,6 +18513,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/fakeOverride/kt65695.kt");
}
@Test
@TestMetadata("kt65707.kt")
public void testKt65707() throws Exception {
runTest("compiler/testData/codegen/box/fakeOverride/kt65707.kt");
}
@Test
@TestMetadata("methodOfAnyFromInterface.kt")
public void testMethodOfAnyFromInterface() throws Exception {
@@ -19377,6 +19377,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/fakeOverride/kt65695.kt");
}
@Test
@TestMetadata("kt65707.kt")
public void testKt65707() throws Exception {
runTest("compiler/testData/codegen/box/fakeOverride/kt65707.kt");
}
@Test
@TestMetadata("methodOfAnyFromInterface.kt")
public void testMethodOfAnyFromInterface() throws Exception {
@@ -19377,6 +19377,12 @@ public class IrBlackBoxCodegenWithIrInlinerTestGenerated extends AbstractIrBlack
runTest("compiler/testData/codegen/box/fakeOverride/kt65695.kt");
}
@Test
@TestMetadata("kt65707.kt")
public void testKt65707() throws Exception {
runTest("compiler/testData/codegen/box/fakeOverride/kt65707.kt");
}
@Test
@TestMetadata("methodOfAnyFromInterface.kt")
public void testMethodOfAnyFromInterface() throws Exception {
@@ -16144,6 +16144,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/fakeOverride/kt65695.kt");
}
@TestMetadata("kt65707.kt")
public void testKt65707() throws Exception {
runTest("compiler/testData/codegen/box/fakeOverride/kt65707.kt");
}
@TestMetadata("methodOfAnyFromInterface.kt")
public void testMethodOfAnyFromInterface() throws Exception {
runTest("compiler/testData/codegen/box/fakeOverride/methodOfAnyFromInterface.kt");