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 31f7207f566..ab49f0f1c37 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 @@ -587,6 +587,12 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") { parameter("containingClassName") } + val RETURN_TYPE_MISMATCH_ON_INHERITANCE by error(PositioningStrategy.DECLARATION_NAME) { + parameter>("classOrObject") + parameter>("conflictingDeclaration1") + parameter>("conflictingDeclaration2") + } + 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 73d3f84fe4f..72f1fd218b4 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 @@ -347,6 +347,7 @@ object FirErrors { val CANNOT_WEAKEN_ACCESS_PRIVILEGE by error3(SourceElementPositioningStrategies.VISIBILITY_MODIFIER) 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 error3, FirCallableDeclaration<*>, 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/CommonDeclarationCheckers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt index 1cdfbf871b0..21fa5255e5b 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt @@ -66,6 +66,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() { FirSealedSupertypeChecker, FirMemberFunctionsChecker, FirMemberPropertiesChecker, + FirImplementationMismatchChecker, ) override val regularClassCheckers: Set 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 new file mode 100644 index 00000000000..09ac61f78c5 --- /dev/null +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirImplementationMismatchChecker.kt @@ -0,0 +1,96 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.analysis.checkers.declaration + +import org.jetbrains.kotlin.descriptors.ClassKind +import org.jetbrains.kotlin.fir.FirFakeSourceElementKind +import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext +import org.jetbrains.kotlin.fir.analysis.checkers.unsubstitutedScope +import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.impl.deduplicating +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn +import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.scopes.impl.delegatedWrapperData +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.coneType +import org.jetbrains.kotlin.types.AbstractTypeChecker + +object FirImplementationMismatchChecker : FirClassChecker() { + + override fun check(declaration: FirClass<*>, context: CheckerContext, reporter: DiagnosticReporter) { + val source = declaration.source ?: return + val sourceKind = source.kind + if (sourceKind is FirFakeSourceElementKind && sourceKind != FirFakeSourceElementKind.EnumInitializer) return + if (declaration is FirRegularClass && declaration.isExpect) return + val classKind = declaration.classKind + if (classKind == ClassKind.ANNOTATION_CLASS || classKind == ClassKind.ENUM_CLASS) return + + val typeCheckerContext = context.session.typeContext.newBaseTypeCheckerContext( + errorTypesEqualToAnything = false, + stubTypesEqualToAnything = false + ) + val classScope = declaration.unsubstitutedScope(context) + val dedupReporter = reporter.deduplicating() + + fun checkSymbol(symbol: FirCallableSymbol<*>) { + if (symbol.callableId.classId != declaration.classId) return + if (symbol !is FirIntersectionCallableSymbol) return + val withTypes = symbol.intersections.map { + it.fir to context.returnTypeCalculator.tryCalculateReturnType(it.fir).coneType + } + + if (withTypes.any { it.second is ConeKotlinErrorType }) return + + var delegation: FirCallableDeclaration<*>? = null + val implementations = mutableListOf>() + + for (intSymbol in symbol.intersections) { + val fir = intSymbol.fir + if (fir.delegatedWrapperData?.containingClass?.classId == declaration.classId) { + delegation = fir + break + } + if (!(fir as FirCallableMemberDeclaration<*>).isAbstract) { + implementations.add(fir) + } +// val type = context.returnTypeCalculator.tryCalculateReturnType(intSymbol.fir).coneType + } + + 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 + dedupReporter.reportOn(source, FirErrors.RETURN_TYPE_MISMATCH_ON_INHERITANCE, declaration, method, conflict, context) + } else { + //if there is no implementation, check that there can be any type compatible (subtype of) with all + 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)) { + clash = m1 to m2 + } + result + } + } + clash?.takeIf { !compatible }?.let { (m1, m2) -> + dedupReporter.reportOn(source, FirErrors.RETURN_TYPE_MISMATCH_ON_INHERITANCE, declaration, m1, m2, context) + } + } + } + + for (name in classScope.getCallableNames()) { + classScope.processFunctionsByName(name, ::checkSymbol) + } + } +} \ No newline at end of file diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/impl/DeduplicatingDiagnosticReporter.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/impl/DeduplicatingDiagnosticReporter.kt new file mode 100644 index 00000000000..637dbd71171 --- /dev/null +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/impl/DeduplicatingDiagnosticReporter.kt @@ -0,0 +1,25 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.analysis.diagnostics.impl + +import org.jetbrains.kotlin.fir.FirSourceElement +import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext +import org.jetbrains.kotlin.fir.analysis.diagnostics.AbstractFirDiagnosticFactory +import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic + +class DeduplicatingDiagnosticReporter(private val inner: DiagnosticReporter) : DiagnosticReporter() { + + private val reported = mutableSetOf>() + + override fun report(diagnostic: FirDiagnostic?, context: CheckerContext) { + if (diagnostic != null && reported.add(Pair(diagnostic.element, diagnostic.factory))) { + inner.report(diagnostic, context) + } + } +} + +fun DiagnosticReporter.deduplicating(): DeduplicatingDiagnosticReporter = DeduplicatingDiagnosticReporter(this) \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/delegation/Delegation_ClashingFunctions.fir.kt b/compiler/testData/diagnostics/tests/delegation/Delegation_ClashingFunctions.fir.kt index dd22f583e75..cb753f3700b 100644 --- a/compiler/testData/diagnostics/tests/delegation/Delegation_ClashingFunctions.fir.kt +++ b/compiler/testData/diagnostics/tests/delegation/Delegation_ClashingFunctions.fir.kt @@ -10,9 +10,9 @@ interface Three { public fun foo(): String } -class Test123(val v1: One, val v2: Two, val v3: Three) : One by v1, Two by v2, Three by v3 { } -class Test132(val v1: One, val v2: Two, val v3: Three) : One by v1, Three by v3, Two by v2 { } +class Test123(val v1: One, val v2: Two, val v3: Three) : One by v1, Two by v2, Three by v3 { } +class Test132(val v1: One, val v2: Two, val v3: Three) : One by v1, Three by v3, Two by v2 { } class Test312(val v1: One, val v2: Two, val v3: Three) : Three by v3, One by v1, Two by v2 { } class Test321(val v1: One, val v2: Two, val v3: Three) : Three by v3, Two by v2, One by v1 { } -class Test231(val v1: One, val v2: Two, val v3: Three) : Two by v2, Three by v3, One by v1 { } -class Test213(val v1: One, val v2: Two, val v3: Three) : Two by v2, One by v1, Three by v3 { } +class Test231(val v1: One, val v2: Two, val v3: Three) : Two by v2, Three by v3, One by v1 { } +class Test213(val v1: One, val v2: Two, val v3: Three) : Two by v2, One by v1, Three by v3 { } diff --git a/compiler/testData/diagnostics/tests/delegation/clashes/returnTypeMismatch.fir.kt b/compiler/testData/diagnostics/tests/delegation/clashes/returnTypeMismatch.fir.kt index 7d43fa00374..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/override/clashesOnInheritance/covariantOverrides.fir.kt b/compiler/testData/diagnostics/tests/override/clashesOnInheritance/covariantOverrides.fir.kt deleted file mode 100644 index 3ad448ae157..00000000000 --- a/compiler/testData/diagnostics/tests/override/clashesOnInheritance/covariantOverrides.fir.kt +++ /dev/null @@ -1,37 +0,0 @@ -interface IBase { - fun copy(): IBase -} - -interface ILeft : IBase { - override fun copy(): ILeft -} - -open class CLeft : ILeft { - override fun copy(): ILeft = CLeft() -} - -interface IRight : IBase { - override fun copy(): IRight -} - -interface IDerived : ILeft, IRight { - override fun copy(): IDerived -} - -// Error: ILeft::copy and IRight::copy have unrelated return types -class CDerivedInvalid1 : ILeft, IRight - -// Error: CLeft::copy and IRight::copy have unrelated return types -class CDerivedInvalid2 : CLeft(), IRight - -// OK: CDerived1::copy overrides both ILeft::copy and IRight::copy -class CDerived1 : ILeft, IRight { - override fun copy(): CDerived1 = CDerived1() -} - -// Although ILeft::copy and IRight::copy return types are unrelated, IDerived::copy return type is the most specific of three. -abstract class CDerived2 : ILeft, IRight, IDerived - -class CDerived2a : ILeft, IRight, IDerived { - override fun copy(): IDerived = CDerived2a() -} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/override/clashesOnInheritance/covariantOverrides.kt b/compiler/testData/diagnostics/tests/override/clashesOnInheritance/covariantOverrides.kt index d2e62a5b314..b6497fff677 100644 --- a/compiler/testData/diagnostics/tests/override/clashesOnInheritance/covariantOverrides.kt +++ b/compiler/testData/diagnostics/tests/override/clashesOnInheritance/covariantOverrides.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL interface IBase { fun copy(): IBase } diff --git a/compiler/testData/diagnostics/tests/override/clashesOnInheritance/flexibleReturnTypeList.fir.kt b/compiler/testData/diagnostics/tests/override/clashesOnInheritance/flexibleReturnTypeList.fir.kt deleted file mode 100644 index 5c7598aafaf..00000000000 --- a/compiler/testData/diagnostics/tests/override/clashesOnInheritance/flexibleReturnTypeList.fir.kt +++ /dev/null @@ -1,43 +0,0 @@ -// FILE: J.java -public interface J { - java.util.List foo(); -} - -// FILE: K.kt -interface ILNS { - fun foo(): List -} - -interface IMLS { - fun foo(): MutableList -} - -interface IMLNS { - fun foo(): MutableList -} - -interface ILS { - fun foo(): List -} - -interface Test1 : ILNS, J -interface Test2 : J, ILNS - -interface Test3 : IMLS, J -interface Test4 : J, IMLS - -interface Test5 : ILNS, IMLS, J -interface Test6 : ILNS, J, IMLS -interface Test7 : J, ILNS, IMLS - -// Return types of ILS::foo and IMLNS::foo are incompatible themselves. -// However, return type of J::foo is (Mutable)List!, -// which is subtype of both List and MutalbeList. -// Thus, inheriting from J, IMLNS, and ILS is Ok, -// but inheriting from IMLNS and ILS is not. - -interface Test8 : J, IMLNS, ILS -interface Test9 : IMLNS, J, ILS -interface Test10 : IMLNS, ILS, J - -interface Test11 : IMLNS, ILS \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/override/clashesOnInheritance/flexibleReturnTypeList.kt b/compiler/testData/diagnostics/tests/override/clashesOnInheritance/flexibleReturnTypeList.kt index eaa3f7471d0..b3a9aefdbf1 100644 --- a/compiler/testData/diagnostics/tests/override/clashesOnInheritance/flexibleReturnTypeList.kt +++ b/compiler/testData/diagnostics/tests/override/clashesOnInheritance/flexibleReturnTypeList.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // FILE: J.java public interface J { java.util.List foo(); diff --git a/compiler/testData/diagnostics/tests/override/clashesOnInheritance/kt13355viaJava.fir.kt b/compiler/testData/diagnostics/tests/override/clashesOnInheritance/kt13355viaJava.fir.kt deleted file mode 100644 index 0ad54762042..00000000000 --- a/compiler/testData/diagnostics/tests/override/clashesOnInheritance/kt13355viaJava.fir.kt +++ /dev/null @@ -1,47 +0,0 @@ -// FILE: K.kt -abstract class ATest1 : TestNN.JNullVsNotNull() - -abstract class ATest2 : TestNN.JUnknownImpl(), TestNN.JNotNull - -abstract class ATest3 : TestNN.JUnknownVsNotNull() - -class CTest1 : TestNN.JNullVsNotNull() - -class CTest2 : TestNN.JUnknownImpl(), TestNN.JNotNull - -class CTest3 : TestNN.JUnknownVsNotNull() - -// FILE: TestNN.java -import org.jetbrains.annotations.*; - -public class TestNN { - public interface JNull { - @Nullable Object foo(); - } - - public interface JNotNull { - @NotNull Object foo(); - } - - public static class JNullVsNotNull implements JNull, JNotNull { - public Object foo() { - return this; - } - } - - public static class JNullBase { - @Nullable public Object foo() { - return null; - } - } - - public static class JUnknownImpl extends JNullBase { - public Object foo() { - return this; - } - } - - public static class JUnknownVsNotNull extends JUnknownImpl implements JNotNull { - } -} - diff --git a/compiler/testData/diagnostics/tests/override/clashesOnInheritance/kt13355viaJava.kt b/compiler/testData/diagnostics/tests/override/clashesOnInheritance/kt13355viaJava.kt index 41679b53d86..40f987a64cf 100644 --- a/compiler/testData/diagnostics/tests/override/clashesOnInheritance/kt13355viaJava.kt +++ b/compiler/testData/diagnostics/tests/override/clashesOnInheritance/kt13355viaJava.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // FILE: K.kt abstract class ATest1 : TestNN.JNullVsNotNull() diff --git a/compiler/testData/diagnostics/tests/override/clashesOnInheritance/returnTypeMismatch.fir.kt b/compiler/testData/diagnostics/tests/override/clashesOnInheritance/returnTypeMismatch.fir.kt deleted file mode 100644 index 93f1a1414fc..00000000000 --- a/compiler/testData/diagnostics/tests/override/clashesOnInheritance/returnTypeMismatch.fir.kt +++ /dev/null @@ -1,29 +0,0 @@ -open class A { - open fun foo(): Boolean = true -} - -interface IA { - fun foo(): String -} - -interface IAA { - fun foo(): Int -} - -interface IGA { - fun 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/returnTypeMismatch.kt b/compiler/testData/diagnostics/tests/override/clashesOnInheritance/returnTypeMismatch.kt index 3548cc9114b..b55122fbb3a 100644 --- a/compiler/testData/diagnostics/tests/override/clashesOnInheritance/returnTypeMismatch.kt +++ b/compiler/testData/diagnostics/tests/override/clashesOnInheritance/returnTypeMismatch.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL open class A { open fun foo(): Boolean = true } diff --git a/compiler/testData/diagnostics/tests/override/kt4763.fir.kt b/compiler/testData/diagnostics/tests/override/kt4763.fir.kt deleted file mode 100644 index 0f18e051678..00000000000 --- a/compiler/testData/diagnostics/tests/override/kt4763.fir.kt +++ /dev/null @@ -1,11 +0,0 @@ -interface A { - fun f(): String -} - -open class B { - open fun f(): CharSequence = "charSequence" -} - -class C : B(), A - -val d: A = object : B(), A {} diff --git a/compiler/testData/diagnostics/tests/override/kt4763.kt b/compiler/testData/diagnostics/tests/override/kt4763.kt index 7176a31711b..566f20fd3d7 100644 --- a/compiler/testData/diagnostics/tests/override/kt4763.kt +++ b/compiler/testData/diagnostics/tests/override/kt4763.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL interface A { fun f(): String } diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index 29ce586434b..50a3873cf0c 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -20624,7 +20624,7 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { @Test @TestMetadata("kt13355viaJava.kt") - public void testKt13355viaJava() throws Exception { + public void testKt13355viaJava1111() throws Exception { runTest("compiler/testData/diagnostics/tests/override/clashesOnInheritance/kt13355viaJava.kt"); } 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 79c4acc2bf5..72fabe16d63 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 @@ -1652,6 +1652,15 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert token, ) } + add(FirErrors.RETURN_TYPE_MISMATCH_ON_INHERITANCE) { firDiagnostic -> + ReturnTypeMismatchOnInheritanceImpl( + firSymbolBuilder.classifierBuilder.buildClassLikeSymbol(firDiagnostic.a), + firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.b as FirCallableDeclaration), + firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.c 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 bfbc36038dd..8742ad45275 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 @@ -1171,6 +1171,13 @@ sealed class KtFirDiagnostic : KtDiagnosticWithPsi { abstract val containingClassName: Name } + abstract class ReturnTypeMismatchOnInheritance : KtFirDiagnostic() { + override val diagnosticClass get() = ReturnTypeMismatchOnInheritance::class + abstract val classOrObject: KtClassLikeSymbol + abstract val conflictingDeclaration1: KtCallableSymbol + abstract val conflictingDeclaration2: 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 a7167166c51..1c6d1f316a1 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 @@ -1883,6 +1883,16 @@ internal class OverridingFinalMemberImpl( override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic) } +internal class ReturnTypeMismatchOnInheritanceImpl( + override val classOrObject: KtClassLikeSymbol, + override val conflictingDeclaration1: KtCallableSymbol, + override val conflictingDeclaration2: KtCallableSymbol, + firDiagnostic: FirPsiDiagnostic<*>, + override val token: ValidityToken, +) : KtFirDiagnostic.ReturnTypeMismatchOnInheritance(), KtAbstractFirDiagnostic { + override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic) +} + internal class AbstractMemberNotImplementedImpl( override val classOrObject: KtClassLikeSymbol, override val missingDeclaration: KtCallableSymbol,