[FIR] Implement deprecation for implementing var by inherited val
#KT-56779 Fixed
This commit is contained in:
committed by
Space Team
parent
941446ea39
commit
df03f0df0a
+18
@@ -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,
|
||||
|
||||
+14
@@ -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
|
||||
}
|
||||
|
||||
+16
@@ -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,
|
||||
|
||||
+12
@@ -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")
|
||||
|
||||
+12
@@ -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")
|
||||
|
||||
+12
@@ -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")
|
||||
|
||||
+12
@@ -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")
|
||||
|
||||
+8
@@ -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)
|
||||
|
||||
+47
-18
@@ -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
|
||||
|
||||
+14
-1
@@ -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()
|
||||
|
||||
+8
@@ -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(
|
||||
|
||||
+28
@@ -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
|
||||
+28
@@ -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
|
||||
+28
@@ -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
|
||||
Generated
+12
@@ -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,
|
||||
|
||||
|
||||
Reference in New Issue
Block a user