From c98cd3b190ed92ad4cf5f121d36c35176bcc8acd Mon Sep 17 00:00:00 2001 From: Andrey Zinovyev Date: Fri, 11 Jun 2021 13:07:17 +0300 Subject: [PATCH] [FIR] Implement properties types mismatch on inheritence PROPERTY_TYPE_MISMATCH_ON_INHERITANCE, VAR_TYPE_MISMATCH_ON_INHERITANCE, PROPERTY_TYPE_MISMATCH_BY_DELEGATION --- .../diagnostics/FirDiagnosticsList.kt | 15 +++++ .../fir/analysis/diagnostics/FirErrors.kt | 3 + .../FirImplementationMismatchChecker.kt | 58 ++++++++++++++----- .../diagnostics/FirDefaultErrorMessages.kt | 24 ++++++++ .../scopes/impl/FirTypeIntersectionScope.kt | 6 +- .../clashes/propertyTypeMismatch.fir.kt | 14 ++--- .../clashes/returnTypeMismatch.fir.kt | 16 ++--- .../covariantOverrides/fromClass.fir.kt | 19 ------ .../covariantOverrides/fromClass.kt | 1 + .../covariantOverrides/irrelevant.fir.kt | 2 +- .../covariantOverrides/simple.fir.kt | 19 ------ .../delegation/covariantOverrides/simple.kt | 1 + .../clashesOnInheritance/kt13355.fir.kt | 13 ----- .../override/clashesOnInheritance/kt13355.kt | 1 + .../valTypeMismatch.fir.kt | 29 ---------- .../clashesOnInheritance/valTypeMismatch.kt | 1 + .../varTypeMismatch.fir.kt | 29 ---------- .../clashesOnInheritance/varTypeMismatch.kt | 1 + .../diagnostics/KtFirDataClassConverters.kt | 24 ++++++++ .../api/fir/diagnostics/KtFirDiagnostics.kt | 18 ++++++ .../fir/diagnostics/KtFirDiagnosticsImpl.kt | 27 +++++++++ 21 files changed, 179 insertions(+), 142 deletions(-) delete mode 100644 compiler/testData/diagnostics/tests/delegation/covariantOverrides/fromClass.fir.kt delete mode 100644 compiler/testData/diagnostics/tests/delegation/covariantOverrides/simple.fir.kt delete mode 100644 compiler/testData/diagnostics/tests/override/clashesOnInheritance/kt13355.fir.kt delete mode 100644 compiler/testData/diagnostics/tests/override/clashesOnInheritance/valTypeMismatch.fir.kt delete mode 100644 compiler/testData/diagnostics/tests/override/clashesOnInheritance/varTypeMismatch.fir.kt diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt index 413b0e1fc5e..de658286fca 100644 --- a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt @@ -592,11 +592,26 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") { parameter>("conflictingDeclaration2") } + val PROPERTY_TYPE_MISMATCH_ON_INHERITANCE by error(PositioningStrategy.DECLARATION_NAME) { + parameter>("conflictingDeclaration1") + parameter>("conflictingDeclaration2") + } + + val VAR_TYPE_MISMATCH_ON_INHERITANCE by error(PositioningStrategy.DECLARATION_NAME) { + parameter>("conflictingDeclaration1") + parameter>("conflictingDeclaration2") + } + val RETURN_TYPE_MISMATCH_BY_DELEGATION by error(PositioningStrategy.DECLARATION_NAME) { parameter>("delegateDeclaration") parameter>("baseDeclaration") } + val PROPERTY_TYPE_MISMATCH_BY_DELEGATION by error(PositioningStrategy.DECLARATION_NAME) { + parameter>("delegateDeclaration") + parameter>("baseDeclaration") + } + val ABSTRACT_MEMBER_NOT_IMPLEMENTED by error(PositioningStrategy.DECLARATION_NAME) { parameter("classOrObject") parameter("missingDeclaration") diff --git a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt index b7cf2b396e1..ce9de435345 100644 --- a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt +++ b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt @@ -348,7 +348,10 @@ object FirErrors { val CANNOT_CHANGE_ACCESS_PRIVILEGE by error3(SourceElementPositioningStrategies.VISIBILITY_MODIFIER) val OVERRIDING_FINAL_MEMBER by error2(SourceElementPositioningStrategies.OVERRIDE_MODIFIER) val RETURN_TYPE_MISMATCH_ON_INHERITANCE by error2, FirCallableDeclaration<*>>(SourceElementPositioningStrategies.DECLARATION_NAME) + val PROPERTY_TYPE_MISMATCH_ON_INHERITANCE by error2, FirCallableDeclaration<*>>(SourceElementPositioningStrategies.DECLARATION_NAME) + val VAR_TYPE_MISMATCH_ON_INHERITANCE by error2, FirCallableDeclaration<*>>(SourceElementPositioningStrategies.DECLARATION_NAME) val RETURN_TYPE_MISMATCH_BY_DELEGATION by error2, FirCallableDeclaration<*>>(SourceElementPositioningStrategies.DECLARATION_NAME) + val PROPERTY_TYPE_MISMATCH_BY_DELEGATION by error2, FirCallableDeclaration<*>>(SourceElementPositioningStrategies.DECLARATION_NAME) val ABSTRACT_MEMBER_NOT_IMPLEMENTED by error2(SourceElementPositioningStrategies.DECLARATION_NAME) val ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED by error2(SourceElementPositioningStrategies.DECLARATION_NAME) val INVISIBLE_ABSTRACT_MEMBER_FROM_SUPER by error2(SourceElementPositioningStrategies.DECLARATION_NAME) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirImplementationMismatchChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirImplementationMismatchChecker.kt index fead0001cc8..90fddf7fb9c 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirImplementationMismatchChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirImplementationMismatchChecker.kt @@ -19,6 +19,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirIntersectionCallableSymbol import org.jetbrains.kotlin.fir.typeContext import org.jetbrains.kotlin.fir.types.ConeKotlinErrorType +import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.types.AbstractTypeChecker @@ -39,6 +40,30 @@ object FirImplementationMismatchChecker : FirClassChecker() { val classScope = declaration.unsubstitutedScope(context) val dedupReporter = reporter.deduplicating() + fun reportTypeMismatch(member1: FirCallableDeclaration<*>, member2: FirCallableDeclaration<*>, isDelegation: Boolean) { + val error = if (member1 is FirProperty && member2 is FirProperty) { + if (member1.isVar || member2.isVar) { + FirErrors.VAR_TYPE_MISMATCH_ON_INHERITANCE + } else { + if (isDelegation) FirErrors.PROPERTY_TYPE_MISMATCH_BY_DELEGATION + else FirErrors.PROPERTY_TYPE_MISMATCH_ON_INHERITANCE + } + } else { + if (isDelegation) FirErrors.RETURN_TYPE_MISMATCH_BY_DELEGATION + else FirErrors.RETURN_TYPE_MISMATCH_ON_INHERITANCE + } + dedupReporter.reportOn(source, error, member1, member2, context) + } + + fun canOverride( + baseMember: FirCallableDeclaration<*>, + inheritedType: ConeKotlinType, + baseType: ConeKotlinType + ): Boolean = + if (baseMember is FirProperty && baseMember.isVar) AbstractTypeChecker.equalTypes(typeCheckerContext, inheritedType, baseType) + else AbstractTypeChecker.isSubtypeOf(typeCheckerContext, inheritedType, baseType) + + fun checkSymbol(symbol: FirCallableSymbol<*>) { if (symbol.callableId.classId != declaration.classId) return if (symbol !is FirIntersectionCallableSymbol) return @@ -62,37 +87,38 @@ object FirImplementationMismatchChecker : FirClassChecker() { } } - if (delegation != null || implementations.isNotEmpty()) { - //if there are more than one implementation we report nothing because it will be reported differently - val method = delegation ?: implementations.singleOrNull() ?: return - val methodType = context.returnTypeCalculator.tryCalculateReturnType(method).coneType - val (conflict, _) = withTypes.find { (_, type) -> - !AbstractTypeChecker.isSubtypeOf(typeCheckerContext, methodType, type) - } ?: return - val error = - if (delegation != null) FirErrors.RETURN_TYPE_MISMATCH_BY_DELEGATION - else FirErrors.RETURN_TYPE_MISMATCH_ON_INHERITANCE - dedupReporter.reportOn(source, error, method, conflict, context) - } else { - //if there is no implementation, check that there can be any type compatible (subtype of) with all + run { var clash: Pair, FirCallableDeclaration<*>>? = null val compatible = withTypes.any { (m1, type1) -> withTypes.all { (m2, type2) -> - val result = AbstractTypeChecker.isSubtypeOf(typeCheckerContext, type1, type2) - if (!result && clash == null && !AbstractTypeChecker.isSubtypeOf(typeCheckerContext, type2, type1)) { + val result = canOverride(m2, type1, type2) + if (!result && clash == null && !canOverride(m1, type2, type1)) { clash = m1 to m2 } result } } clash?.takeIf { !compatible }?.let { (m1, m2) -> - dedupReporter.reportOn(source, FirErrors.RETURN_TYPE_MISMATCH_ON_INHERITANCE, m1, m2, context) + reportTypeMismatch(m1, m2, false) + return@checkSymbol } } + + if (delegation != null || implementations.isNotEmpty()) { + //if there are more than one implementation we report nothing because it will be reported differently + val implementationMember = delegation ?: implementations.singleOrNull() ?: return + val methodType = context.returnTypeCalculator.tryCalculateReturnType(implementationMember).coneType + val (conflict, _) = withTypes.find { (baseMember, baseType) -> + !canOverride(baseMember, methodType, baseType) + } ?: return + + reportTypeMismatch(implementationMember, conflict, delegation != null) + } } for (name in classScope.getCallableNames()) { classScope.processFunctionsByName(name, ::checkSymbol) + classScope.processPropertiesByName(name, ::checkSymbol) } } } \ No newline at end of file diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt index be94a601e81..dc8ee5e71e1 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt @@ -267,6 +267,8 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PROJECTION_IN_IMM import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PROPERTY_INITIALIZER_IN_INTERFACE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PROPERTY_INITIALIZER_NO_BACKING_FIELD +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PROPERTY_TYPE_MISMATCH_BY_DELEGATION +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PROPERTY_TYPE_MISMATCH_ON_INHERITANCE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PROPERTY_TYPE_MISMATCH_ON_OVERRIDE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PROPERTY_WITH_BACKING_FIELD_INSIDE_INLINE_CLASS import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PROPERTY_WITH_NO_TYPE_NO_INITIALIZER @@ -384,6 +386,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VARIABLE_NEVER_RE 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_OVERRIDDEN_BY_VAL +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAR_TYPE_MISMATCH_ON_INHERITANCE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAR_TYPE_MISMATCH_ON_OVERRIDE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VIRTUAL_MEMBER_HIDDEN import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_ANNOTATION_TARGET @@ -944,6 +947,20 @@ class FirDefaultErrorMessages { NAME ) + map.put( + PROPERTY_TYPE_MISMATCH_ON_INHERITANCE, + "''{0}'' clashes with ''{1}'': property types are incompatible", + NAME, + NAME + ) + + map.put( + VAR_TYPE_MISMATCH_ON_INHERITANCE, + "''{0}'' clashes with ''{1}'': property types do not match", + NAME, + NAME + ) + map.put( RETURN_TYPE_MISMATCH_BY_DELEGATION, "Type of ''{0}'' is not a subtype of overridden by delegation ''{1}''", @@ -951,6 +968,13 @@ class FirDefaultErrorMessages { NAME ) + map.put( + PROPERTY_TYPE_MISMATCH_BY_DELEGATION, + "Type of property ''{0}'' is not a subtype of overridden by delegation ''{1}''", + NAME, + NAME + ) + // Redeclarations map.put(MANY_COMPANION_OBJECTS, "Only one companion object is allowed per class") map.put(CONFLICTING_OVERLOADS, "Conflicting overloads: {0}", SYMBOLS) // * diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirTypeIntersectionScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirTypeIntersectionScope.kt index 4027e179822..298a6874202 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirTypeIntersectionScope.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirTypeIntersectionScope.kt @@ -345,7 +345,11 @@ class FirTypeIntersectionScope private constructor( newModality: Modality?, newVisibility: Visibility, ): FirPropertySymbol { - val newSymbol = FirIntersectionOverridePropertySymbol(mostSpecific.callableId, overrides) + val callableId = CallableId( + dispatchReceiverType.classId ?: mostSpecific.dispatchReceiverClassOrNull()?.classId!!, + mostSpecific.fir.name + ) + val newSymbol = FirIntersectionOverridePropertySymbol(callableId, overrides) val mostSpecificProperty = mostSpecific.fir FirFakeOverrideGenerator.createCopyForFirProperty( newSymbol, mostSpecificProperty, session, FirDeclarationOrigin.IntersectionOverride, diff --git a/compiler/testData/diagnostics/tests/delegation/clashes/propertyTypeMismatch.fir.kt b/compiler/testData/diagnostics/tests/delegation/clashes/propertyTypeMismatch.fir.kt index e3f5a382dc4..86c121cf674 100644 --- a/compiler/testData/diagnostics/tests/delegation/clashes/propertyTypeMismatch.fir.kt +++ b/compiler/testData/diagnostics/tests/delegation/clashes/propertyTypeMismatch.fir.kt @@ -30,28 +30,28 @@ class CGeneric : IGeneric { override val foo: T get() = null!! } -abstract class Test1 : IStr by CStr(), IInt +abstract class Test1 : IStr by CStr(), IInt -abstract class Test2 : IStr, IInt by CInt() +abstract class Test2 : IStr, IInt by CInt() -abstract class Test3 : IStr by CStr(), IInt by CInt() +abstract class Test3 : IStr by CStr(), IInt by CInt() abstract class Test4 : IStr by CStr(), IGeneric abstract class Test5 : IStr by CStr(), IGeneric -abstract class Test6 : IStr by CStr(), IGeneric +abstract class Test6 : IStr by CStr(), IGeneric abstract class Test7 : IGeneric by CGeneric(), IStr -abstract class Test8 : IGeneric by CGeneric(), IInt +abstract class Test8 : IGeneric by CGeneric(), IInt // Can't test right now due to https://youtrack.jetbrains.com/issue/KT-10258 // abstract class Test9 : IGeneric by CGeneric(), IGeneric -abstract class Test10 : IInt by CInt(), IStr by CStr(), IAny by CAny() +abstract class Test10 : IInt by CInt(), IStr by CStr(), IAny by CAny() abstract class Test11 : IInt, IStr by CStr(), IAny by CAny() -abstract class Test12 : IInt, IStr, IAny by CAny() +abstract class Test12 : IInt, IStr, IAny by CAny() diff --git a/compiler/testData/diagnostics/tests/delegation/clashes/returnTypeMismatch.fir.kt b/compiler/testData/diagnostics/tests/delegation/clashes/returnTypeMismatch.fir.kt index 9f0da27c818..bc69e355a11 100644 --- a/compiler/testData/diagnostics/tests/delegation/clashes/returnTypeMismatch.fir.kt +++ b/compiler/testData/diagnostics/tests/delegation/clashes/returnTypeMismatch.fir.kt @@ -32,28 +32,28 @@ class CGeneric : IGeneric { } } -abstract class Test1 : IStr by CStr(), IInt +abstract class Test1 : IStr by CStr(), IInt -abstract class Test2 : IStr, IInt by CInt() +abstract class Test2 : IStr, IInt by CInt() -abstract class Test3 : IStr by CStr(), IInt by CInt() +abstract class Test3 : IStr by CStr(), IInt by CInt() abstract class Test4 : IStr by CStr(), IGeneric abstract class Test5 : IStr by CStr(), IGeneric -abstract class Test6 : IStr by CStr(), IGeneric +abstract class Test6 : IStr by CStr(), IGeneric abstract class Test7 : IGeneric by CGeneric(), IStr -abstract class Test8 : IGeneric by CGeneric(), IInt +abstract class Test8 : IGeneric by CGeneric(), IInt // Can't test due to https://youtrack.jetbrains.com/issue/KT-10258 // abstract class Test9 : IGeneric by CGeneric(), IGeneric -abstract class Test10 : IInt by CInt(), IStr by CStr(), IAny by CAny() +abstract class Test10 : IInt by CInt(), IStr by CStr(), IAny by CAny() -abstract class Test11 : IInt, IStr by CStr(), IAny by CAny() +abstract class Test11 : IInt, IStr by CStr(), IAny by CAny() -abstract class Test12 : IInt, IStr, IAny by CAny() +abstract class Test12 : IInt, IStr, IAny by CAny() diff --git a/compiler/testData/diagnostics/tests/delegation/covariantOverrides/fromClass.fir.kt b/compiler/testData/diagnostics/tests/delegation/covariantOverrides/fromClass.fir.kt deleted file mode 100644 index feedc7d930e..00000000000 --- a/compiler/testData/diagnostics/tests/delegation/covariantOverrides/fromClass.fir.kt +++ /dev/null @@ -1,19 +0,0 @@ -interface IBase1 { - fun foo(): Any -} - -open class IDerived1 : IBase1 { - override fun foo(): String = "1" -} - -class Broken1(val b: IBase1) : IBase1 by b, IDerived1() - -interface IBase2 { - val foo: Any -} - -open class IDerived2 : IBase2 { - override val foo: String = "2" -} - -class Broken2(val b: IBase2) : IBase2 by b, IDerived2() diff --git a/compiler/testData/diagnostics/tests/delegation/covariantOverrides/fromClass.kt b/compiler/testData/diagnostics/tests/delegation/covariantOverrides/fromClass.kt index ddaaec96f72..0a302ceb0d2 100644 --- a/compiler/testData/diagnostics/tests/delegation/covariantOverrides/fromClass.kt +++ b/compiler/testData/diagnostics/tests/delegation/covariantOverrides/fromClass.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL interface IBase1 { fun foo(): Any } diff --git a/compiler/testData/diagnostics/tests/delegation/covariantOverrides/irrelevant.fir.kt b/compiler/testData/diagnostics/tests/delegation/covariantOverrides/irrelevant.fir.kt index 02972f61725..981e36d5e2a 100644 --- a/compiler/testData/diagnostics/tests/delegation/covariantOverrides/irrelevant.fir.kt +++ b/compiler/testData/diagnostics/tests/delegation/covariantOverrides/irrelevant.fir.kt @@ -16,4 +16,4 @@ interface IDerived2 { val foo: String } -class Broken2(val b: IBase2) : IBase2 by b, IDerived2 +class Broken2(val b: IBase2) : IBase2 by b, IDerived2 diff --git a/compiler/testData/diagnostics/tests/delegation/covariantOverrides/simple.fir.kt b/compiler/testData/diagnostics/tests/delegation/covariantOverrides/simple.fir.kt deleted file mode 100644 index a4b93100dcf..00000000000 --- a/compiler/testData/diagnostics/tests/delegation/covariantOverrides/simple.fir.kt +++ /dev/null @@ -1,19 +0,0 @@ -interface IBase1 { - fun foo(): Any -} - -interface IDerived1 : IBase1 { - override fun foo(): String -} - -class Broken1(val b: IBase1) : IBase1 by b, IDerived1 - -interface IBase2 { - val foo: Any -} - -interface IDerived2 : IBase2 { - override val foo: String -} - -class Broken2(val b: IBase2) : IBase2 by b, IDerived2 diff --git a/compiler/testData/diagnostics/tests/delegation/covariantOverrides/simple.kt b/compiler/testData/diagnostics/tests/delegation/covariantOverrides/simple.kt index ef16b6cc8fa..f8754471299 100644 --- a/compiler/testData/diagnostics/tests/delegation/covariantOverrides/simple.kt +++ b/compiler/testData/diagnostics/tests/delegation/covariantOverrides/simple.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL interface IBase1 { fun foo(): Any } diff --git a/compiler/testData/diagnostics/tests/override/clashesOnInheritance/kt13355.fir.kt b/compiler/testData/diagnostics/tests/override/clashesOnInheritance/kt13355.fir.kt deleted file mode 100644 index 7d3db4e4f22..00000000000 --- a/compiler/testData/diagnostics/tests/override/clashesOnInheritance/kt13355.fir.kt +++ /dev/null @@ -1,13 +0,0 @@ -interface IFooAny { - val foo: Any -} - -interface IFooStr : IFooAny { - override val foo: String -} - -abstract class BaseAny(override val foo: Any): IFooAny - -abstract class BaseStr : BaseAny(42), IFooStr - -class C : BaseStr() \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/override/clashesOnInheritance/kt13355.kt b/compiler/testData/diagnostics/tests/override/clashesOnInheritance/kt13355.kt index a8d15e0936d..903f65ac988 100644 --- a/compiler/testData/diagnostics/tests/override/clashesOnInheritance/kt13355.kt +++ b/compiler/testData/diagnostics/tests/override/clashesOnInheritance/kt13355.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL interface IFooAny { val foo: Any } diff --git a/compiler/testData/diagnostics/tests/override/clashesOnInheritance/valTypeMismatch.fir.kt b/compiler/testData/diagnostics/tests/override/clashesOnInheritance/valTypeMismatch.fir.kt deleted file mode 100644 index a46c47515ab..00000000000 --- a/compiler/testData/diagnostics/tests/override/clashesOnInheritance/valTypeMismatch.fir.kt +++ /dev/null @@ -1,29 +0,0 @@ -open class A { - open val foo: Boolean = true -} - -interface IA { - val foo: String -} - -interface IAA { - val foo: Int -} - -interface IGA { - val foo: T -} - -class B1: A(), IA - -class B2: A(), IA, IAA - -abstract class B3: IA, IAA - -class BS1: A(), IGA - -class BS2: A(), IGA - -class BS3: A(), IGA - -class BG1: A(), IGA diff --git a/compiler/testData/diagnostics/tests/override/clashesOnInheritance/valTypeMismatch.kt b/compiler/testData/diagnostics/tests/override/clashesOnInheritance/valTypeMismatch.kt index 35a34215757..74d6bcabb59 100644 --- a/compiler/testData/diagnostics/tests/override/clashesOnInheritance/valTypeMismatch.kt +++ b/compiler/testData/diagnostics/tests/override/clashesOnInheritance/valTypeMismatch.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL open class A { open val foo: Boolean = true } diff --git a/compiler/testData/diagnostics/tests/override/clashesOnInheritance/varTypeMismatch.fir.kt b/compiler/testData/diagnostics/tests/override/clashesOnInheritance/varTypeMismatch.fir.kt deleted file mode 100644 index 81f5a80065e..00000000000 --- a/compiler/testData/diagnostics/tests/override/clashesOnInheritance/varTypeMismatch.fir.kt +++ /dev/null @@ -1,29 +0,0 @@ -open class A { - open var foo: Boolean = true -} - -interface IA { - var foo: String -} - -interface IAA { - var foo: Int -} - -interface IGA { - var foo: T -} - -class B1: A(), IA - -class B2: A(), IA, IAA - -abstract class B3: IA, IAA - -class BS1: A(), IGA - -class BS2: A(), IGA - -class BS3: A(), IGA - -class BG1: A(), IGA diff --git a/compiler/testData/diagnostics/tests/override/clashesOnInheritance/varTypeMismatch.kt b/compiler/testData/diagnostics/tests/override/clashesOnInheritance/varTypeMismatch.kt index 6b3b1c5bcaa..a1b9b259f2c 100644 --- a/compiler/testData/diagnostics/tests/override/clashesOnInheritance/varTypeMismatch.kt +++ b/compiler/testData/diagnostics/tests/override/clashesOnInheritance/varTypeMismatch.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL open class A { open var foo: Boolean = true } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt index d348e5ca291..57e86d87350 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt @@ -1660,6 +1660,22 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert token, ) } + add(FirErrors.PROPERTY_TYPE_MISMATCH_ON_INHERITANCE) { firDiagnostic -> + PropertyTypeMismatchOnInheritanceImpl( + firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a as FirCallableDeclaration), + firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.b as FirCallableDeclaration), + firDiagnostic as FirPsiDiagnostic<*>, + token, + ) + } + add(FirErrors.VAR_TYPE_MISMATCH_ON_INHERITANCE) { firDiagnostic -> + VarTypeMismatchOnInheritanceImpl( + firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a as FirCallableDeclaration), + firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.b as FirCallableDeclaration), + firDiagnostic as FirPsiDiagnostic<*>, + token, + ) + } add(FirErrors.RETURN_TYPE_MISMATCH_BY_DELEGATION) { firDiagnostic -> ReturnTypeMismatchByDelegationImpl( firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a as FirCallableDeclaration), @@ -1668,6 +1684,14 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert token, ) } + add(FirErrors.PROPERTY_TYPE_MISMATCH_BY_DELEGATION) { firDiagnostic -> + PropertyTypeMismatchByDelegationImpl( + firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a as FirCallableDeclaration), + firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.b as FirCallableDeclaration), + firDiagnostic as FirPsiDiagnostic<*>, + token, + ) + } add(FirErrors.ABSTRACT_MEMBER_NOT_IMPLEMENTED) { firDiagnostic -> AbstractMemberNotImplementedImpl( firSymbolBuilder.classifierBuilder.buildClassLikeSymbol(firDiagnostic.a), diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt index 7e48c8e6baa..b53fea508bf 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt @@ -1177,12 +1177,30 @@ sealed class KtFirDiagnostic : KtDiagnosticWithPsi { abstract val conflictingDeclaration2: KtCallableSymbol } + abstract class PropertyTypeMismatchOnInheritance : KtFirDiagnostic() { + override val diagnosticClass get() = PropertyTypeMismatchOnInheritance::class + abstract val conflictingDeclaration1: KtCallableSymbol + abstract val conflictingDeclaration2: KtCallableSymbol + } + + abstract class VarTypeMismatchOnInheritance : KtFirDiagnostic() { + override val diagnosticClass get() = VarTypeMismatchOnInheritance::class + abstract val conflictingDeclaration1: KtCallableSymbol + abstract val conflictingDeclaration2: KtCallableSymbol + } + abstract class ReturnTypeMismatchByDelegation : KtFirDiagnostic() { override val diagnosticClass get() = ReturnTypeMismatchByDelegation::class abstract val delegateDeclaration: KtCallableSymbol abstract val baseDeclaration: KtCallableSymbol } + abstract class PropertyTypeMismatchByDelegation : KtFirDiagnostic() { + override val diagnosticClass get() = PropertyTypeMismatchByDelegation::class + abstract val delegateDeclaration: KtCallableSymbol + abstract val baseDeclaration: KtCallableSymbol + } + abstract class AbstractMemberNotImplemented : KtFirDiagnostic() { override val diagnosticClass get() = AbstractMemberNotImplemented::class abstract val classOrObject: KtClassLikeSymbol diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt index 8fb1b2d0739..b96d76cfbe2 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt @@ -1892,6 +1892,24 @@ internal class ReturnTypeMismatchOnInheritanceImpl( override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic) } +internal class PropertyTypeMismatchOnInheritanceImpl( + override val conflictingDeclaration1: KtCallableSymbol, + override val conflictingDeclaration2: KtCallableSymbol, + firDiagnostic: FirPsiDiagnostic<*>, + override val token: ValidityToken, +) : KtFirDiagnostic.PropertyTypeMismatchOnInheritance(), KtAbstractFirDiagnostic { + override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic) +} + +internal class VarTypeMismatchOnInheritanceImpl( + override val conflictingDeclaration1: KtCallableSymbol, + override val conflictingDeclaration2: KtCallableSymbol, + firDiagnostic: FirPsiDiagnostic<*>, + override val token: ValidityToken, +) : KtFirDiagnostic.VarTypeMismatchOnInheritance(), KtAbstractFirDiagnostic { + override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic) +} + internal class ReturnTypeMismatchByDelegationImpl( override val delegateDeclaration: KtCallableSymbol, override val baseDeclaration: KtCallableSymbol, @@ -1901,6 +1919,15 @@ internal class ReturnTypeMismatchByDelegationImpl( override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic) } +internal class PropertyTypeMismatchByDelegationImpl( + override val delegateDeclaration: KtCallableSymbol, + override val baseDeclaration: KtCallableSymbol, + firDiagnostic: FirPsiDiagnostic<*>, + override val token: ValidityToken, +) : KtFirDiagnostic.PropertyTypeMismatchByDelegation(), KtAbstractFirDiagnostic { + override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic) +} + internal class AbstractMemberNotImplementedImpl( override val classOrObject: KtClassLikeSymbol, override val missingDeclaration: KtCallableSymbol,