[FIR] Report ABSTRACT_MEMBER_NOT_IMPLEMENTED_BY_ENUM_ENTRY on enum entries with initializer
#KT-59577 Fixed
This commit is contained in:
committed by
Space Team
parent
ef78d4b95a
commit
44a4498ee5
@@ -0,0 +1,3 @@
|
||||
/enum.kt:(506,508): error: 'static enum entry E2: EnumClass = object : EnumClass' does not implement abstract members: [fun foo(): Int, val bar: String].
|
||||
|
||||
/enum.kt:(524,526): error: 'static enum entry E3: EnumClass = object : EnumClass' does not implement abstract members: [fun foo(): Int, val bar: String].
|
||||
+3
-2
@@ -1,3 +1,4 @@
|
||||
// RENDER_DIAGNOSTICS_FULL_TEXT
|
||||
interface Some
|
||||
|
||||
object O1 : Some
|
||||
@@ -26,11 +27,11 @@ enum class EnumClass {
|
||||
override val bar: String = "a"
|
||||
},
|
||||
|
||||
<!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>E2<!> {
|
||||
<!ABSTRACT_MEMBER_NOT_IMPLEMENTED_BY_ENUM_ENTRY!>E2<!> {
|
||||
|
||||
},
|
||||
|
||||
<!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>E3<!>();
|
||||
<!ABSTRACT_MEMBER_NOT_IMPLEMENTED_BY_ENUM_ENTRY!>E3<!>();
|
||||
|
||||
abstract fun foo(): Int
|
||||
abstract val bar: String
|
||||
|
||||
+27
-1
@@ -18,13 +18,17 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INVISIBLE_ABSTRAC
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MANY_IMPL_MEMBER_NOT_IMPLEMENTED
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OVERRIDING_FINAL_MEMBER_BY_DELEGATION
|
||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ABSTRACT_MEMBER_NOT_IMPLEMENTED_BY_ENUM_ENTRY
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAR_IMPLEMENTED_BY_INHERITED_VAL
|
||||
import org.jetbrains.kotlin.fir.containingClassLookupTag
|
||||
import org.jetbrains.kotlin.fir.declarations.FirClass
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
||||
import org.jetbrains.kotlin.fir.declarations.FirEnumEntry
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.*
|
||||
import org.jetbrains.kotlin.fir.delegatedWrapperData
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnonymousObjectExpression
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.scopes.MemberWithBaseScope
|
||||
import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenMembersWithBaseScope
|
||||
@@ -32,6 +36,8 @@ import org.jetbrains.kotlin.fir.scopes.impl.*
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.unwrapFakeOverrides
|
||||
import org.jetbrains.kotlin.util.ImplementationStatus
|
||||
import kotlin.contracts.ExperimentalContracts
|
||||
import kotlin.contracts.contract
|
||||
|
||||
object FirNotImplementedOverrideChecker : FirClassChecker() {
|
||||
|
||||
@@ -126,7 +132,18 @@ object FirNotImplementedOverrideChecker : FirClassChecker() {
|
||||
val notImplemented = (notImplementedSymbols.firstOrNull { !it.isFromInterfaceOrEnum(context) } ?: notImplementedSymbols.first())
|
||||
.unwrapFakeOverrides()
|
||||
if (notImplemented.isFromInterfaceOrEnum(context)) {
|
||||
reporter.reportOn(source, ABSTRACT_MEMBER_NOT_IMPLEMENTED, classSymbol, notImplemented, context)
|
||||
val containingDeclaration = context.containingDeclarations.lastOrNull()
|
||||
if (declaration.isInitializerOfEnumEntry(containingDeclaration)) {
|
||||
reporter.reportOn(
|
||||
source,
|
||||
ABSTRACT_MEMBER_NOT_IMPLEMENTED_BY_ENUM_ENTRY,
|
||||
containingDeclaration.symbol,
|
||||
notImplementedSymbols,
|
||||
context
|
||||
)
|
||||
} else {
|
||||
reporter.reportOn(source, ABSTRACT_MEMBER_NOT_IMPLEMENTED, classSymbol, notImplemented, context)
|
||||
}
|
||||
} else {
|
||||
reporter.reportOn(source, ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED, classSymbol, notImplemented, context)
|
||||
}
|
||||
@@ -183,6 +200,15 @@ object FirNotImplementedOverrideChecker : FirClassChecker() {
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalContracts::class)
|
||||
private fun FirClass.isInitializerOfEnumEntry(containingDeclaration: FirDeclaration?): Boolean {
|
||||
contract {
|
||||
returns(true) implies (containingDeclaration is FirEnumEntry)
|
||||
}
|
||||
return containingDeclaration is FirEnumEntry &&
|
||||
containingDeclaration.initializer.let { it is FirAnonymousObjectExpression && it.anonymousObject == this }
|
||||
}
|
||||
|
||||
private fun FirCallableSymbol<*>.isFromInterfaceOrEnum(context: CheckerContext): Boolean =
|
||||
(getContainingClassSymbol(context.session) as? FirRegularClassSymbol)?.let { it.isInterface || it.isEnumClass } == true
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
enum class EnumClass {
|
||||
E1 {
|
||||
override fun foo() = 1
|
||||
override val bar: String = "a"
|
||||
},
|
||||
|
||||
<!ABSTRACT_MEMBER_NOT_IMPLEMENTED_BY_ENUM_ENTRY!>E2<!> {
|
||||
|
||||
};
|
||||
|
||||
abstract fun foo(): Int
|
||||
abstract val bar: String
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
// FIR_IDENTICAL
|
||||
enum class EnumClass {
|
||||
E1 {
|
||||
override fun foo() = 1
|
||||
|
||||
Reference in New Issue
Block a user