FIR: Use refined visibility/modality for intersection overrides
This commit is contained in:
+20
-8
@@ -5,11 +5,13 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.scopes.impl
|
package org.jetbrains.kotlin.fir.scopes.impl
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
|
import org.jetbrains.kotlin.descriptors.Visibility
|
||||||
import org.jetbrains.kotlin.fir.*
|
import org.jetbrains.kotlin.fir.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.builder.*
|
import org.jetbrains.kotlin.fir.declarations.builder.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl
|
import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
|
||||||
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
|
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
|
||||||
import org.jetbrains.kotlin.fir.declarations.synthetic.buildSyntheticProperty
|
import org.jetbrains.kotlin.fir.declarations.synthetic.buildSyntheticProperty
|
||||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||||
@@ -316,14 +318,16 @@ class FirClassSubstitutionScope(
|
|||||||
newParameterTypes: List<ConeKotlinType?>? = null,
|
newParameterTypes: List<ConeKotlinType?>? = null,
|
||||||
newTypeParameters: List<FirTypeParameter>? = null,
|
newTypeParameters: List<FirTypeParameter>? = null,
|
||||||
newReceiverType: ConeKotlinType? = null,
|
newReceiverType: ConeKotlinType? = null,
|
||||||
newReturnType: ConeKotlinType? = null
|
newReturnType: ConeKotlinType? = null,
|
||||||
|
newModality: Modality? = null,
|
||||||
|
newVisibility: Visibility? = null,
|
||||||
): FirSimpleFunction {
|
): FirSimpleFunction {
|
||||||
return buildSimpleFunction {
|
return buildSimpleFunction {
|
||||||
source = baseFunction.source
|
source = baseFunction.source
|
||||||
this.session = session
|
this.session = session
|
||||||
this.origin = origin
|
this.origin = origin
|
||||||
name = baseFunction.name
|
name = baseFunction.name
|
||||||
status = baseFunction.status.withExpect(isExpect)
|
status = baseFunction.status.updatedStatus(isExpect, newModality, newVisibility)
|
||||||
symbol = newSymbol
|
symbol = newSymbol
|
||||||
resolvePhase = baseFunction.resolvePhase
|
resolvePhase = baseFunction.resolvePhase
|
||||||
|
|
||||||
@@ -349,7 +353,7 @@ class FirClassSubstitutionScope(
|
|||||||
this.session = session
|
this.session = session
|
||||||
origin = FirDeclarationOrigin.FakeOverride
|
origin = FirDeclarationOrigin.FakeOverride
|
||||||
receiverTypeRef = baseConstructor.receiverTypeRef?.withReplacedConeType(null)
|
receiverTypeRef = baseConstructor.receiverTypeRef?.withReplacedConeType(null)
|
||||||
status = baseConstructor.status.withExpect(isExpect)
|
status = baseConstructor.status.updatedStatus(isExpect)
|
||||||
symbol = fakeOverrideSymbol
|
symbol = fakeOverrideSymbol
|
||||||
resolvePhase = baseConstructor.resolvePhase
|
resolvePhase = baseConstructor.resolvePhase
|
||||||
|
|
||||||
@@ -452,6 +456,8 @@ class FirClassSubstitutionScope(
|
|||||||
newTypeParameters: List<FirTypeParameter>? = null,
|
newTypeParameters: List<FirTypeParameter>? = null,
|
||||||
newReceiverType: ConeKotlinType? = null,
|
newReceiverType: ConeKotlinType? = null,
|
||||||
newReturnType: ConeKotlinType? = null,
|
newReturnType: ConeKotlinType? = null,
|
||||||
|
newModality: Modality? = null,
|
||||||
|
newVisibility: Visibility? = null,
|
||||||
): FirProperty {
|
): FirProperty {
|
||||||
return buildProperty {
|
return buildProperty {
|
||||||
source = baseProperty.source
|
source = baseProperty.source
|
||||||
@@ -461,7 +467,8 @@ class FirClassSubstitutionScope(
|
|||||||
isVar = baseProperty.isVar
|
isVar = baseProperty.isVar
|
||||||
this.symbol = newSymbol
|
this.symbol = newSymbol
|
||||||
isLocal = false
|
isLocal = false
|
||||||
status = baseProperty.status.withExpect(isExpect)
|
status = baseProperty.status.updatedStatus(isExpect, newModality, newVisibility)
|
||||||
|
|
||||||
resolvePhase = baseProperty.resolvePhase
|
resolvePhase = baseProperty.resolvePhase
|
||||||
typeParameters += configureAnnotationsTypeParametersAndSignature(
|
typeParameters += configureAnnotationsTypeParametersAndSignature(
|
||||||
baseProperty,
|
baseProperty,
|
||||||
@@ -574,11 +581,16 @@ class FirClassSubstitutionScope(
|
|||||||
}.symbol
|
}.symbol
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FirDeclarationStatus.withExpect(isExpect: Boolean): FirDeclarationStatus {
|
private fun FirDeclarationStatus.updatedStatus(
|
||||||
return if (this.isExpect == isExpect) {
|
isExpect: Boolean,
|
||||||
|
newModality: Modality? = null,
|
||||||
|
newVisibility: Visibility? = null,
|
||||||
|
): FirDeclarationStatus {
|
||||||
|
return if (this.isExpect == isExpect && newModality == null && newVisibility == null) {
|
||||||
this
|
this
|
||||||
} else {
|
} else {
|
||||||
FirResolvedDeclarationStatusImpl(visibility, modality!!).apply {
|
require(this is FirDeclarationStatusImpl) { "Unexpected class ${this::class}" }
|
||||||
|
this.resolved(newVisibility ?: visibility, newModality ?: modality!!).apply {
|
||||||
this.isExpect = isExpect
|
this.isExpect = isExpect
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+47
-11
@@ -5,8 +5,10 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.scopes.impl
|
package org.jetbrains.kotlin.fir.scopes.impl
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
|
import org.jetbrains.kotlin.descriptors.Visibility
|
||||||
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirOverrideChecker
|
import org.jetbrains.kotlin.fir.scopes.FirOverrideChecker
|
||||||
@@ -38,7 +40,8 @@ class FirTypeIntersectionScope private constructor(
|
|||||||
|
|
||||||
private val typeContext = ConeTypeCheckerContext(isErrorTypeEqualsToAnything = false, isStubTypeEqualsToAnything = false, session)
|
private val typeContext = ConeTypeCheckerContext(isErrorTypeEqualsToAnything = false, isStubTypeEqualsToAnything = false, session)
|
||||||
|
|
||||||
private val overriddenSymbols: MutableMap<FirCallableSymbol<*>, Collection<MemberWithBaseScope<out FirCallableSymbol<*>>>> = mutableMapOf()
|
private val overriddenSymbols: MutableMap<FirCallableSymbol<*>, Collection<MemberWithBaseScope<out FirCallableSymbol<*>>>> =
|
||||||
|
mutableMapOf()
|
||||||
|
|
||||||
private val intersectionOverrides: MutableMap<FirCallableSymbol<*>, MemberWithBaseScope<out FirCallableSymbol<*>>> = mutableMapOf()
|
private val intersectionOverrides: MutableMap<FirCallableSymbol<*>, MemberWithBaseScope<out FirCallableSymbol<*>>> = mutableMapOf()
|
||||||
|
|
||||||
@@ -97,21 +100,23 @@ class FirTypeIntersectionScope private constructor(
|
|||||||
|
|
||||||
while (allMembersWithScope.isNotEmpty()) {
|
while (allMembersWithScope.isNotEmpty()) {
|
||||||
val maxByVisibility = findMemberWithMaxVisibility(allMembersWithScope)
|
val maxByVisibility = findMemberWithMaxVisibility(allMembersWithScope)
|
||||||
val extractedOverrides = extractBothWaysOverridable(maxByVisibility, allMembersWithScope)
|
val extractBothWaysWithPrivate = extractBothWaysOverridable(maxByVisibility, allMembersWithScope)
|
||||||
|
val extractedOverrides = extractBothWaysWithPrivate.filterNot {
|
||||||
|
Visibilities.isPrivate((it.member.fir as FirMemberDeclaration).visibility)
|
||||||
|
}.takeIf { it.isNotEmpty() } ?: extractBothWaysWithPrivate
|
||||||
|
|
||||||
val (mostSpecific, scopeForMostSpecific) = selectMostSpecificMember(extractedOverrides)
|
val (mostSpecific, scopeForMostSpecific) = selectMostSpecificMember(extractedOverrides)
|
||||||
if (extractedOverrides.size > 1) {
|
if (extractedOverrides.size > 1) {
|
||||||
val intersectionOverride = intersectionOverrides.getOrPut(mostSpecific) {
|
val intersectionOverride = intersectionOverrides.getOrPut(mostSpecific) {
|
||||||
|
val newModality = chooseIntersectionOverrideModality(extractedOverrides)
|
||||||
|
val newVisibility = chooseIntersectionVisibility(extractedOverrides)
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
when (mostSpecific) {
|
when (mostSpecific) {
|
||||||
is FirNamedFunctionSymbol -> {
|
is FirNamedFunctionSymbol -> {
|
||||||
createIntersectionOverride(
|
createIntersectionOverride(mostSpecific, newModality, newVisibility)
|
||||||
mostSpecific,
|
|
||||||
extractedOverrides as Collection<MemberWithBaseScope<FirNamedFunctionSymbol>>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
is FirPropertySymbol -> {
|
is FirPropertySymbol -> {
|
||||||
createIntersectionOverride(mostSpecific)
|
createIntersectionOverride(mostSpecific, newModality, newVisibility)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
throw IllegalStateException("Should not be here")
|
throw IllegalStateException("Should not be here")
|
||||||
@@ -130,9 +135,32 @@ class FirTypeIntersectionScope private constructor(
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun <D : FirCallableSymbol<*>> chooseIntersectionOverrideModality(
|
||||||
|
extractedOverrides: Collection<MemberWithBaseScope<D>>
|
||||||
|
): Modality {
|
||||||
|
return extractedOverrides.minOf { (it.member.fir as FirMemberDeclaration).modality ?: Modality.ABSTRACT }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun <D : FirCallableSymbol<*>> chooseIntersectionVisibility(
|
||||||
|
extractedOverrides: Collection<MemberWithBaseScope<D>>
|
||||||
|
): Visibility {
|
||||||
|
var maxVisibility: Visibility = Visibilities.Private
|
||||||
|
for ((override) in extractedOverrides) {
|
||||||
|
val visibility = (override.fir as FirMemberDeclaration).visibility
|
||||||
|
// TODO: There is more complex logic at org.jetbrains.kotlin.resolve.OverridingUtil.resolveUnknownVisibilityForMember
|
||||||
|
// TODO: and org.jetbrains.kotlin.resolve.OverridingUtil.findMaxVisibility
|
||||||
|
val compare = Visibilities.compare(visibility, maxVisibility) ?: return Visibilities.DEFAULT_VISIBILITY
|
||||||
|
if (compare > 0) {
|
||||||
|
maxVisibility = visibility
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return maxVisibility
|
||||||
|
}
|
||||||
|
|
||||||
private fun createIntersectionOverride(
|
private fun createIntersectionOverride(
|
||||||
mostSpecific: FirNamedFunctionSymbol,
|
mostSpecific: FirNamedFunctionSymbol,
|
||||||
extractedOverrides: Collection<MemberWithBaseScope<FirNamedFunctionSymbol>>
|
newModality: Modality,
|
||||||
|
newVisibility: Visibility,
|
||||||
): FirNamedFunctionSymbol {
|
): FirNamedFunctionSymbol {
|
||||||
val newSymbol =
|
val newSymbol =
|
||||||
FirNamedFunctionSymbol(
|
FirNamedFunctionSymbol(
|
||||||
@@ -146,15 +174,23 @@ class FirTypeIntersectionScope private constructor(
|
|||||||
newSymbol,
|
newSymbol,
|
||||||
mostSpecificFunction, session, FirDeclarationOrigin.IntersectionOverride,
|
mostSpecificFunction, session, FirDeclarationOrigin.IntersectionOverride,
|
||||||
mostSpecificFunction.isExpect,
|
mostSpecificFunction.isExpect,
|
||||||
|
newModality = newModality,
|
||||||
|
newVisibility = newVisibility,
|
||||||
)
|
)
|
||||||
return newSymbol
|
return newSymbol
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createIntersectionOverride(mostSpecific: FirPropertySymbol): FirPropertySymbol {
|
private fun createIntersectionOverride(
|
||||||
|
mostSpecific: FirPropertySymbol,
|
||||||
|
newModality: Modality,
|
||||||
|
newVisibility: Visibility,
|
||||||
|
): FirPropertySymbol {
|
||||||
val newSymbol = FirPropertySymbol(mostSpecific.callableId, mostSpecific.isFakeOverride, mostSpecific, isIntersectionOverride = true)
|
val newSymbol = FirPropertySymbol(mostSpecific.callableId, mostSpecific.isFakeOverride, mostSpecific, isIntersectionOverride = true)
|
||||||
val mostSpecificProperty = mostSpecific.fir
|
val mostSpecificProperty = mostSpecific.fir
|
||||||
FirClassSubstitutionScope.createCopyForFirProperty(
|
FirClassSubstitutionScope.createCopyForFirProperty(
|
||||||
newSymbol, mostSpecificProperty, mostSpecificProperty.session
|
newSymbol, mostSpecificProperty, mostSpecificProperty.session,
|
||||||
|
newModality = newModality,
|
||||||
|
newVisibility = newVisibility,
|
||||||
)
|
)
|
||||||
return newSymbol
|
return newSymbol
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -166,7 +166,7 @@ open class FirDeclarationStatusImpl(
|
|||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
fun resolved(visibility: Visibility, modality: Modality): FirDeclarationStatus {
|
fun resolved(visibility: Visibility, modality: Modality): FirResolvedDeclarationStatusImpl {
|
||||||
return FirResolvedDeclarationStatusImpl(visibility, modality, flags)
|
return FirResolvedDeclarationStatusImpl(visibility, modality, flags)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user