[FIR] Implement RETURN_TYPE_MISMATCH_ON_INHERITANCE diagnostic
This commit is contained in:
committed by
teamcityserver
parent
8012eb3214
commit
94da1e37aa
+6
@@ -587,6 +587,12 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
||||
parameter<Name>("containingClassName")
|
||||
}
|
||||
|
||||
val RETURN_TYPE_MISMATCH_ON_INHERITANCE by error<KtClassOrObject>(PositioningStrategy.DECLARATION_NAME) {
|
||||
parameter<FirClass<*>>("classOrObject")
|
||||
parameter<FirCallableDeclaration<*>>("conflictingDeclaration1")
|
||||
parameter<FirCallableDeclaration<*>>("conflictingDeclaration2")
|
||||
}
|
||||
|
||||
val ABSTRACT_MEMBER_NOT_IMPLEMENTED by error<KtClassOrObject>(PositioningStrategy.DECLARATION_NAME) {
|
||||
parameter<FirClass>("classOrObject")
|
||||
parameter<FirCallableDeclaration>("missingDeclaration")
|
||||
|
||||
@@ -347,6 +347,7 @@ object FirErrors {
|
||||
val CANNOT_WEAKEN_ACCESS_PRIVILEGE by error3<KtModifierListOwner, Visibility, FirCallableDeclaration, Name>(SourceElementPositioningStrategies.VISIBILITY_MODIFIER)
|
||||
val CANNOT_CHANGE_ACCESS_PRIVILEGE by error3<KtModifierListOwner, Visibility, FirCallableDeclaration, Name>(SourceElementPositioningStrategies.VISIBILITY_MODIFIER)
|
||||
val OVERRIDING_FINAL_MEMBER by error2<KtNamedDeclaration, FirCallableDeclaration, Name>(SourceElementPositioningStrategies.OVERRIDE_MODIFIER)
|
||||
val RETURN_TYPE_MISMATCH_ON_INHERITANCE by error3<KtClassOrObject, FirClass<*>, FirCallableDeclaration<*>, FirCallableDeclaration<*>>(SourceElementPositioningStrategies.DECLARATION_NAME)
|
||||
val ABSTRACT_MEMBER_NOT_IMPLEMENTED by error2<KtClassOrObject, FirClass, FirCallableDeclaration>(SourceElementPositioningStrategies.DECLARATION_NAME)
|
||||
val ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED by error2<KtClassOrObject, FirClass, FirCallableDeclaration>(SourceElementPositioningStrategies.DECLARATION_NAME)
|
||||
val INVISIBLE_ABSTRACT_MEMBER_FROM_SUPER by error2<KtClassOrObject, FirClass, FirCallableDeclaration>(SourceElementPositioningStrategies.DECLARATION_NAME)
|
||||
|
||||
+1
@@ -66,6 +66,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
|
||||
FirSealedSupertypeChecker,
|
||||
FirMemberFunctionsChecker,
|
||||
FirMemberPropertiesChecker,
|
||||
FirImplementationMismatchChecker,
|
||||
)
|
||||
|
||||
override val regularClassCheckers: Set<FirRegularClassChecker>
|
||||
|
||||
+96
@@ -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<FirCallableDeclaration<*>>()
|
||||
|
||||
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<*>, 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
+25
@@ -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<Pair<FirSourceElement, AbstractFirDiagnosticFactory>>()
|
||||
|
||||
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)
|
||||
+4
-4
@@ -10,9 +10,9 @@ interface Three {
|
||||
public fun foo(): String
|
||||
}
|
||||
|
||||
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>class Test123<!>(val v1: One, val v2: Two, val v3: Three) : One by v1, Two by v2, Three by v3 { }
|
||||
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>class Test132<!>(val v1: One, val v2: Two, val v3: Three) : One by v1, Three by v3, Two by v2 { }
|
||||
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED, RETURN_TYPE_MISMATCH_ON_INHERITANCE!>class Test123<!>(val v1: One, val v2: Two, val v3: Three) : One by v1, Two by v2, Three by v3 { }
|
||||
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED, RETURN_TYPE_MISMATCH_ON_INHERITANCE!>class Test132<!>(val v1: One, val v2: Two, val v3: Three) : One by v1, Three by v3, Two by v2 { }
|
||||
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>class Test312<!>(val v1: One, val v2: Two, val v3: Three) : Three by v3, One by v1, Two by v2 { }
|
||||
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>class Test321<!>(val v1: One, val v2: Two, val v3: Three) : Three by v3, Two by v2, One by v1 { }
|
||||
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>class Test231<!>(val v1: One, val v2: Two, val v3: Three) : Two by v2, Three by v3, One by v1 { }
|
||||
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>class Test213<!>(val v1: One, val v2: Two, val v3: Three) : Two by v2, One by v1, Three by v3 { }
|
||||
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED, RETURN_TYPE_MISMATCH_ON_INHERITANCE!>class Test231<!>(val v1: One, val v2: Two, val v3: Three) : Two by v2, Three by v3, One by v1 { }
|
||||
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED, RETURN_TYPE_MISMATCH_ON_INHERITANCE!>class Test213<!>(val v1: One, val v2: Two, val v3: Three) : Two by v2, One by v1, Three by v3 { }
|
||||
|
||||
+8
-8
@@ -32,28 +32,28 @@ class CGeneric<T> : IGeneric<T> {
|
||||
}
|
||||
}
|
||||
|
||||
abstract class Test1 : IStr by CStr(), IInt
|
||||
abstract <!RETURN_TYPE_MISMATCH_ON_INHERITANCE!>class Test1<!> : IStr by CStr(), IInt
|
||||
|
||||
abstract class Test2 : IStr, IInt by CInt()
|
||||
abstract <!RETURN_TYPE_MISMATCH_ON_INHERITANCE!>class Test2<!> : IStr, IInt by CInt()
|
||||
|
||||
abstract <!MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>class Test3<!> : IStr by CStr(), IInt by CInt()
|
||||
abstract <!MANY_IMPL_MEMBER_NOT_IMPLEMENTED, RETURN_TYPE_MISMATCH_ON_INHERITANCE!>class Test3<!> : IStr by CStr(), IInt by CInt()
|
||||
|
||||
abstract class Test4 : IStr by CStr(), IGeneric<String>
|
||||
|
||||
abstract class Test5 : IStr by CStr(), IGeneric<Any>
|
||||
|
||||
abstract class Test6 : IStr by CStr(), IGeneric<Int>
|
||||
abstract <!RETURN_TYPE_MISMATCH_ON_INHERITANCE!>class Test6<!> : IStr by CStr(), IGeneric<Int>
|
||||
|
||||
abstract class Test7 : IGeneric<String> by CGeneric<String>(), IStr
|
||||
|
||||
abstract class Test8 : IGeneric<String> by CGeneric<String>(), IInt
|
||||
abstract <!RETURN_TYPE_MISMATCH_ON_INHERITANCE!>class Test8<!> : IGeneric<String> by CGeneric<String>(), IInt
|
||||
|
||||
// Can't test due to https://youtrack.jetbrains.com/issue/KT-10258
|
||||
// abstract class Test9 : IGeneric<String> by CGeneric<String>(), IGeneric<Int>
|
||||
|
||||
abstract <!MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>class Test10<!> : IInt by CInt(), IStr by CStr(), IAny by CAny()
|
||||
abstract <!MANY_IMPL_MEMBER_NOT_IMPLEMENTED, RETURN_TYPE_MISMATCH_ON_INHERITANCE!>class Test10<!> : IInt by CInt(), IStr by CStr(), IAny by CAny()
|
||||
|
||||
abstract <!MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>class Test11<!> : IInt, IStr by CStr(), IAny by CAny()
|
||||
abstract <!MANY_IMPL_MEMBER_NOT_IMPLEMENTED, RETURN_TYPE_MISMATCH_ON_INHERITANCE!>class Test11<!> : IInt, IStr by CStr(), IAny by CAny()
|
||||
|
||||
abstract class Test12 : IInt, IStr, IAny by CAny()
|
||||
abstract <!RETURN_TYPE_MISMATCH_ON_INHERITANCE!>class Test12<!> : IInt, IStr, IAny by CAny()
|
||||
|
||||
|
||||
Vendored
-37
@@ -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
|
||||
<!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>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()
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
interface IBase {
|
||||
fun copy(): IBase
|
||||
}
|
||||
|
||||
Vendored
-43
@@ -1,43 +0,0 @@
|
||||
// FILE: J.java
|
||||
public interface J {
|
||||
java.util.List<String> foo();
|
||||
}
|
||||
|
||||
// FILE: K.kt
|
||||
interface ILNS {
|
||||
fun foo(): List<String?>
|
||||
}
|
||||
|
||||
interface IMLS {
|
||||
fun foo(): MutableList<String>
|
||||
}
|
||||
|
||||
interface IMLNS {
|
||||
fun foo(): MutableList<String?>
|
||||
}
|
||||
|
||||
interface ILS {
|
||||
fun foo(): List<String>
|
||||
}
|
||||
|
||||
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<String!>!,
|
||||
// which is subtype of both List<String> and MutalbeList<String?>.
|
||||
// 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
|
||||
Vendored
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// FILE: J.java
|
||||
public interface J {
|
||||
java.util.List<String> foo();
|
||||
|
||||
-47
@@ -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 {
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// FILE: K.kt
|
||||
abstract class ATest1 : TestNN.JNullVsNotNull()
|
||||
|
||||
|
||||
Vendored
-29
@@ -1,29 +0,0 @@
|
||||
open class A {
|
||||
open fun foo(): Boolean = true
|
||||
}
|
||||
|
||||
interface IA {
|
||||
fun foo(): String
|
||||
}
|
||||
|
||||
interface IAA {
|
||||
fun foo(): Int
|
||||
}
|
||||
|
||||
interface IGA<T> {
|
||||
fun foo(): T
|
||||
}
|
||||
|
||||
class B1: A(), IA
|
||||
|
||||
class B2: A(), IA, IAA
|
||||
|
||||
abstract class B3: IA, IAA
|
||||
|
||||
class BS1: A(), IGA<Boolean>
|
||||
|
||||
class BS2: A(), IGA<Any>
|
||||
|
||||
class BS3: A(), IGA<String>
|
||||
|
||||
class BG1<T>: A(), IGA<T>
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
open class A {
|
||||
open fun foo(): Boolean = true
|
||||
}
|
||||
|
||||
@@ -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 {}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
interface A {
|
||||
fun f(): String
|
||||
}
|
||||
|
||||
Generated
+1
-1
@@ -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");
|
||||
}
|
||||
|
||||
|
||||
+9
@@ -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),
|
||||
|
||||
+7
@@ -1171,6 +1171,13 @@ sealed class KtFirDiagnostic<PSI: PsiElement> : KtDiagnosticWithPsi<PSI> {
|
||||
abstract val containingClassName: Name
|
||||
}
|
||||
|
||||
abstract class ReturnTypeMismatchOnInheritance : KtFirDiagnostic<KtClassOrObject>() {
|
||||
override val diagnosticClass get() = ReturnTypeMismatchOnInheritance::class
|
||||
abstract val classOrObject: KtClassLikeSymbol
|
||||
abstract val conflictingDeclaration1: KtCallableSymbol
|
||||
abstract val conflictingDeclaration2: KtCallableSymbol
|
||||
}
|
||||
|
||||
abstract class AbstractMemberNotImplemented : KtFirDiagnostic<KtClassOrObject>() {
|
||||
override val diagnosticClass get() = AbstractMemberNotImplemented::class
|
||||
abstract val classOrObject: KtClassLikeSymbol
|
||||
|
||||
+10
@@ -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<KtClassOrObject> {
|
||||
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class AbstractMemberNotImplementedImpl(
|
||||
override val classOrObject: KtClassLikeSymbol,
|
||||
override val missingDeclaration: KtCallableSymbol,
|
||||
|
||||
Reference in New Issue
Block a user