[FIR] Implement properties types mismatch on inheritence
PROPERTY_TYPE_MISMATCH_ON_INHERITANCE, VAR_TYPE_MISMATCH_ON_INHERITANCE, PROPERTY_TYPE_MISMATCH_BY_DELEGATION
This commit is contained in:
committed by
teamcityserver
parent
8c7ee0b714
commit
c98cd3b190
+15
@@ -592,11 +592,26 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
|||||||
parameter<FirCallableDeclaration<*>>("conflictingDeclaration2")
|
parameter<FirCallableDeclaration<*>>("conflictingDeclaration2")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val PROPERTY_TYPE_MISMATCH_ON_INHERITANCE by error<KtClassOrObject>(PositioningStrategy.DECLARATION_NAME) {
|
||||||
|
parameter<FirCallableDeclaration<*>>("conflictingDeclaration1")
|
||||||
|
parameter<FirCallableDeclaration<*>>("conflictingDeclaration2")
|
||||||
|
}
|
||||||
|
|
||||||
|
val VAR_TYPE_MISMATCH_ON_INHERITANCE by error<KtClassOrObject>(PositioningStrategy.DECLARATION_NAME) {
|
||||||
|
parameter<FirCallableDeclaration<*>>("conflictingDeclaration1")
|
||||||
|
parameter<FirCallableDeclaration<*>>("conflictingDeclaration2")
|
||||||
|
}
|
||||||
|
|
||||||
val RETURN_TYPE_MISMATCH_BY_DELEGATION by error<KtClassOrObject>(PositioningStrategy.DECLARATION_NAME) {
|
val RETURN_TYPE_MISMATCH_BY_DELEGATION by error<KtClassOrObject>(PositioningStrategy.DECLARATION_NAME) {
|
||||||
parameter<FirCallableDeclaration<*>>("delegateDeclaration")
|
parameter<FirCallableDeclaration<*>>("delegateDeclaration")
|
||||||
parameter<FirCallableDeclaration<*>>("baseDeclaration")
|
parameter<FirCallableDeclaration<*>>("baseDeclaration")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val PROPERTY_TYPE_MISMATCH_BY_DELEGATION by error<KtClassOrObject>(PositioningStrategy.DECLARATION_NAME) {
|
||||||
|
parameter<FirCallableDeclaration<*>>("delegateDeclaration")
|
||||||
|
parameter<FirCallableDeclaration<*>>("baseDeclaration")
|
||||||
|
}
|
||||||
|
|
||||||
val ABSTRACT_MEMBER_NOT_IMPLEMENTED by error<KtClassOrObject>(PositioningStrategy.DECLARATION_NAME) {
|
val ABSTRACT_MEMBER_NOT_IMPLEMENTED by error<KtClassOrObject>(PositioningStrategy.DECLARATION_NAME) {
|
||||||
parameter<FirClass>("classOrObject")
|
parameter<FirClass>("classOrObject")
|
||||||
parameter<FirCallableDeclaration>("missingDeclaration")
|
parameter<FirCallableDeclaration>("missingDeclaration")
|
||||||
|
|||||||
@@ -348,7 +348,10 @@ object FirErrors {
|
|||||||
val CANNOT_CHANGE_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 OVERRIDING_FINAL_MEMBER by error2<KtNamedDeclaration, FirCallableDeclaration, Name>(SourceElementPositioningStrategies.OVERRIDE_MODIFIER)
|
||||||
val RETURN_TYPE_MISMATCH_ON_INHERITANCE by error2<KtClassOrObject, FirCallableDeclaration<*>, FirCallableDeclaration<*>>(SourceElementPositioningStrategies.DECLARATION_NAME)
|
val RETURN_TYPE_MISMATCH_ON_INHERITANCE by error2<KtClassOrObject, FirCallableDeclaration<*>, FirCallableDeclaration<*>>(SourceElementPositioningStrategies.DECLARATION_NAME)
|
||||||
|
val PROPERTY_TYPE_MISMATCH_ON_INHERITANCE by error2<KtClassOrObject, FirCallableDeclaration<*>, FirCallableDeclaration<*>>(SourceElementPositioningStrategies.DECLARATION_NAME)
|
||||||
|
val VAR_TYPE_MISMATCH_ON_INHERITANCE by error2<KtClassOrObject, FirCallableDeclaration<*>, FirCallableDeclaration<*>>(SourceElementPositioningStrategies.DECLARATION_NAME)
|
||||||
val RETURN_TYPE_MISMATCH_BY_DELEGATION by error2<KtClassOrObject, FirCallableDeclaration<*>, FirCallableDeclaration<*>>(SourceElementPositioningStrategies.DECLARATION_NAME)
|
val RETURN_TYPE_MISMATCH_BY_DELEGATION by error2<KtClassOrObject, FirCallableDeclaration<*>, FirCallableDeclaration<*>>(SourceElementPositioningStrategies.DECLARATION_NAME)
|
||||||
|
val PROPERTY_TYPE_MISMATCH_BY_DELEGATION by error2<KtClassOrObject, FirCallableDeclaration<*>, FirCallableDeclaration<*>>(SourceElementPositioningStrategies.DECLARATION_NAME)
|
||||||
val ABSTRACT_MEMBER_NOT_IMPLEMENTED by error2<KtClassOrObject, FirClass, 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 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)
|
val INVISIBLE_ABSTRACT_MEMBER_FROM_SUPER by error2<KtClassOrObject, FirClass, FirCallableDeclaration>(SourceElementPositioningStrategies.DECLARATION_NAME)
|
||||||
|
|||||||
+42
-16
@@ -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.symbols.impl.FirIntersectionCallableSymbol
|
||||||
import org.jetbrains.kotlin.fir.typeContext
|
import org.jetbrains.kotlin.fir.typeContext
|
||||||
import org.jetbrains.kotlin.fir.types.ConeKotlinErrorType
|
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.fir.types.coneType
|
||||||
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||||
|
|
||||||
@@ -39,6 +40,30 @@ object FirImplementationMismatchChecker : FirClassChecker() {
|
|||||||
val classScope = declaration.unsubstitutedScope(context)
|
val classScope = declaration.unsubstitutedScope(context)
|
||||||
val dedupReporter = reporter.deduplicating()
|
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<*>) {
|
fun checkSymbol(symbol: FirCallableSymbol<*>) {
|
||||||
if (symbol.callableId.classId != declaration.classId) return
|
if (symbol.callableId.classId != declaration.classId) return
|
||||||
if (symbol !is FirIntersectionCallableSymbol) return
|
if (symbol !is FirIntersectionCallableSymbol) return
|
||||||
@@ -62,37 +87,38 @@ object FirImplementationMismatchChecker : FirClassChecker() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (delegation != null || implementations.isNotEmpty()) {
|
run {
|
||||||
//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
|
|
||||||
var clash: Pair<FirCallableDeclaration<*>, FirCallableDeclaration<*>>? = null
|
var clash: Pair<FirCallableDeclaration<*>, FirCallableDeclaration<*>>? = null
|
||||||
val compatible = withTypes.any { (m1, type1) ->
|
val compatible = withTypes.any { (m1, type1) ->
|
||||||
withTypes.all { (m2, type2) ->
|
withTypes.all { (m2, type2) ->
|
||||||
val result = AbstractTypeChecker.isSubtypeOf(typeCheckerContext, type1, type2)
|
val result = canOverride(m2, type1, type2)
|
||||||
if (!result && clash == null && !AbstractTypeChecker.isSubtypeOf(typeCheckerContext, type2, type1)) {
|
if (!result && clash == null && !canOverride(m1, type2, type1)) {
|
||||||
clash = m1 to m2
|
clash = m1 to m2
|
||||||
}
|
}
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
clash?.takeIf { !compatible }?.let { (m1, m2) ->
|
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()) {
|
for (name in classScope.getCallableNames()) {
|
||||||
classScope.processFunctionsByName(name, ::checkSymbol)
|
classScope.processFunctionsByName(name, ::checkSymbol)
|
||||||
|
classScope.processPropertiesByName(name, ::checkSymbol)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+24
@@ -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.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_IN_INTERFACE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PROPERTY_INITIALIZER_NO_BACKING_FIELD
|
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_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_BACKING_FIELD_INSIDE_INLINE_CLASS
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PROPERTY_WITH_NO_TYPE_NO_INITIALIZER
|
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.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_ANNOTATION_PARAMETER
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAR_OVERRIDDEN_BY_VAL
|
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.VAR_TYPE_MISMATCH_ON_OVERRIDE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VIRTUAL_MEMBER_HIDDEN
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VIRTUAL_MEMBER_HIDDEN
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_ANNOTATION_TARGET
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_ANNOTATION_TARGET
|
||||||
@@ -944,6 +947,20 @@ class FirDefaultErrorMessages {
|
|||||||
NAME
|
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(
|
map.put(
|
||||||
RETURN_TYPE_MISMATCH_BY_DELEGATION,
|
RETURN_TYPE_MISMATCH_BY_DELEGATION,
|
||||||
"Type of ''{0}'' is not a subtype of overridden by delegation ''{1}''",
|
"Type of ''{0}'' is not a subtype of overridden by delegation ''{1}''",
|
||||||
@@ -951,6 +968,13 @@ class FirDefaultErrorMessages {
|
|||||||
NAME
|
NAME
|
||||||
)
|
)
|
||||||
|
|
||||||
|
map.put(
|
||||||
|
PROPERTY_TYPE_MISMATCH_BY_DELEGATION,
|
||||||
|
"Type of property ''{0}'' is not a subtype of overridden by delegation ''{1}''",
|
||||||
|
NAME,
|
||||||
|
NAME
|
||||||
|
)
|
||||||
|
|
||||||
// Redeclarations
|
// Redeclarations
|
||||||
map.put(MANY_COMPANION_OBJECTS, "Only one companion object is allowed per class")
|
map.put(MANY_COMPANION_OBJECTS, "Only one companion object is allowed per class")
|
||||||
map.put(CONFLICTING_OVERLOADS, "Conflicting overloads: {0}", SYMBOLS) // *
|
map.put(CONFLICTING_OVERLOADS, "Conflicting overloads: {0}", SYMBOLS) // *
|
||||||
|
|||||||
+5
-1
@@ -345,7 +345,11 @@ class FirTypeIntersectionScope private constructor(
|
|||||||
newModality: Modality?,
|
newModality: Modality?,
|
||||||
newVisibility: Visibility,
|
newVisibility: Visibility,
|
||||||
): FirPropertySymbol {
|
): 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
|
val mostSpecificProperty = mostSpecific.fir
|
||||||
FirFakeOverrideGenerator.createCopyForFirProperty(
|
FirFakeOverrideGenerator.createCopyForFirProperty(
|
||||||
newSymbol, mostSpecificProperty, session, FirDeclarationOrigin.IntersectionOverride,
|
newSymbol, mostSpecificProperty, session, FirDeclarationOrigin.IntersectionOverride,
|
||||||
|
|||||||
+7
-7
@@ -30,28 +30,28 @@ class CGeneric<T> : IGeneric<T> {
|
|||||||
override val foo: T get() = null!!
|
override val foo: T get() = null!!
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class Test1 : IStr by CStr(), IInt
|
abstract <!PROPERTY_TYPE_MISMATCH_ON_INHERITANCE!>class Test1<!> : IStr by CStr(), IInt
|
||||||
|
|
||||||
abstract class Test2 : IStr, IInt by CInt()
|
abstract <!PROPERTY_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, PROPERTY_TYPE_MISMATCH_ON_INHERITANCE!>class Test3<!> : IStr by CStr(), IInt by CInt()
|
||||||
|
|
||||||
abstract class Test4 : IStr by CStr(), IGeneric<String>
|
abstract class Test4 : IStr by CStr(), IGeneric<String>
|
||||||
|
|
||||||
abstract class Test5 : IStr by CStr(), IGeneric<Any>
|
abstract class Test5 : IStr by CStr(), IGeneric<Any>
|
||||||
|
|
||||||
abstract class Test6 : IStr by CStr(), IGeneric<Int>
|
abstract <!PROPERTY_TYPE_MISMATCH_ON_INHERITANCE!>class Test6<!> : IStr by CStr(), IGeneric<Int>
|
||||||
|
|
||||||
abstract class Test7 : IGeneric<String> by CGeneric<String>(), IStr
|
abstract class Test7 : IGeneric<String> by CGeneric<String>(), IStr
|
||||||
|
|
||||||
abstract class Test8 : IGeneric<String> by CGeneric<String>(), IInt
|
abstract <!PROPERTY_TYPE_MISMATCH_ON_INHERITANCE!>class Test8<!> : IGeneric<String> by CGeneric<String>(), IInt
|
||||||
|
|
||||||
// Can't test right now due to https://youtrack.jetbrains.com/issue/KT-10258
|
// Can't test right now due to https://youtrack.jetbrains.com/issue/KT-10258
|
||||||
// abstract class Test9 : IGeneric<String> by CGeneric<String>(), IGeneric<Int>
|
// 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, PROPERTY_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!>class Test11<!> : IInt, IStr by CStr(), IAny by CAny()
|
||||||
|
|
||||||
abstract class Test12 : IInt, IStr, IAny by CAny()
|
abstract <!PROPERTY_TYPE_MISMATCH_ON_INHERITANCE!>class Test12<!> : IInt, IStr, IAny by CAny()
|
||||||
|
|
||||||
|
|||||||
+8
-8
@@ -32,28 +32,28 @@ class CGeneric<T> : IGeneric<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract <!RETURN_TYPE_MISMATCH_BY_DELEGATION!>class Test1<!> : IStr by CStr(), IInt
|
abstract <!RETURN_TYPE_MISMATCH_ON_INHERITANCE!>class Test1<!> : IStr by CStr(), IInt
|
||||||
|
|
||||||
abstract <!RETURN_TYPE_MISMATCH_BY_DELEGATION!>class Test2<!> : IStr, IInt by CInt()
|
abstract <!RETURN_TYPE_MISMATCH_ON_INHERITANCE!>class Test2<!> : IStr, IInt by CInt()
|
||||||
|
|
||||||
abstract <!MANY_IMPL_MEMBER_NOT_IMPLEMENTED, RETURN_TYPE_MISMATCH_BY_DELEGATION!>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 Test4 : IStr by CStr(), IGeneric<String>
|
||||||
|
|
||||||
abstract class Test5 : IStr by CStr(), IGeneric<Any>
|
abstract class Test5 : IStr by CStr(), IGeneric<Any>
|
||||||
|
|
||||||
abstract <!RETURN_TYPE_MISMATCH_BY_DELEGATION!>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 Test7 : IGeneric<String> by CGeneric<String>(), IStr
|
||||||
|
|
||||||
abstract <!RETURN_TYPE_MISMATCH_BY_DELEGATION!>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
|
// Can't test due to https://youtrack.jetbrains.com/issue/KT-10258
|
||||||
// abstract class Test9 : IGeneric<String> by CGeneric<String>(), IGeneric<Int>
|
// abstract class Test9 : IGeneric<String> by CGeneric<String>(), IGeneric<Int>
|
||||||
|
|
||||||
abstract <!MANY_IMPL_MEMBER_NOT_IMPLEMENTED, RETURN_TYPE_MISMATCH_BY_DELEGATION!>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, RETURN_TYPE_MISMATCH_BY_DELEGATION!>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 <!RETURN_TYPE_MISMATCH_BY_DELEGATION!>class Test12<!> : IInt, IStr, IAny by CAny()
|
abstract <!RETURN_TYPE_MISMATCH_ON_INHERITANCE!>class Test12<!> : IInt, IStr, IAny by CAny()
|
||||||
|
|
||||||
|
|||||||
-19
@@ -1,19 +0,0 @@
|
|||||||
interface IBase1 {
|
|
||||||
fun foo(): Any
|
|
||||||
}
|
|
||||||
|
|
||||||
open class IDerived1 : IBase1 {
|
|
||||||
override fun foo(): String = "1"
|
|
||||||
}
|
|
||||||
|
|
||||||
<!DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE, RETURN_TYPE_MISMATCH_BY_DELEGATION!>class Broken1<!>(val b: IBase1) : IBase1 by b, IDerived1()
|
|
||||||
|
|
||||||
interface IBase2 {
|
|
||||||
val foo: Any
|
|
||||||
}
|
|
||||||
|
|
||||||
open class IDerived2 : IBase2 {
|
|
||||||
override val foo: String = "2"
|
|
||||||
}
|
|
||||||
|
|
||||||
<!DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE!>class Broken2<!>(val b: IBase2) : IBase2 by b, IDerived2()
|
|
||||||
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
interface IBase1 {
|
interface IBase1 {
|
||||||
fun foo(): Any
|
fun foo(): Any
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -16,4 +16,4 @@ interface IDerived2 {
|
|||||||
val foo: String
|
val foo: String
|
||||||
}
|
}
|
||||||
|
|
||||||
class Broken2(val b: IBase2) : IBase2 by b, IDerived2
|
<!PROPERTY_TYPE_MISMATCH_BY_DELEGATION!>class Broken2<!>(val b: IBase2) : IBase2 by b, IDerived2
|
||||||
|
|||||||
-19
@@ -1,19 +0,0 @@
|
|||||||
interface IBase1 {
|
|
||||||
fun foo(): Any
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IDerived1 : IBase1 {
|
|
||||||
override fun foo(): String
|
|
||||||
}
|
|
||||||
|
|
||||||
<!RETURN_TYPE_MISMATCH_BY_DELEGATION!>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
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
interface IBase1 {
|
interface IBase1 {
|
||||||
fun foo(): Any
|
fun foo(): Any
|
||||||
}
|
}
|
||||||
|
|||||||
-13
@@ -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()
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
interface IFooAny {
|
interface IFooAny {
|
||||||
val foo: Any
|
val foo: Any
|
||||||
}
|
}
|
||||||
|
|||||||
-29
@@ -1,29 +0,0 @@
|
|||||||
open class A {
|
|
||||||
open val foo: Boolean = true
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IA {
|
|
||||||
val foo: String
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IAA {
|
|
||||||
val foo: Int
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IGA<T> {
|
|
||||||
val 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 class A {
|
||||||
open val foo: Boolean = true
|
open val foo: Boolean = true
|
||||||
}
|
}
|
||||||
|
|||||||
-29
@@ -1,29 +0,0 @@
|
|||||||
open class A {
|
|
||||||
open var foo: Boolean = true
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IA {
|
|
||||||
var foo: String
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IAA {
|
|
||||||
var foo: Int
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IGA<T> {
|
|
||||||
var 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 class A {
|
||||||
open var foo: Boolean = true
|
open var foo: Boolean = true
|
||||||
}
|
}
|
||||||
|
|||||||
+24
@@ -1660,6 +1660,22 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
|||||||
token,
|
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 ->
|
add(FirErrors.RETURN_TYPE_MISMATCH_BY_DELEGATION) { firDiagnostic ->
|
||||||
ReturnTypeMismatchByDelegationImpl(
|
ReturnTypeMismatchByDelegationImpl(
|
||||||
firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a as FirCallableDeclaration),
|
firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a as FirCallableDeclaration),
|
||||||
@@ -1668,6 +1684,14 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
|||||||
token,
|
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 ->
|
add(FirErrors.ABSTRACT_MEMBER_NOT_IMPLEMENTED) { firDiagnostic ->
|
||||||
AbstractMemberNotImplementedImpl(
|
AbstractMemberNotImplementedImpl(
|
||||||
firSymbolBuilder.classifierBuilder.buildClassLikeSymbol(firDiagnostic.a),
|
firSymbolBuilder.classifierBuilder.buildClassLikeSymbol(firDiagnostic.a),
|
||||||
|
|||||||
+18
@@ -1177,12 +1177,30 @@ sealed class KtFirDiagnostic<PSI: PsiElement> : KtDiagnosticWithPsi<PSI> {
|
|||||||
abstract val conflictingDeclaration2: KtCallableSymbol
|
abstract val conflictingDeclaration2: KtCallableSymbol
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract class PropertyTypeMismatchOnInheritance : KtFirDiagnostic<KtClassOrObject>() {
|
||||||
|
override val diagnosticClass get() = PropertyTypeMismatchOnInheritance::class
|
||||||
|
abstract val conflictingDeclaration1: KtCallableSymbol
|
||||||
|
abstract val conflictingDeclaration2: KtCallableSymbol
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class VarTypeMismatchOnInheritance : KtFirDiagnostic<KtClassOrObject>() {
|
||||||
|
override val diagnosticClass get() = VarTypeMismatchOnInheritance::class
|
||||||
|
abstract val conflictingDeclaration1: KtCallableSymbol
|
||||||
|
abstract val conflictingDeclaration2: KtCallableSymbol
|
||||||
|
}
|
||||||
|
|
||||||
abstract class ReturnTypeMismatchByDelegation : KtFirDiagnostic<KtClassOrObject>() {
|
abstract class ReturnTypeMismatchByDelegation : KtFirDiagnostic<KtClassOrObject>() {
|
||||||
override val diagnosticClass get() = ReturnTypeMismatchByDelegation::class
|
override val diagnosticClass get() = ReturnTypeMismatchByDelegation::class
|
||||||
abstract val delegateDeclaration: KtCallableSymbol
|
abstract val delegateDeclaration: KtCallableSymbol
|
||||||
abstract val baseDeclaration: KtCallableSymbol
|
abstract val baseDeclaration: KtCallableSymbol
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract class PropertyTypeMismatchByDelegation : KtFirDiagnostic<KtClassOrObject>() {
|
||||||
|
override val diagnosticClass get() = PropertyTypeMismatchByDelegation::class
|
||||||
|
abstract val delegateDeclaration: KtCallableSymbol
|
||||||
|
abstract val baseDeclaration: KtCallableSymbol
|
||||||
|
}
|
||||||
|
|
||||||
abstract class AbstractMemberNotImplemented : KtFirDiagnostic<KtClassOrObject>() {
|
abstract class AbstractMemberNotImplemented : KtFirDiagnostic<KtClassOrObject>() {
|
||||||
override val diagnosticClass get() = AbstractMemberNotImplemented::class
|
override val diagnosticClass get() = AbstractMemberNotImplemented::class
|
||||||
abstract val classOrObject: KtClassLikeSymbol
|
abstract val classOrObject: KtClassLikeSymbol
|
||||||
|
|||||||
+27
@@ -1892,6 +1892,24 @@ internal class ReturnTypeMismatchOnInheritanceImpl(
|
|||||||
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
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<KtClassOrObject> {
|
||||||
|
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<KtClassOrObject> {
|
||||||
|
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||||
|
}
|
||||||
|
|
||||||
internal class ReturnTypeMismatchByDelegationImpl(
|
internal class ReturnTypeMismatchByDelegationImpl(
|
||||||
override val delegateDeclaration: KtCallableSymbol,
|
override val delegateDeclaration: KtCallableSymbol,
|
||||||
override val baseDeclaration: KtCallableSymbol,
|
override val baseDeclaration: KtCallableSymbol,
|
||||||
@@ -1901,6 +1919,15 @@ internal class ReturnTypeMismatchByDelegationImpl(
|
|||||||
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
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<KtClassOrObject> {
|
||||||
|
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||||
|
}
|
||||||
|
|
||||||
internal class AbstractMemberNotImplementedImpl(
|
internal class AbstractMemberNotImplementedImpl(
|
||||||
override val classOrObject: KtClassLikeSymbol,
|
override val classOrObject: KtClassLikeSymbol,
|
||||||
override val missingDeclaration: KtCallableSymbol,
|
override val missingDeclaration: KtCallableSymbol,
|
||||||
|
|||||||
Reference in New Issue
Block a user