[FIR] Fixes after delegation scope rework
This commit is contained in:
committed by
teamcityserver
parent
02297d2c75
commit
1cb34541bd
+28
-23
@@ -20,6 +20,8 @@ import org.jetbrains.kotlin.fir.declarations.utils.isExpect
|
|||||||
import org.jetbrains.kotlin.fir.declarations.utils.isSuspend
|
import org.jetbrains.kotlin.fir.declarations.utils.isSuspend
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
|
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
|
||||||
|
import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenMembers
|
||||||
|
import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenProperties
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.delegatedWrapperData
|
import org.jetbrains.kotlin.fir.scopes.impl.delegatedWrapperData
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.toConeType
|
import org.jetbrains.kotlin.fir.scopes.impl.toConeType
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
@@ -49,10 +51,12 @@ object FirImplementationMismatchChecker : FirClassChecker() {
|
|||||||
val dedupReporter = reporter.deduplicating()
|
val dedupReporter = reporter.deduplicating()
|
||||||
|
|
||||||
for (name in classScope.getCallableNames()) {
|
for (name in classScope.getCallableNames()) {
|
||||||
classScope.processFunctionsByName(name) { checkInheritanceClash(declaration, context, dedupReporter, typeCheckerContext, it) }
|
classScope.processFunctionsByName(name) {
|
||||||
|
checkInheritanceClash(declaration, context, dedupReporter, typeCheckerContext, it, classScope)
|
||||||
|
}
|
||||||
classScope.processPropertiesByName(name) {
|
classScope.processPropertiesByName(name) {
|
||||||
checkInheritanceClash(declaration, context, dedupReporter, typeCheckerContext, it)
|
checkInheritanceClash(declaration, context, dedupReporter, typeCheckerContext, it, classScope)
|
||||||
checkValOverridesVar(declaration, context, dedupReporter, it)
|
checkValOverridesVar(declaration, context, dedupReporter, it, classScope)
|
||||||
}
|
}
|
||||||
checkConflictingMembers(declaration, context, dedupReporter, classScope, name)
|
checkConflictingMembers(declaration, context, dedupReporter, classScope, name)
|
||||||
}
|
}
|
||||||
@@ -63,7 +67,8 @@ object FirImplementationMismatchChecker : FirClassChecker() {
|
|||||||
context: CheckerContext,
|
context: CheckerContext,
|
||||||
reporter: DiagnosticReporter,
|
reporter: DiagnosticReporter,
|
||||||
typeCheckerContext: ConeTypeCheckerContext,
|
typeCheckerContext: ConeTypeCheckerContext,
|
||||||
symbol: FirCallableSymbol<*>
|
symbol: FirCallableSymbol<*>,
|
||||||
|
classScope: FirTypeScope
|
||||||
) {
|
) {
|
||||||
fun reportTypeMismatch(member1: FirCallableDeclaration, member2: FirCallableDeclaration, isDelegation: Boolean) {
|
fun reportTypeMismatch(member1: FirCallableDeclaration, member2: FirCallableDeclaration, isDelegation: Boolean) {
|
||||||
val error = when {
|
val error = when {
|
||||||
@@ -96,9 +101,15 @@ object FirImplementationMismatchChecker : FirClassChecker() {
|
|||||||
AbstractTypeChecker.isSubtypeOf(typeCheckerContext, inheritedTypeSubstituted, baseType)
|
AbstractTypeChecker.isSubtypeOf(typeCheckerContext, inheritedTypeSubstituted, baseType)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (symbol.callableId.classId != containingClass.classId) return
|
val intersectionSymbols = when {
|
||||||
if (symbol !is FirIntersectionCallableSymbol) return
|
symbol.fir.delegatedWrapperData != null ->
|
||||||
val withTypes = symbol.intersections.map {
|
classScope.getDirectOverriddenMembers(symbol) + symbol
|
||||||
|
symbol is FirIntersectionCallableSymbol && symbol.callableId.classId == containingClass.classId ->
|
||||||
|
symbol.intersections
|
||||||
|
else -> return
|
||||||
|
}
|
||||||
|
|
||||||
|
val withTypes = intersectionSymbols.map {
|
||||||
it.fir to context.returnTypeCalculator.tryCalculateReturnType(it.fir).coneType
|
it.fir to context.returnTypeCalculator.tryCalculateReturnType(it.fir).coneType
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,7 +118,7 @@ object FirImplementationMismatchChecker : FirClassChecker() {
|
|||||||
var delegation: FirCallableDeclaration? = null
|
var delegation: FirCallableDeclaration? = null
|
||||||
val implementations = mutableListOf<FirCallableDeclaration>()
|
val implementations = mutableListOf<FirCallableDeclaration>()
|
||||||
|
|
||||||
for (intSymbol in symbol.intersections) {
|
for (intSymbol in intersectionSymbols) {
|
||||||
val fir = intSymbol.fir
|
val fir = intSymbol.fir
|
||||||
if (fir.delegatedWrapperData?.containingClass?.classId == containingClass.classId) {
|
if (fir.delegatedWrapperData?.containingClass?.classId == containingClass.classId) {
|
||||||
delegation = fir
|
delegation = fir
|
||||||
@@ -149,24 +160,18 @@ object FirImplementationMismatchChecker : FirClassChecker() {
|
|||||||
containingClass: FirClass,
|
containingClass: FirClass,
|
||||||
context: CheckerContext,
|
context: CheckerContext,
|
||||||
reporter: DiagnosticReporter,
|
reporter: DiagnosticReporter,
|
||||||
symbol: FirVariableSymbol<*>
|
symbol: FirVariableSymbol<*>,
|
||||||
|
classScope: FirTypeScope
|
||||||
) {
|
) {
|
||||||
if (symbol.callableId.classId != containingClass.classId) return
|
if (symbol !is FirPropertySymbol || symbol.fir.isVar) return
|
||||||
if (symbol !is FirIntersectionOverridePropertySymbol) return
|
if (symbol.fir.delegatedWrapperData == null) return
|
||||||
|
|
||||||
val (delegates, others) = symbol.intersections.partition {
|
val overriddenVar =
|
||||||
val fir = it.fir as? FirProperty ?: return@partition false
|
classScope.getDirectOverriddenProperties(symbol, true)
|
||||||
fir.isVal && fir.delegatedWrapperData?.containingClass?.classId == containingClass.classId
|
.find { it.fir.isVar }
|
||||||
}
|
?: return
|
||||||
|
|
||||||
val delegatedVal = delegates.firstOrNull() ?: return
|
reporter.reportOn(containingClass.source, FirErrors.VAR_OVERRIDDEN_BY_VAL_BY_DELEGATION, symbol.fir, overriddenVar.fir, context)
|
||||||
val baseVar = others.find {
|
|
||||||
it is FirPropertySymbol && it.fir.isVar
|
|
||||||
}
|
|
||||||
|
|
||||||
if (baseVar != null) {
|
|
||||||
reporter.reportOn(containingClass.source, FirErrors.VAR_OVERRIDDEN_BY_VAL_BY_DELEGATION, delegatedVal.fir, baseVar.fir, context)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkConflictingMembers(
|
private fun checkConflictingMembers(
|
||||||
|
|||||||
+1
-1
@@ -51,7 +51,7 @@ abstract <!PROPERTY_TYPE_MISMATCH_ON_INHERITANCE!>class Test8<!> : IGeneric<Stri
|
|||||||
|
|
||||||
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, 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, PROPERTY_TYPE_MISMATCH_ON_INHERITANCE!>class Test11<!> : IInt, IStr by CStr(), IAny by CAny()
|
||||||
|
|
||||||
abstract <!PROPERTY_TYPE_MISMATCH_ON_INHERITANCE!>class Test12<!> : IInt, IStr, IAny by CAny()
|
abstract <!PROPERTY_TYPE_MISMATCH_ON_INHERITANCE!>class Test12<!> : IInt, IStr, IAny by CAny()
|
||||||
|
|
||||||
|
|||||||
-17
@@ -1,17 +0,0 @@
|
|||||||
interface IA {
|
|
||||||
fun foo(): Number
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IB : IA {
|
|
||||||
override fun foo(): Int
|
|
||||||
}
|
|
||||||
|
|
||||||
object AImpl : IA {
|
|
||||||
override fun foo() = 42
|
|
||||||
}
|
|
||||||
|
|
||||||
open <!RETURN_TYPE_MISMATCH_BY_DELEGATION!>class C<!> : IA by AImpl, IB
|
|
||||||
|
|
||||||
class D : C() {
|
|
||||||
override fun foo(): Double = 3.14
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
interface IA {
|
interface IA {
|
||||||
fun foo(): Number
|
fun foo(): Number
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user