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 7d76058b56b..9b1d6f70c9d 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 @@ -17,6 +17,7 @@ import org.jetbrains.kotlin.fir.resolve.providers.firProvider import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider import org.jetbrains.kotlin.fir.resolve.providers.toSymbol import org.jetbrains.kotlin.fir.resolve.toSymbol +import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag import org.jetbrains.kotlin.fir.symbols.Fir2IrClassSymbol import org.jetbrains.kotlin.fir.symbols.Fir2IrEnumEntrySymbol @@ -197,15 +198,39 @@ class Fir2IrClassifierStorage( declarations.any { it is FirCallableDeclaration && it.modality == Modality.ABSTRACT } -> { Modality.ABSTRACT } - declarations.any { it is FirEnumEntry && it.initializer != null } -> { - Modality.OPEN - } - else -> { + declarations.none { it is FirEnumEntry && it.initializer != null } -> { Modality.FINAL } + hasAbstractMembersInScope() -> { + Modality.ABSTRACT + } + else -> { + Modality.OPEN + } } } + private fun FirRegularClass.hasAbstractMembersInScope(): Boolean { + val scope = unsubstitutedScope(session, scopeSession, withForcedTypeCalculator = false) + val names = scope.getCallableNames() + var hasAbstract = false + for (name in names) { + scope.processFunctionsByName(name) { + if (it.isAbstract) { + hasAbstract = true + } + } + if (hasAbstract) return true + scope.processPropertiesByName(name) { + if (it.isAbstract) { + hasAbstract = true + } + } + if (hasAbstract) return true + } + return false + } + // This function is called when we refer local class earlier than we reach its declaration // This can happen e.g. when implicit return type has a local class constructor private fun createLocalIrClassOnTheFly(klass: FirClass): IrClass { diff --git a/compiler/testData/codegen/box/enum/enumEntryReferenceFromInnerClassConstructor1.kt b/compiler/testData/codegen/box/enum/enumEntryReferenceFromInnerClassConstructor1.kt index e39d4be0823..135eeffae89 100644 --- a/compiler/testData/codegen/box/enum/enumEntryReferenceFromInnerClassConstructor1.kt +++ b/compiler/testData/codegen/box/enum/enumEntryReferenceFromInnerClassConstructor1.kt @@ -1,5 +1,3 @@ -// KT-55828 -// IGNORE_BACKEND_K2: NATIVE interface IFoo { fun foo(): String } diff --git a/compiler/testData/codegen/box/enum/enumEntryReferenceFromInnerClassConstructor2.kt b/compiler/testData/codegen/box/enum/enumEntryReferenceFromInnerClassConstructor2.kt index d80baf9452e..7745c582462 100644 --- a/compiler/testData/codegen/box/enum/enumEntryReferenceFromInnerClassConstructor2.kt +++ b/compiler/testData/codegen/box/enum/enumEntryReferenceFromInnerClassConstructor2.kt @@ -1,5 +1,3 @@ -// KT-55828 -// IGNORE_BACKEND_K2: NATIVE interface IFoo { fun foo(): String } diff --git a/compiler/testData/codegen/box/enum/enumEntryReferenceFromInnerClassConstructor3.kt b/compiler/testData/codegen/box/enum/enumEntryReferenceFromInnerClassConstructor3.kt index 384fc0315c3..635103b8b02 100644 --- a/compiler/testData/codegen/box/enum/enumEntryReferenceFromInnerClassConstructor3.kt +++ b/compiler/testData/codegen/box/enum/enumEntryReferenceFromInnerClassConstructor3.kt @@ -1,5 +1,3 @@ -// KT-55828 -// IGNORE_BACKEND_K2: NATIVE interface IFoo { fun foo(): String } diff --git a/compiler/testData/codegen/box/enum/enumInheritedFromTrait.kt b/compiler/testData/codegen/box/enum/enumInheritedFromTrait.kt index 3e3a2d26d4d..8171865caed 100644 --- a/compiler/testData/codegen/box/enum/enumInheritedFromTrait.kt +++ b/compiler/testData/codegen/box/enum/enumInheritedFromTrait.kt @@ -1,5 +1,3 @@ -// KT-55828 -// IGNORE_BACKEND_K2: NATIVE package test fun box() = MyEnum.E1.f() + MyEnum.E2.f() diff --git a/compiler/testData/ir/irText/classes/enumClassModality.fir.ir.txt b/compiler/testData/ir/irText/classes/enumClassModality.fir.ir.txt index fbd0c5bdb89..f27917540a8 100644 --- a/compiler/testData/ir/irText/classes/enumClassModality.fir.ir.txt +++ b/compiler/testData/ir/irText/classes/enumClassModality.fir.ir.txt @@ -542,13 +542,13 @@ FILE fqName: fileName:/enumClassModality.kt overridden: public open fun toString (): kotlin.String declared in kotlin.Any $this: VALUE_PARAMETER name: type:kotlin.Any - CLASS ENUM_CLASS name:TestAbstractEnum2 modality:OPEN visibility:public superTypes:[.IFoo; kotlin.Enum<.TestAbstractEnum2>] + CLASS ENUM_CLASS name:TestAbstractEnum2 modality:ABSTRACT visibility:public superTypes:[.IFoo; kotlin.Enum<.TestAbstractEnum2>] $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.TestAbstractEnum2 CONSTRUCTOR visibility:private <> () returnType:.TestAbstractEnum2 [primary] BLOCK_BODY ENUM_CONSTRUCTOR_CALL 'public constructor (name: kotlin.String, ordinal: kotlin.Int) [primary] declared in kotlin.Enum' : .TestAbstractEnum2 - INSTANCE_INITIALIZER_CALL classDescriptor='CLASS ENUM_CLASS name:TestAbstractEnum2 modality:OPEN visibility:public superTypes:[.IFoo; kotlin.Enum<.TestAbstractEnum2>]' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS ENUM_CLASS name:TestAbstractEnum2 modality:ABSTRACT visibility:public superTypes:[.IFoo; kotlin.Enum<.TestAbstractEnum2>]' ENUM_ENTRY name:X1 init: EXPRESSION_BODY ENUM_CONSTRUCTOR_CALL 'private constructor () [primary] declared in .TestAbstractEnum2.X1' diff --git a/compiler/testData/ir/irText/classes/enumClassModality.fir.kt.txt b/compiler/testData/ir/irText/classes/enumClassModality.fir.kt.txt index 34e7aa73f03..412ff657fba 100644 --- a/compiler/testData/ir/irText/classes/enumClassModality.fir.kt.txt +++ b/compiler/testData/ir/irText/classes/enumClassModality.fir.kt.txt @@ -156,7 +156,7 @@ interface IFoo { } -open enum class TestAbstractEnum2 : IFoo, Enum { +abstract enum class TestAbstractEnum2 : IFoo, Enum { private constructor() /* primary */ { super/*Enum*/() /* () */