FIR2IR: make enum with abstract members from interfaces abstract
Related to KT-55828
This commit is contained in:
+29
-4
@@ -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 {
|
||||||
|
|||||||
-2
@@ -1,5 +1,3 @@
|
|||||||
// KT-55828
|
|
||||||
// IGNORE_BACKEND_K2: NATIVE
|
|
||||||
interface IFoo {
|
interface IFoo {
|
||||||
fun foo(): String
|
fun foo(): String
|
||||||
}
|
}
|
||||||
|
|||||||
-2
@@ -1,5 +1,3 @@
|
|||||||
// KT-55828
|
|
||||||
// IGNORE_BACKEND_K2: NATIVE
|
|
||||||
interface IFoo {
|
interface IFoo {
|
||||||
fun foo(): String
|
fun foo(): String
|
||||||
}
|
}
|
||||||
|
|||||||
-2
@@ -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>() */
|
||||||
|
|||||||
Reference in New Issue
Block a user