[FIR] Implement deprecation for implementing var by inherited val

#KT-56779 Fixed
This commit is contained in:
Kirill Rakhman
2023-05-12 12:58:04 +02:00
committed by Space Team
parent 941446ea39
commit df03f0df0a
19 changed files with 303 additions and 19 deletions
@@ -2571,6 +2571,24 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
token,
)
}
add(FirErrors.VAR_IMPLEMENTED_BY_INHERITED_VAL.errorFactory) { firDiagnostic ->
VarImplementedByInheritedValErrorImpl(
firSymbolBuilder.classifierBuilder.buildClassLikeSymbol(firDiagnostic.a),
firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.b),
firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.c),
firDiagnostic as KtPsiDiagnostic,
token,
)
}
add(FirErrors.VAR_IMPLEMENTED_BY_INHERITED_VAL.warningFactory) { firDiagnostic ->
VarImplementedByInheritedValWarningImpl(
firSymbolBuilder.classifierBuilder.buildClassLikeSymbol(firDiagnostic.a),
firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.b),
firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.c),
firDiagnostic as KtPsiDiagnostic,
token,
)
}
add(FirErrors.NON_FINAL_MEMBER_IN_FINAL_CLASS) { firDiagnostic ->
NonFinalMemberInFinalClassImpl(
firDiagnostic as KtPsiDiagnostic,
@@ -1829,6 +1829,20 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
abstract val overriddenDeclaration: KtCallableSymbol
}
abstract class VarImplementedByInheritedValError : KtFirDiagnostic<KtNamedDeclaration>() {
override val diagnosticClass get() = VarImplementedByInheritedValError::class
abstract val classOrObject: KtClassLikeSymbol
abstract val overridingDeclaration: KtCallableSymbol
abstract val overriddenDeclaration: KtCallableSymbol
}
abstract class VarImplementedByInheritedValWarning : KtFirDiagnostic<KtNamedDeclaration>() {
override val diagnosticClass get() = VarImplementedByInheritedValWarning::class
abstract val classOrObject: KtClassLikeSymbol
abstract val overridingDeclaration: KtCallableSymbol
abstract val overriddenDeclaration: KtCallableSymbol
}
abstract class NonFinalMemberInFinalClass : KtFirDiagnostic<KtNamedDeclaration>() {
override val diagnosticClass get() = NonFinalMemberInFinalClass::class
}
@@ -2193,6 +2193,22 @@ internal class VarOverriddenByValImpl(
override val token: KtLifetimeToken,
) : KtFirDiagnostic.VarOverriddenByVal(), KtAbstractFirDiagnostic<KtNamedDeclaration>
internal class VarImplementedByInheritedValErrorImpl(
override val classOrObject: KtClassLikeSymbol,
override val overridingDeclaration: KtCallableSymbol,
override val overriddenDeclaration: KtCallableSymbol,
override val firDiagnostic: KtPsiDiagnostic,
override val token: KtLifetimeToken,
) : KtFirDiagnostic.VarImplementedByInheritedValError(), KtAbstractFirDiagnostic<KtNamedDeclaration>
internal class VarImplementedByInheritedValWarningImpl(
override val classOrObject: KtClassLikeSymbol,
override val overridingDeclaration: KtCallableSymbol,
override val overriddenDeclaration: KtCallableSymbol,
override val firDiagnostic: KtPsiDiagnostic,
override val token: KtLifetimeToken,
) : KtFirDiagnostic.VarImplementedByInheritedValWarning(), KtAbstractFirDiagnostic<KtNamedDeclaration>
internal class NonFinalMemberInFinalClassImpl(
override val firDiagnostic: KtPsiDiagnostic,
override val token: KtLifetimeToken,
@@ -23756,6 +23756,18 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia
runTest("compiler/testData/diagnostics/tests/override/ToAbstractMembersFromSuper-kt1996.kt");
}
@Test
@TestMetadata("varImplementedByInheritedVal.kt")
public void testVarImplementedByInheritedVal() throws Exception {
runTest("compiler/testData/diagnostics/tests/override/varImplementedByInheritedVal.kt");
}
@Test
@TestMetadata("varImplementedByInheritedValError.kt")
public void testVarImplementedByInheritedValError() throws Exception {
runTest("compiler/testData/diagnostics/tests/override/varImplementedByInheritedValError.kt");
}
@Nested
@TestMetadata("compiler/testData/diagnostics/tests/override/clashesOnInheritance")
@TestDataPath("$PROJECT_ROOT")
@@ -23756,6 +23756,18 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
runTest("compiler/testData/diagnostics/tests/override/ToAbstractMembersFromSuper-kt1996.kt");
}
@Test
@TestMetadata("varImplementedByInheritedVal.kt")
public void testVarImplementedByInheritedVal() throws Exception {
runTest("compiler/testData/diagnostics/tests/override/varImplementedByInheritedVal.kt");
}
@Test
@TestMetadata("varImplementedByInheritedValError.kt")
public void testVarImplementedByInheritedValError() throws Exception {
runTest("compiler/testData/diagnostics/tests/override/varImplementedByInheritedValError.kt");
}
@Nested
@TestMetadata("compiler/testData/diagnostics/tests/override/clashesOnInheritance")
@TestDataPath("$PROJECT_ROOT")
@@ -23756,6 +23756,18 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
runTest("compiler/testData/diagnostics/tests/override/ToAbstractMembersFromSuper-kt1996.kt");
}
@Test
@TestMetadata("varImplementedByInheritedVal.kt")
public void testVarImplementedByInheritedVal() throws Exception {
runTest("compiler/testData/diagnostics/tests/override/varImplementedByInheritedVal.kt");
}
@Test
@TestMetadata("varImplementedByInheritedValError.kt")
public void testVarImplementedByInheritedValError() throws Exception {
runTest("compiler/testData/diagnostics/tests/override/varImplementedByInheritedValError.kt");
}
@Nested
@TestMetadata("compiler/testData/diagnostics/tests/override/clashesOnInheritance")
@TestDataPath("$PROJECT_ROOT")
@@ -23762,6 +23762,18 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
runTest("compiler/testData/diagnostics/tests/override/ToAbstractMembersFromSuper-kt1996.kt");
}
@Test
@TestMetadata("varImplementedByInheritedVal.kt")
public void testVarImplementedByInheritedVal() throws Exception {
runTest("compiler/testData/diagnostics/tests/override/varImplementedByInheritedVal.kt");
}
@Test
@TestMetadata("varImplementedByInheritedValError.kt")
public void testVarImplementedByInheritedValError() throws Exception {
runTest("compiler/testData/diagnostics/tests/override/varImplementedByInheritedValError.kt");
}
@Nested
@TestMetadata("compiler/testData/diagnostics/tests/override/clashesOnInheritance")
@TestDataPath("$PROJECT_ROOT")
@@ -908,6 +908,14 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
parameter<FirCallableSymbol<*>>("overridingDeclaration")
parameter<FirCallableSymbol<*>>("overriddenDeclaration")
}
val VAR_IMPLEMENTED_BY_INHERITED_VAL by deprecationError<KtNamedDeclaration>(
LanguageFeature.ProhibitImplementingVarByInheritedVal,
PositioningStrategy.DECLARATION_NAME,
) {
parameter<FirClassSymbol<*>>("classOrObject")
parameter<FirCallableSymbol<*>>("overridingDeclaration")
parameter<FirCallableSymbol<*>>("overriddenDeclaration")
}
val NON_FINAL_MEMBER_IN_FINAL_CLASS by warning<KtNamedDeclaration>(PositioningStrategy.OPEN_MODIFIER)
val NON_FINAL_MEMBER_IN_OBJECT by warning<KtNamedDeclaration>(PositioningStrategy.OPEN_MODIFIER)
val VIRTUAL_MEMBER_HIDDEN by error<KtNamedDeclaration>(PositioningStrategy.DECLARATION_NAME) {
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.config.LanguageFeature.ModifierNonBuiltinSuspendFunE
import org.jetbrains.kotlin.config.LanguageFeature.ProhibitAssigningSingleElementsToVarargsInNamedForm
import org.jetbrains.kotlin.config.LanguageFeature.ProhibitConfusingSyntaxInWhenBranches
import org.jetbrains.kotlin.config.LanguageFeature.ProhibitCyclesInAnnotations
import org.jetbrains.kotlin.config.LanguageFeature.ProhibitImplementingVarByInheritedVal
import org.jetbrains.kotlin.config.LanguageFeature.ProhibitInvisibleAbstractMethodsInSuperclasses
import org.jetbrains.kotlin.config.LanguageFeature.ProhibitNonReifiedArraysAsReifiedTypeArguments
import org.jetbrains.kotlin.config.LanguageFeature.ProhibitUseSiteTargetAnnotationsOnSuperTypes
@@ -481,6 +482,7 @@ object FirErrors {
val PROPERTY_TYPE_MISMATCH_ON_OVERRIDE by error2<KtNamedDeclaration, FirCallableSymbol<*>, FirCallableSymbol<*>>(SourceElementPositioningStrategies.DECLARATION_RETURN_TYPE)
val VAR_TYPE_MISMATCH_ON_OVERRIDE by error2<KtNamedDeclaration, FirCallableSymbol<*>, FirCallableSymbol<*>>(SourceElementPositioningStrategies.DECLARATION_RETURN_TYPE)
val VAR_OVERRIDDEN_BY_VAL by error2<KtNamedDeclaration, FirCallableSymbol<*>, FirCallableSymbol<*>>(SourceElementPositioningStrategies.VAL_OR_VAR_NODE)
val VAR_IMPLEMENTED_BY_INHERITED_VAL by deprecationError3<KtNamedDeclaration, FirClassSymbol<*>, FirCallableSymbol<*>, FirCallableSymbol<*>>(ProhibitImplementingVarByInheritedVal, SourceElementPositioningStrategies.DECLARATION_NAME)
val NON_FINAL_MEMBER_IN_FINAL_CLASS by warning0<KtNamedDeclaration>(SourceElementPositioningStrategies.OPEN_MODIFIER)
val NON_FINAL_MEMBER_IN_OBJECT by warning0<KtNamedDeclaration>(SourceElementPositioningStrategies.OPEN_MODIFIER)
val VIRTUAL_MEMBER_HIDDEN by error2<KtNamedDeclaration, FirCallableSymbol<*>, FirRegularClassSymbol>(SourceElementPositioningStrategies.DECLARATION_NAME)
@@ -12,7 +12,9 @@ import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
import org.jetbrains.kotlin.diagnostics.*
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.isExpression
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.primaryConstructorSymbol
@@ -26,8 +28,11 @@ import org.jetbrains.kotlin.fir.references.FirSuperReference
import org.jetbrains.kotlin.fir.references.toResolvedCallableSymbol
import org.jetbrains.kotlin.fir.resolve.*
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
import org.jetbrains.kotlin.fir.scopes.*
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenFunctions
import org.jetbrains.kotlin.fir.scopes.impl.multipleDelegatesWithTheSameSignature
import org.jetbrains.kotlin.fir.scopes.overriddenFunctions
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
@@ -325,23 +330,48 @@ fun FirCallableSymbol<*>.getImplementationStatus(
if (containingClassSymbol === parentClassSymbol && symbol.subjectToManyNotImplemented(sessionHolder)) {
return ImplementationStatus.AMBIGUOUSLY_INHERITED
}
var hasAbstractFromClass = false
var hasInterfaceDelegation = false
var hasAbstractVar = false
var hasImplementation = false
var hasImplementationVar = false
for (intersection in symbol.intersections) {
@OptIn(SymbolInternals::class)
val fir = intersection.fir
val unwrappedFir = fir.unwrapFakeOverrides()
val isVar = unwrappedFir is FirProperty && unwrappedFir.isVar
val isFromClass = unwrappedFir.getContainingClassSymbol(sessionHolder.session)?.classKind == ClassKind.CLASS
if (fir.isAbstract) {
if (isFromClass) {
hasAbstractFromClass = true
}
if (isVar) {
hasAbstractVar = true
}
} else {
if (fir.origin == FirDeclarationOrigin.Delegated) {
hasInterfaceDelegation = true
}
if (isFromClass) {
hasImplementation = true
if (isVar) {
hasImplementationVar = true
}
}
}
}
// In Java 8, non-abstract intersection overrides having abstract symbol from base class
// still should be implemented in current class (even when they have default interface implementation)
if (symbol.intersections.any {
@OptIn(SymbolInternals::class)
val fir = it.fir.unwrapFakeOverrides()
fir.isAbstract && (fir.getContainingClassSymbol(sessionHolder.session) as? FirRegularClassSymbol)?.classKind == ClassKind.CLASS
}
) {
// Exception from the rule above: interface implementation via delegation
if (symbol.intersections.none {
@OptIn(SymbolInternals::class)
val fir = it.fir
fir.origin == FirDeclarationOrigin.Delegated && !fir.isAbstract
}
) {
return ImplementationStatus.NOT_IMPLEMENTED
}
// Exception to the rule above: interface implementation via delegation
if (hasAbstractFromClass && !hasInterfaceDelegation) {
return ImplementationStatus.NOT_IMPLEMENTED
}
if (hasAbstractVar && hasImplementation && !hasImplementationVar) {
return ImplementationStatus.VAR_IMPLEMENTED_BY_VAL
}
}
@@ -372,7 +402,6 @@ fun FirCallableSymbol<*>.getImplementationStatus(
}
}
private fun FirIntersectionCallableSymbol.subjectToManyNotImplemented(sessionHolder: SessionHolder): Boolean {
var nonAbstractCountInClass = 0
var nonAbstractCountInInterface = 0
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MANY_IMPL_MEMBER_
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.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.FirDeclarationOrigin
@@ -54,6 +55,7 @@ object FirNotImplementedOverrideChecker : FirClassChecker() {
val delegationOverrideOfFinal = mutableListOf<Pair<FirCallableSymbol<*>, FirCallableSymbol<*>>>()
val delegationOverrideOfOpen = mutableListOf<Pair<FirCallableSymbol<*>, FirCallableSymbol<*>>>()
val invisibleSymbols = mutableListOf<FirCallableSymbol<*>>()
val varsImplementedByInheritedVal = mutableListOf<FirIntersectionCallableSymbol>()
fun collectSymbol(symbol: FirCallableSymbol<*>) {
val delegatedWrapperData = symbol.delegatedWrapperData
@@ -99,7 +101,7 @@ object FirNotImplementedOverrideChecker : FirClassChecker() {
symbol.isVisibleInClass(classSymbol) -> notImplementedSymbols.add(symbol)
else -> invisibleSymbols.add(symbol)
}
ImplementationStatus.VAR_IMPLEMENTED_BY_VAL -> varsImplementedByInheritedVal.add(symbol as FirIntersectionCallableSymbol)
else -> {
// nothing to do
}
@@ -111,6 +113,17 @@ object FirNotImplementedOverrideChecker : FirClassChecker() {
classScope.processPropertiesByName(name, ::collectSymbol)
}
varsImplementedByInheritedVal.firstOrNull()?.let { symbol ->
val implementationVal = symbol.intersections.first { it is FirPropertySymbol && it.isVal && !it.isAbstract }
reporter.reportOn(
source,
VAR_IMPLEMENTED_BY_INHERITED_VAL,
classSymbol,
symbol as FirCallableSymbol<*>,
implementationVal,
context,
)
}
if (!canHaveAbstractDeclarations && notImplementedSymbols.isNotEmpty()) {
val notImplemented = (notImplementedSymbols.firstOrNull { !it.isFromInterfaceOrEnum(context) } ?: notImplementedSymbols.first())
.unwrapFakeOverrides()
@@ -606,6 +606,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VARIABLE_NEVER_RE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VARIABLE_WITH_NO_TYPE_NO_INITIALIZER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VARIANCE_ON_TYPE_PARAMETER_NOT_ALLOWED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAR_ANNOTATION_PARAMETER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAR_IMPLEMENTED_BY_INHERITED_VAL
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAR_OVERRIDDEN_BY_VAL
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAR_OVERRIDDEN_BY_VAL_BY_DELEGATION
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAR_TYPE_MISMATCH_ON_INHERITANCE
@@ -1461,6 +1462,13 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
FQ_NAMES_IN_TYPES,
FQ_NAMES_IN_TYPES
)
map.put(
VAR_IMPLEMENTED_BY_INHERITED_VAL,
"{0} implements var-property {1} by inherited val-property {2}",
RENDER_CLASS_OR_OBJECT,
DECLARATION_NAME,
FQ_NAMES_IN_TYPES
)
map.put(NON_FINAL_MEMBER_IN_FINAL_CLASS, "'open' has no effect in a final class")
map.put(NON_FINAL_MEMBER_IN_OBJECT, "'open' has no effect in an object")
map.put(
@@ -0,0 +1,28 @@
// LANGUAGE: -ProhibitImplementingVarByInheritedVal
interface IVal {
val a: String
}
interface IVar {
var a: String
}
interface IVarDefault {
var a: String
get() = ""
set(value) {}
}
open class CVal {
val a: String = "default"
}
open class CVar {
var a: String = "default"
}
<!MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED!>class C1<!> : IVar, IVarDefault
<!VAR_IMPLEMENTED_BY_INHERITED_VAL_WARNING!>class C2<!> : CVal(), IVar
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>class C3<!> : CVal(), IVarDefault
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>class C4<!> : CVal(), IVar, IVarDefault
class C5 : CVar(), IVar
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>class C6<!> : CVar(), IVarDefault
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>class C7<!> : CVar(), IVar, IVarDefault
<!VAR_OVERRIDDEN_BY_VAL_BY_DELEGATION!>class C8<!>(ival: IVal) : IVar, IVal by ival
@@ -0,0 +1,28 @@
// LANGUAGE: -ProhibitImplementingVarByInheritedVal
interface IVal {
val a: String
}
interface IVar {
var a: String
}
interface IVarDefault {
var a: String
get() = ""
set(value) {}
}
open class CVal {
val a: String = "default"
}
open class CVar {
var a: String = "default"
}
<!MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED!>class C1<!> : IVar, IVarDefault
class C2 : CVal(), IVar
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>class C3<!> : CVal(), IVarDefault
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>class C4<!> : CVal(), IVar, IVarDefault
class C5 : CVar(), IVar
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>class C6<!> : CVar(), IVarDefault
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>class C7<!> : CVar(), IVar, IVarDefault
<!VAR_OVERRIDDEN_BY_VAL_BY_DELEGATION!>class C8<!>(ival: IVal) : IVar, IVal by ival
@@ -0,0 +1,28 @@
// LANGUAGE: +ProhibitImplementingVarByInheritedVal
interface IVal {
val a: String
}
interface IVar {
var a: String
}
interface IVarDefault {
var a: String
get() = ""
set(value) {}
}
open class CVal {
val a: String = "default"
}
open class CVar {
var a: String = "default"
}
<!MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED!>class C1<!> : IVar, IVarDefault
<!VAR_IMPLEMENTED_BY_INHERITED_VAL_ERROR!>class C2<!> : CVal(), IVar
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>class C3<!> : CVal(), IVarDefault
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>class C4<!> : CVal(), IVar, IVarDefault
class C5 : CVar(), IVar
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>class C6<!> : CVar(), IVarDefault
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>class C7<!> : CVar(), IVar, IVarDefault
<!VAR_OVERRIDDEN_BY_VAL_BY_DELEGATION!>class C8<!>(ival: IVal) : IVar, IVal by ival
@@ -0,0 +1,28 @@
// LANGUAGE: +ProhibitImplementingVarByInheritedVal
interface IVal {
val a: String
}
interface IVar {
var a: String
}
interface IVarDefault {
var a: String
get() = ""
set(value) {}
}
open class CVal {
val a: String = "default"
}
open class CVar {
var a: String = "default"
}
<!MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED!>class C1<!> : IVar, IVarDefault
class C2 : CVal(), IVar
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>class C3<!> : CVal(), IVarDefault
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>class C4<!> : CVal(), IVar, IVarDefault
class C5 : CVar(), IVar
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>class C6<!> : CVar(), IVarDefault
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>class C7<!> : CVar(), IVar, IVarDefault
<!VAR_OVERRIDDEN_BY_VAL_BY_DELEGATION!>class C8<!>(ival: IVal) : IVar, IVal by ival
@@ -24534,6 +24534,18 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
runTest("compiler/testData/diagnostics/tests/override/ToAbstractMembersFromSuper-kt1996.kt");
}
@Test
@TestMetadata("varImplementedByInheritedVal.kt")
public void testVarImplementedByInheritedVal() throws Exception {
runTest("compiler/testData/diagnostics/tests/override/varImplementedByInheritedVal.kt");
}
@Test
@TestMetadata("varImplementedByInheritedValError.kt")
public void testVarImplementedByInheritedValError() throws Exception {
runTest("compiler/testData/diagnostics/tests/override/varImplementedByInheritedValError.kt");
}
@Nested
@TestMetadata("compiler/testData/diagnostics/tests/override/clashesOnInheritance")
@TestDataPath("$PROJECT_ROOT")
@@ -292,6 +292,7 @@ enum class LanguageFeature(
// 2.1
ReferencesToSyntheticJavaProperties(KOTLIN_2_1), // KT-8575
ProhibitImplementingVarByInheritedVal(KOTLIN_2_1, kind = BUG_FIX), // KT-56779
// End of 2.* language features --------------------------------------------------
@@ -10,6 +10,9 @@ enum class ImplementationStatus {
/** This symbol is not implemented and should be implemented if the class is not abstract. */
NOT_IMPLEMENTED,
/** This symbol is a var property but only has a val property as implementation */
VAR_IMPLEMENTED_BY_VAL,
/** The symbol is inheriting multiple non-abstract symbols and hence must be explicitly implemented. */
AMBIGUOUSLY_INHERITED,