[FIR] Fix declaration specificity rules
Handle visibility of declarations and setters of properties
This commit is contained in:
committed by
teamcity
parent
caffe36181
commit
ff1e2c05bf
@@ -5,10 +5,14 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.scopes
|
package org.jetbrains.kotlin.fir.scopes
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
|
import org.jetbrains.kotlin.descriptors.Visibility
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.FirSessionComponent
|
import org.jetbrains.kotlin.fir.FirSessionComponent
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirPropertyAccessor
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.utils.visibility
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.buildSubstitutorForOverridesCheck
|
import org.jetbrains.kotlin.fir.scopes.impl.buildSubstitutorForOverridesCheck
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.similarFunctionsOrBothProperties
|
import org.jetbrains.kotlin.fir.scopes.impl.similarFunctionsOrBothProperties
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
@@ -124,6 +128,8 @@ class FirOverrideService(val session: FirSession) : FirSessionComponent {
|
|||||||
val aFir = a.fir
|
val aFir = a.fir
|
||||||
val bFir = b.fir
|
val bFir = b.fir
|
||||||
|
|
||||||
|
if (!isVisibilityMoreSpecific(aFir.visibility, bFir.visibility)) return false
|
||||||
|
|
||||||
val substitutor = buildSubstitutorForOverridesCheck(aFir, bFir, session) ?: return false
|
val substitutor = buildSubstitutorForOverridesCheck(aFir, bFir, session) ?: return false
|
||||||
// NB: these lines throw CCE in modularized tests when changed to just .coneType (FirImplicitTypeRef)
|
// NB: these lines throw CCE in modularized tests when changed to just .coneType (FirImplicitTypeRef)
|
||||||
val aReturnType = a.fir.returnTypeRef.coneTypeSafe<ConeKotlinType>()?.let(substitutor::substituteOrSelf) ?: return false
|
val aReturnType = a.fir.returnTypeRef.coneTypeSafe<ConeKotlinType>()?.let(substitutor::substituteOrSelf) ?: return false
|
||||||
@@ -140,7 +146,9 @@ class FirOverrideService(val session: FirSession) : FirSessionComponent {
|
|||||||
}
|
}
|
||||||
if (aFir is FirProperty) {
|
if (aFir is FirProperty) {
|
||||||
require(bFir is FirProperty) { "b is " + b.javaClass }
|
require(bFir is FirProperty) { "b is " + b.javaClass }
|
||||||
// TODO: if (!OverridingUtil.isAccessorMoreSpecific(pa.getSetter(), pb.getSetter())) return false
|
|
||||||
|
if (!isAccessorMoreSpecific(aFir.setter, bFir.setter)) return false
|
||||||
|
|
||||||
return if (aFir.isVar && bFir.isVar) {
|
return if (aFir.isVar && bFir.isVar) {
|
||||||
AbstractTypeChecker.equalTypes(typeCheckerState, aReturnType, bReturnType)
|
AbstractTypeChecker.equalTypes(typeCheckerState, aReturnType, bReturnType)
|
||||||
} else { // both vals or var vs val: val can't be more specific then var
|
} else { // both vals or var vs val: val can't be more specific then var
|
||||||
@@ -152,6 +160,16 @@ class FirOverrideService(val session: FirSession) : FirSessionComponent {
|
|||||||
|
|
||||||
private fun isTypeMoreSpecific(a: ConeKotlinType, b: ConeKotlinType, typeCheckerState: TypeCheckerState): Boolean =
|
private fun isTypeMoreSpecific(a: ConeKotlinType, b: ConeKotlinType, typeCheckerState: TypeCheckerState): Boolean =
|
||||||
AbstractTypeChecker.isSubtypeOf(typeCheckerState, a, b)
|
AbstractTypeChecker.isSubtypeOf(typeCheckerState, a, b)
|
||||||
|
|
||||||
|
private fun isAccessorMoreSpecific(a: FirPropertyAccessor?, b: FirPropertyAccessor?): Boolean {
|
||||||
|
if (a == null || b == null) return true
|
||||||
|
return isVisibilityMoreSpecific(a.visibility, b.visibility)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isVisibilityMoreSpecific(a: Visibility, b: Visibility): Boolean {
|
||||||
|
val result = Visibilities.compare(a, b)
|
||||||
|
return result == null || result >= 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val FirSession.overrideService: FirOverrideService by FirSession.sessionComponentAccessor()
|
val FirSession.overrideService: FirOverrideService by FirSession.sessionComponentAccessor()
|
||||||
|
|||||||
Reference in New Issue
Block a user