FIR2IR: make enum with abstract members from interfaces abstract

Related to KT-55828
This commit is contained in:
Mikhail Glukhikh
2023-02-01 10:56:15 +01:00
parent 89c42e20c9
commit 6d642c88f5
7 changed files with 32 additions and 15 deletions
@@ -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.symbolProvider
import org.jetbrains.kotlin.fir.resolve.providers.toSymbol import org.jetbrains.kotlin.fir.resolve.providers.toSymbol
import org.jetbrains.kotlin.fir.resolve.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.ConeClassLikeLookupTag
import org.jetbrains.kotlin.fir.symbols.Fir2IrClassSymbol import org.jetbrains.kotlin.fir.symbols.Fir2IrClassSymbol
import org.jetbrains.kotlin.fir.symbols.Fir2IrEnumEntrySymbol import org.jetbrains.kotlin.fir.symbols.Fir2IrEnumEntrySymbol
@@ -197,15 +198,39 @@ class Fir2IrClassifierStorage(
declarations.any { it is FirCallableDeclaration && it.modality == Modality.ABSTRACT } -> { declarations.any { it is FirCallableDeclaration && it.modality == Modality.ABSTRACT } -> {
Modality.ABSTRACT Modality.ABSTRACT
} }
declarations.any { it is FirEnumEntry && it.initializer != null } -> { declarations.none { it is FirEnumEntry && it.initializer != null } -> {
Modality.OPEN
}
else -> {
Modality.FINAL 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 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 // This can happen e.g. when implicit return type has a local class constructor
private fun createLocalIrClassOnTheFly(klass: FirClass): IrClass { private fun createLocalIrClassOnTheFly(klass: FirClass): IrClass {
@@ -1,5 +1,3 @@
// KT-55828
// IGNORE_BACKEND_K2: NATIVE
interface IFoo { interface IFoo {
fun foo(): String fun foo(): String
} }
@@ -1,5 +1,3 @@
// KT-55828
// IGNORE_BACKEND_K2: NATIVE
interface IFoo { interface IFoo {
fun foo(): String fun foo(): String
} }
@@ -1,5 +1,3 @@
// KT-55828
// IGNORE_BACKEND_K2: NATIVE
interface IFoo { interface IFoo {
fun foo(): String fun foo(): String
} }
@@ -1,5 +1,3 @@
// KT-55828
// IGNORE_BACKEND_K2: NATIVE
package test package test
fun box() = MyEnum.E1.f() + MyEnum.E2.f() fun box() = MyEnum.E1.f() + MyEnum.E2.f()
@@ -542,13 +542,13 @@ FILE fqName:<root> fileName:/enumClassModality.kt
overridden: overridden:
public open fun toString (): kotlin.String declared in kotlin.Any public open fun toString (): kotlin.String declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any $this: VALUE_PARAMETER name:<this> type:kotlin.Any
CLASS ENUM_CLASS name:TestAbstractEnum2 modality:OPEN visibility:public superTypes:[<root>.IFoo; kotlin.Enum<<root>.TestAbstractEnum2>] CLASS ENUM_CLASS name:TestAbstractEnum2 modality:ABSTRACT visibility:public superTypes:[<root>.IFoo; kotlin.Enum<<root>.TestAbstractEnum2>]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.TestAbstractEnum2 $this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.TestAbstractEnum2
CONSTRUCTOR visibility:private <> () returnType:<root>.TestAbstractEnum2 [primary] CONSTRUCTOR visibility:private <> () returnType:<root>.TestAbstractEnum2 [primary]
BLOCK_BODY BLOCK_BODY
ENUM_CONSTRUCTOR_CALL 'public constructor <init> (name: kotlin.String, ordinal: kotlin.Int) [primary] declared in kotlin.Enum' ENUM_CONSTRUCTOR_CALL 'public constructor <init> (name: kotlin.String, ordinal: kotlin.Int) [primary] declared in kotlin.Enum'
<E>: <root>.TestAbstractEnum2 <E>: <root>.TestAbstractEnum2
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS ENUM_CLASS name:TestAbstractEnum2 modality:OPEN visibility:public superTypes:[<root>.IFoo; kotlin.Enum<<root>.TestAbstractEnum2>]' INSTANCE_INITIALIZER_CALL classDescriptor='CLASS ENUM_CLASS name:TestAbstractEnum2 modality:ABSTRACT visibility:public superTypes:[<root>.IFoo; kotlin.Enum<<root>.TestAbstractEnum2>]'
ENUM_ENTRY name:X1 ENUM_ENTRY name:X1
init: EXPRESSION_BODY init: EXPRESSION_BODY
ENUM_CONSTRUCTOR_CALL 'private constructor <init> () [primary] declared in <root>.TestAbstractEnum2.X1' ENUM_CONSTRUCTOR_CALL 'private constructor <init> () [primary] declared in <root>.TestAbstractEnum2.X1'
@@ -156,7 +156,7 @@ interface IFoo {
} }
open enum class TestAbstractEnum2 : IFoo, Enum<TestAbstractEnum2> { abstract enum class TestAbstractEnum2 : IFoo, Enum<TestAbstractEnum2> {
private constructor() /* primary */ { private constructor() /* primary */ {
super/*Enum*/<TestAbstractEnum2>() super/*Enum*/<TestAbstractEnum2>()
/* <init>() */ /* <init>() */