[FIR] Fixes after delegation scope rework

This commit is contained in:
Andrey Zinovyev
2021-07-07 16:36:23 +03:00
committed by teamcityserver
parent 02297d2c75
commit 1cb34541bd
4 changed files with 30 additions and 41 deletions
@@ -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.resolve.substitution.substitutorByMap
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.toConeType
import org.jetbrains.kotlin.fir.symbols.impl.*
@@ -49,10 +51,12 @@ object FirImplementationMismatchChecker : FirClassChecker() {
val dedupReporter = reporter.deduplicating()
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) {
checkInheritanceClash(declaration, context, dedupReporter, typeCheckerContext, it)
checkValOverridesVar(declaration, context, dedupReporter, it)
checkInheritanceClash(declaration, context, dedupReporter, typeCheckerContext, it, classScope)
checkValOverridesVar(declaration, context, dedupReporter, it, classScope)
}
checkConflictingMembers(declaration, context, dedupReporter, classScope, name)
}
@@ -63,7 +67,8 @@ object FirImplementationMismatchChecker : FirClassChecker() {
context: CheckerContext,
reporter: DiagnosticReporter,
typeCheckerContext: ConeTypeCheckerContext,
symbol: FirCallableSymbol<*>
symbol: FirCallableSymbol<*>,
classScope: FirTypeScope
) {
fun reportTypeMismatch(member1: FirCallableDeclaration, member2: FirCallableDeclaration, isDelegation: Boolean) {
val error = when {
@@ -96,9 +101,15 @@ object FirImplementationMismatchChecker : FirClassChecker() {
AbstractTypeChecker.isSubtypeOf(typeCheckerContext, inheritedTypeSubstituted, baseType)
}
if (symbol.callableId.classId != containingClass.classId) return
if (symbol !is FirIntersectionCallableSymbol) return
val withTypes = symbol.intersections.map {
val intersectionSymbols = when {
symbol.fir.delegatedWrapperData != null ->
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
}
@@ -107,7 +118,7 @@ object FirImplementationMismatchChecker : FirClassChecker() {
var delegation: FirCallableDeclaration? = null
val implementations = mutableListOf<FirCallableDeclaration>()
for (intSymbol in symbol.intersections) {
for (intSymbol in intersectionSymbols) {
val fir = intSymbol.fir
if (fir.delegatedWrapperData?.containingClass?.classId == containingClass.classId) {
delegation = fir
@@ -149,24 +160,18 @@ object FirImplementationMismatchChecker : FirClassChecker() {
containingClass: FirClass,
context: CheckerContext,
reporter: DiagnosticReporter,
symbol: FirVariableSymbol<*>
symbol: FirVariableSymbol<*>,
classScope: FirTypeScope
) {
if (symbol.callableId.classId != containingClass.classId) return
if (symbol !is FirIntersectionOverridePropertySymbol) return
if (symbol !is FirPropertySymbol || symbol.fir.isVar) return
if (symbol.fir.delegatedWrapperData == null) return
val (delegates, others) = symbol.intersections.partition {
val fir = it.fir as? FirProperty ?: return@partition false
fir.isVal && fir.delegatedWrapperData?.containingClass?.classId == containingClass.classId
}
val overriddenVar =
classScope.getDirectOverriddenProperties(symbol, true)
.find { it.fir.isVar }
?: return
val delegatedVal = delegates.firstOrNull() ?: return
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)
}
reporter.reportOn(containingClass.source, FirErrors.VAR_OVERRIDDEN_BY_VAL_BY_DELEGATION, symbol.fir, overriddenVar.fir, context)
}
private fun checkConflictingMembers(
@@ -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!>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()
@@ -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 {
fun foo(): Number
}