[FIR] Calculate property setters visibilities for intersections properly
Basically, just calculate them the same way it's done for other members. `chooseIntersectionVisibilityForSymbolsOrNull` is named like this to prevent a JVM clash. ^KT-66046 Fixed
This commit is contained in:
committed by
Space Team
parent
b7926b68ab
commit
7ecbaf7d1e
+3
-4
@@ -12,7 +12,6 @@ import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
|||||||
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||||
import org.jetbrains.kotlin.fir.java.JavaTypeParameterStack
|
import org.jetbrains.kotlin.fir.java.JavaTypeParameterStack
|
||||||
import org.jetbrains.kotlin.fir.scopes.MemberWithBaseScope
|
|
||||||
import org.jetbrains.kotlin.fir.scopes.PlatformSpecificOverridabilityRules
|
import org.jetbrains.kotlin.fir.scopes.PlatformSpecificOverridabilityRules
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||||
@@ -51,8 +50,8 @@ class JavaOverridabilityRules(session: FirSession) : PlatformSpecificOverridabil
|
|||||||
|
|
||||||
private fun FirCallableDeclaration.isOriginallyFromJava(): Boolean = unwrapFakeOverrides().origin == FirDeclarationOrigin.Enhancement
|
private fun FirCallableDeclaration.isOriginallyFromJava(): Boolean = unwrapFakeOverrides().origin == FirDeclarationOrigin.Enhancement
|
||||||
|
|
||||||
override fun <D : FirCallableSymbol<*>> chooseIntersectionVisibility(
|
override fun chooseIntersectionVisibility(
|
||||||
extractedOverrides: Collection<MemberWithBaseScope<D>>,
|
overrides: Collection<FirCallableSymbol<*>>,
|
||||||
dispatchClassSymbol: FirRegularClassSymbol?,
|
dispatchClassSymbol: FirRegularClassSymbol?,
|
||||||
): Visibility = javaOverrideChecker.chooseIntersectionVisibility(extractedOverrides, dispatchClassSymbol)
|
): Visibility = javaOverrideChecker.chooseIntersectionVisibility(overrides, dispatchClassSymbol)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,11 +25,8 @@ import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
|||||||
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
||||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
|
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.MemberWithBaseScope
|
|
||||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.FirAbstractOverrideChecker
|
import org.jetbrains.kotlin.fir.scopes.impl.*
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.chooseIntersectionVisibilityOrNull
|
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.isAbstract
|
|
||||||
import org.jetbrains.kotlin.fir.scopes.jvm.computeJvmDescriptorRepresentation
|
import org.jetbrains.kotlin.fir.scopes.jvm.computeJvmDescriptorRepresentation
|
||||||
import org.jetbrains.kotlin.fir.scopes.processOverriddenFunctions
|
import org.jetbrains.kotlin.fir.scopes.processOverriddenFunctions
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
@@ -370,25 +367,23 @@ class JavaOverrideChecker internal constructor(
|
|||||||
return overridesMutableCollectionRemove
|
return overridesMutableCollectionRemove
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun <D : FirCallableSymbol<*>> chooseIntersectionVisibility(
|
override fun chooseIntersectionVisibility(
|
||||||
extractedOverrides: Collection<MemberWithBaseScope<D>>,
|
overrides: Collection<FirCallableSymbol<*>>,
|
||||||
dispatchClassSymbol: FirRegularClassSymbol?,
|
dispatchClassSymbol: FirRegularClassSymbol?,
|
||||||
): Visibility {
|
): Visibility {
|
||||||
val nonSubsumed = extractedOverrides.getNonSubsumedNonPhantomOverriddenSymbols()
|
|
||||||
|
|
||||||
// In Java it's OK to inherit multiple implementations of the same function
|
// In Java it's OK to inherit multiple implementations of the same function
|
||||||
// from the supertypes as long as there's an implementation from a class.
|
// from the supertypes as long as there's an implementation from a class.
|
||||||
// We shouldn't reject green Java code.
|
// We shouldn't reject green Java code.
|
||||||
if (dispatchClassSymbol?.fir is FirJavaClass) {
|
if (dispatchClassSymbol?.fir is FirJavaClass) {
|
||||||
val nonAbstractFromClass = nonSubsumed.find {
|
val nonAbstractFromClass = overrides.find {
|
||||||
!it.isAbstract && it.member.dispatchReceiverClassLookupTagOrNull()
|
!it.isAbstractAccordingToRawStatus && it.dispatchReceiverClassLookupTagOrNull()
|
||||||
?.toSymbol(session)?.classKind == ClassKind.CLASS
|
?.toSymbol(session)?.classKind == ClassKind.CLASS
|
||||||
}
|
}
|
||||||
if (nonAbstractFromClass != null) {
|
if (nonAbstractFromClass != null) {
|
||||||
return nonAbstractFromClass.member.rawStatus.visibility
|
return nonAbstractFromClass.rawStatus.visibility
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return chooseIntersectionVisibilityOrNull(nonSubsumed) ?: Visibilities.Unknown
|
return chooseIntersectionVisibilityOrNull(overrides) ?: Visibilities.Unknown
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-5
@@ -14,7 +14,6 @@ import org.jetbrains.kotlin.fir.containingClassLookupTag
|
|||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirOverrideChecker
|
import org.jetbrains.kotlin.fir.scopes.FirOverrideChecker
|
||||||
import org.jetbrains.kotlin.fir.scopes.MemberWithBaseScope
|
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.*
|
import org.jetbrains.kotlin.fir.scopes.impl.*
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||||
@@ -38,12 +37,11 @@ class FirNativeOverrideChecker(private val session: FirSession) : FirOverrideChe
|
|||||||
// KT-57640: There's no necessity to implement platform-dependent overridability check for properties
|
// KT-57640: There's no necessity to implement platform-dependent overridability check for properties
|
||||||
standardOverrideChecker.isOverriddenProperty(overrideCandidate, baseDeclaration)
|
standardOverrideChecker.isOverriddenProperty(overrideCandidate, baseDeclaration)
|
||||||
|
|
||||||
override fun <D : FirCallableSymbol<*>> chooseIntersectionVisibility(
|
override fun chooseIntersectionVisibility(
|
||||||
extractedOverrides: Collection<MemberWithBaseScope<D>>,
|
overrides: Collection<FirCallableSymbol<*>>,
|
||||||
dispatchClassSymbol: FirRegularClassSymbol?,
|
dispatchClassSymbol: FirRegularClassSymbol?,
|
||||||
): Visibility {
|
): Visibility {
|
||||||
val nonSubsumed = extractedOverrides.getNonSubsumedNonPhantomOverriddenSymbols()
|
return chooseIntersectionVisibilityOrNull(overrides) { it.isAbstractAccordingToRawStatus || it.isObjCClassProperty(session) }
|
||||||
return chooseIntersectionVisibilityOrNull(nonSubsumed) { it.isAbstract || it.member.isObjCClassProperty(session) }
|
|
||||||
?: Visibilities.Unknown
|
?: Visibilities.Unknown
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-4
@@ -35,11 +35,11 @@ class FirIntersectionScopeOverrideChecker(session: FirSession) : FirOverrideChec
|
|||||||
return standardOverrideChecker.isOverriddenProperty(overrideCandidate, baseDeclaration)
|
return standardOverrideChecker.isOverriddenProperty(overrideCandidate, baseDeclaration)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun <D : FirCallableSymbol<*>> chooseIntersectionVisibility(
|
override fun chooseIntersectionVisibility(
|
||||||
extractedOverrides: Collection<MemberWithBaseScope<D>>,
|
overrides: Collection<FirCallableSymbol<*>>,
|
||||||
dispatchClassSymbol: FirRegularClassSymbol?,
|
dispatchClassSymbol: FirRegularClassSymbol?,
|
||||||
): Visibility {
|
): Visibility {
|
||||||
platformSpecificOverridabilityRules?.chooseIntersectionVisibility(extractedOverrides, dispatchClassSymbol)?.let { return it }
|
platformSpecificOverridabilityRules?.chooseIntersectionVisibility(overrides, dispatchClassSymbol)?.let { return it }
|
||||||
return standardOverrideChecker.chooseIntersectionVisibility(extractedOverrides, dispatchClassSymbol)
|
return standardOverrideChecker.chooseIntersectionVisibility(overrides, dispatchClassSymbol)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ interface FirOverrideChecker : FirSessionComponent {
|
|||||||
baseDeclaration: FirProperty
|
baseDeclaration: FirProperty
|
||||||
): Boolean
|
): Boolean
|
||||||
|
|
||||||
fun <D : FirCallableSymbol<*>> chooseIntersectionVisibility(
|
fun chooseIntersectionVisibility(
|
||||||
extractedOverrides: Collection<MemberWithBaseScope<D>>,
|
overrides: Collection<FirCallableSymbol<*>>,
|
||||||
dispatchClassSymbol: FirRegularClassSymbol?,
|
dispatchClassSymbol: FirRegularClassSymbol?,
|
||||||
): Visibility
|
): Visibility
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -26,8 +26,8 @@ interface PlatformSpecificOverridabilityRules : FirSessionComponent {
|
|||||||
baseDeclaration: FirProperty
|
baseDeclaration: FirProperty
|
||||||
): Boolean?
|
): Boolean?
|
||||||
|
|
||||||
fun <D : FirCallableSymbol<*>> chooseIntersectionVisibility(
|
fun chooseIntersectionVisibility(
|
||||||
extractedOverrides: Collection<MemberWithBaseScope<D>>,
|
overrides: Collection<FirCallableSymbol<*>>,
|
||||||
dispatchClassSymbol: FirRegularClassSymbol?,
|
dispatchClassSymbol: FirRegularClassSymbol?,
|
||||||
): Visibility?
|
): Visibility?
|
||||||
}
|
}
|
||||||
|
|||||||
+21
-13
@@ -399,6 +399,7 @@ object FirFakeOverrideGenerator {
|
|||||||
newReturnType: ConeKotlinType? = null,
|
newReturnType: ConeKotlinType? = null,
|
||||||
newModality: Modality? = null,
|
newModality: Modality? = null,
|
||||||
newVisibility: Visibility? = null,
|
newVisibility: Visibility? = null,
|
||||||
|
newSetterVisibility: Visibility? = null,
|
||||||
deferredReturnTypeCalculation: DeferredCallableCopyReturnType? = null,
|
deferredReturnTypeCalculation: DeferredCallableCopyReturnType? = null,
|
||||||
newSource: KtSourceElement? = derivedClassLookupTag?.toSymbol(session)?.source,
|
newSource: KtSourceElement? = derivedClassLookupTag?.toSymbol(session)?.source,
|
||||||
): FirProperty = buildProperty {
|
): FirProperty = buildProperty {
|
||||||
@@ -436,16 +437,19 @@ object FirFakeOverrideGenerator {
|
|||||||
newSource = newSource ?: baseProperty.getter?.source,
|
newSource = newSource ?: baseProperty.getter?.source,
|
||||||
)
|
)
|
||||||
|
|
||||||
setter = baseProperty.setter?.buildCopyIfNeeded(
|
setter = baseProperty.setter?.let { setter ->
|
||||||
moduleData = session.nullableModuleData ?: baseProperty.moduleData,
|
setter.buildCopyIfNeeded(
|
||||||
origin = origin,
|
moduleData = session.nullableModuleData ?: baseProperty.moduleData,
|
||||||
propertyReturnTypeRef = this@buildProperty.returnTypeRef,
|
origin = origin,
|
||||||
propertySymbol = newSymbol,
|
propertyReturnTypeRef = this@buildProperty.returnTypeRef,
|
||||||
dispatchReceiverType = dispatchReceiverType,
|
propertySymbol = newSymbol,
|
||||||
derivedClassLookupTag = derivedClassLookupTag,
|
dispatchReceiverType = dispatchReceiverType,
|
||||||
baseProperty = baseProperty,
|
derivedClassLookupTag = derivedClassLookupTag,
|
||||||
newSource = newSource ?: baseProperty.setter?.source,
|
baseProperty = baseProperty,
|
||||||
)
|
newSource = newSource ?: baseProperty.setter?.source,
|
||||||
|
newSetterVisibility ?: setter.visibility,
|
||||||
|
)
|
||||||
|
}
|
||||||
}.apply {
|
}.apply {
|
||||||
containingClassForStaticMemberAttr = derivedClassLookupTag.takeIf { shouldOverrideSetContainingClass(baseProperty) }
|
containingClassForStaticMemberAttr = derivedClassLookupTag.takeIf { shouldOverrideSetContainingClass(baseProperty) }
|
||||||
}
|
}
|
||||||
@@ -459,8 +463,9 @@ object FirFakeOverrideGenerator {
|
|||||||
derivedClassLookupTag: ConeClassLikeLookupTag?,
|
derivedClassLookupTag: ConeClassLikeLookupTag?,
|
||||||
baseProperty: FirProperty,
|
baseProperty: FirProperty,
|
||||||
newSource: KtSourceElement? = source,
|
newSource: KtSourceElement? = source,
|
||||||
|
newVisibility: Visibility = visibility,
|
||||||
) = when {
|
) = when {
|
||||||
annotations.isNotEmpty() || visibility != baseProperty.visibility -> buildCopy(
|
annotations.isNotEmpty() || newVisibility != baseProperty.visibility -> buildCopy(
|
||||||
moduleData,
|
moduleData,
|
||||||
origin,
|
origin,
|
||||||
propertyReturnTypeRef,
|
propertyReturnTypeRef,
|
||||||
@@ -469,6 +474,7 @@ object FirFakeOverrideGenerator {
|
|||||||
derivedClassLookupTag,
|
derivedClassLookupTag,
|
||||||
baseProperty,
|
baseProperty,
|
||||||
newSource,
|
newSource,
|
||||||
|
newVisibility,
|
||||||
)
|
)
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
@@ -482,13 +488,14 @@ object FirFakeOverrideGenerator {
|
|||||||
derivedClassLookupTag: ConeClassLikeLookupTag?,
|
derivedClassLookupTag: ConeClassLikeLookupTag?,
|
||||||
baseProperty: FirProperty,
|
baseProperty: FirProperty,
|
||||||
newSource: KtSourceElement? = source,
|
newSource: KtSourceElement? = source,
|
||||||
|
newVisibility: Visibility = visibility,
|
||||||
) = when (this) {
|
) = when (this) {
|
||||||
is FirDefaultPropertyGetter -> FirDefaultPropertyGetter(
|
is FirDefaultPropertyGetter -> FirDefaultPropertyGetter(
|
||||||
source = newSource,
|
source = newSource,
|
||||||
moduleData = moduleData,
|
moduleData = moduleData,
|
||||||
origin = origin,
|
origin = origin,
|
||||||
propertyTypeRef = propertyReturnTypeRef,
|
propertyTypeRef = propertyReturnTypeRef,
|
||||||
visibility = visibility,
|
visibility = newVisibility,
|
||||||
propertySymbol = propertySymbol,
|
propertySymbol = propertySymbol,
|
||||||
modality = modality ?: Modality.FINAL,
|
modality = modality ?: Modality.FINAL,
|
||||||
effectiveVisibility = effectiveVisibility,
|
effectiveVisibility = effectiveVisibility,
|
||||||
@@ -501,7 +508,7 @@ object FirFakeOverrideGenerator {
|
|||||||
moduleData = moduleData,
|
moduleData = moduleData,
|
||||||
origin = origin,
|
origin = origin,
|
||||||
propertyTypeRef = propertyReturnTypeRef,
|
propertyTypeRef = propertyReturnTypeRef,
|
||||||
visibility = visibility,
|
visibility = newVisibility,
|
||||||
propertySymbol = propertySymbol,
|
propertySymbol = propertySymbol,
|
||||||
modality = modality ?: Modality.FINAL,
|
modality = modality ?: Modality.FINAL,
|
||||||
effectiveVisibility = effectiveVisibility,
|
effectiveVisibility = effectiveVisibility,
|
||||||
@@ -518,6 +525,7 @@ object FirFakeOverrideGenerator {
|
|||||||
this.dispatchReceiverType = dispatchReceiverType
|
this.dispatchReceiverType = dispatchReceiverType
|
||||||
this.body = null
|
this.body = null
|
||||||
resolvePhase = origin.resolvePhaseForCopy
|
resolvePhase = origin.resolvePhaseForCopy
|
||||||
|
this.status = status.copy(visibility = newVisibility)
|
||||||
}.also {
|
}.also {
|
||||||
if (it.isSetter) {
|
if (it.isSetter) {
|
||||||
val originalParameter = it.valueParameters.first()
|
val originalParameter = it.valueParameters.first()
|
||||||
|
|||||||
+28
-13
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.declarations.utils.visibility
|
|||||||
import org.jetbrains.kotlin.fir.scopes.*
|
import org.jetbrains.kotlin.fir.scopes.*
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertyAccessorSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
||||||
import org.jetbrains.kotlin.name.StandardClassIds
|
import org.jetbrains.kotlin.name.StandardClassIds
|
||||||
|
|
||||||
@@ -64,40 +65,54 @@ fun <D : FirCallableSymbol<*>> overrides(
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline fun chooseIntersectionVisibilityOrNull(
|
inline fun chooseIntersectionVisibilityOrNull(
|
||||||
nonSubsumedOverrides: List<MemberWithBaseScope<FirCallableSymbol<*>>>,
|
nonSubsumedOverrides: Collection<FirCallableSymbol<*>>,
|
||||||
isAbstract: (MemberWithBaseScope<FirCallableSymbol<*>>) -> Boolean = MemberWithBaseScope<FirCallableSymbol<*>>::isAbstract,
|
isAbstract: (FirCallableSymbol<*>) -> Boolean = FirCallableSymbol<*>::isAbstractAccordingToRawStatus,
|
||||||
|
): Visibility? = chooseIntersectionVisibilityOrNull(
|
||||||
|
nonSubsumedOverrides,
|
||||||
|
toSymbol = { it },
|
||||||
|
isAbstract,
|
||||||
|
)
|
||||||
|
|
||||||
|
inline fun <D> chooseIntersectionVisibilityOrNull(
|
||||||
|
nonSubsumedOverrides: Collection<D>,
|
||||||
|
toSymbol: (D) -> FirCallableSymbol<*>,
|
||||||
|
isAbstract: (D) -> Boolean,
|
||||||
): Visibility? {
|
): Visibility? {
|
||||||
val nonAbstract = nonSubsumedOverrides.filter {
|
val nonAbstract = nonSubsumedOverrides.filter {
|
||||||
// Kotlin's Cloneable interface contains phantom `protected open fun clone()`.
|
// Kotlin's Cloneable interface contains phantom `protected open fun clone()`.
|
||||||
!isAbstract(it) && it.member.callableId != StandardClassIds.Callables.clone
|
!isAbstract(it) && toSymbol(it).callableId != StandardClassIds.Callables.clone
|
||||||
}
|
}
|
||||||
val allAreAbstract = nonAbstract.isEmpty()
|
val allAreAbstract = nonAbstract.isEmpty()
|
||||||
|
|
||||||
if (allAreAbstract) {
|
if (allAreAbstract) {
|
||||||
return findMaxVisibilityOrNull(nonSubsumedOverrides)
|
return findMaxVisibilityOrNull(nonSubsumedOverrides, toSymbol)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nonAbstract.singleOrNull()?.member?.rawStatus?.visibility
|
return nonAbstract.singleOrNull()?.let(toSymbol)?.rawStatus?.visibility
|
||||||
}
|
}
|
||||||
|
|
||||||
val MemberWithBaseScope<FirCallableSymbol<*>>.isAbstract: Boolean
|
val FirCallableSymbol<*>.isAbstractAccordingToRawStatus: Boolean
|
||||||
get() {
|
get() {
|
||||||
|
val responsibleDeclaration = when (this) {
|
||||||
|
!is FirPropertyAccessorSymbol -> this
|
||||||
|
else -> propertySymbol
|
||||||
|
}
|
||||||
// This function is expected to be called during FirResolvePhase.STATUS,
|
// This function is expected to be called during FirResolvePhase.STATUS,
|
||||||
// meaning we can't yet access `resolvedStatus`, because it would require
|
// meaning we can't yet access `resolvedStatus`, because it would require
|
||||||
// the same phase, but by this time we expect the statuses to have been
|
// the same phase, but by this time we expect the statuses to have been
|
||||||
// calculated de-facto.
|
// calculated de-facto.
|
||||||
require(member.rawStatus is FirResolvedDeclarationStatus)
|
require(responsibleDeclaration.rawStatus is FirResolvedDeclarationStatus)
|
||||||
// Kotlin's Cloneable interface contains phantom `protected open fun clone()`.
|
return responsibleDeclaration.rawStatus.modality == Modality.ABSTRACT
|
||||||
return member.rawStatus.modality == Modality.ABSTRACT
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <D : FirCallableSymbol<*>> findMaxVisibilityOrNull(
|
inline fun <D> findMaxVisibilityOrNull(
|
||||||
extractedOverrides: Collection<MemberWithBaseScope<D>>
|
extractedOverrides: Collection<D>,
|
||||||
|
toSymbol: (D) -> FirCallableSymbol<*>,
|
||||||
): Visibility? {
|
): Visibility? {
|
||||||
var maxVisibility: Visibility = Visibilities.Private
|
var maxVisibility: Visibility = Visibilities.Private
|
||||||
|
|
||||||
for ((override) in extractedOverrides) {
|
for (override in extractedOverrides) {
|
||||||
val visibility = (override.fir as FirMemberDeclaration).visibility
|
val visibility = (toSymbol(override).fir as FirMemberDeclaration).visibility
|
||||||
val compare = Visibilities.compare(visibility, maxVisibility) ?: return null
|
val compare = Visibilities.compare(visibility, maxVisibility) ?: return null
|
||||||
|
|
||||||
if (compare > 0) {
|
if (compare > 0) {
|
||||||
|
|||||||
+3
-5
@@ -13,7 +13,6 @@ import org.jetbrains.kotlin.fir.declarations.utils.isSuspend
|
|||||||
import org.jetbrains.kotlin.fir.declarations.utils.visibility
|
import org.jetbrains.kotlin.fir.declarations.utils.visibility
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.ensureResolvedTypeDeclaration
|
import org.jetbrains.kotlin.fir.resolve.transformers.ensureResolvedTypeDeclaration
|
||||||
import org.jetbrains.kotlin.fir.scopes.MemberWithBaseScope
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
||||||
@@ -162,11 +161,10 @@ class FirStandardOverrideChecker(private val session: FirSession) : FirAbstractO
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun <D : FirCallableSymbol<*>> chooseIntersectionVisibility(
|
override fun chooseIntersectionVisibility(
|
||||||
extractedOverrides: Collection<MemberWithBaseScope<D>>,
|
overrides: Collection<FirCallableSymbol<*>>,
|
||||||
dispatchClassSymbol: FirRegularClassSymbol?,
|
dispatchClassSymbol: FirRegularClassSymbol?,
|
||||||
): Visibility {
|
): Visibility {
|
||||||
val nonSubsumed = extractedOverrides.getNonSubsumedNonPhantomOverriddenSymbols()
|
return chooseIntersectionVisibilityOrNull(overrides) ?: Visibilities.Unknown
|
||||||
return chooseIntersectionVisibilityOrNull(nonSubsumed) ?: Visibilities.Unknown
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-2
@@ -215,7 +215,8 @@ class FirTypeIntersectionScopeContext(
|
|||||||
containsMultipleNonSubsumed: Boolean,
|
containsMultipleNonSubsumed: Boolean,
|
||||||
): MemberWithBaseScope<FirCallableSymbol<*>> {
|
): MemberWithBaseScope<FirCallableSymbol<*>> {
|
||||||
val newModality = chooseIntersectionOverrideModality(extractedOverrides.flatMap { it.flattenIntersectionsRecursively() }.nonSubsumed())
|
val newModality = chooseIntersectionOverrideModality(extractedOverrides.flatMap { it.flattenIntersectionsRecursively() }.nonSubsumed())
|
||||||
val newVisibility = overrideChecker.chooseIntersectionVisibility(extractedOverrides, dispatchClassSymbol)
|
val nonSubsumedNonPhantomOverrides = extractedOverrides.getNonSubsumedNonPhantomOverriddenSymbols().map { it.member }
|
||||||
|
val newVisibility = overrideChecker.chooseIntersectionVisibility(nonSubsumedNonPhantomOverrides, dispatchClassSymbol)
|
||||||
val mostSpecificSymbols = mostSpecific.map { it.member }
|
val mostSpecificSymbols = mostSpecific.map { it.member }
|
||||||
val extractedOverridesSymbols = extractedOverrides.map { it.member }
|
val extractedOverridesSymbols = extractedOverrides.map { it.member }
|
||||||
val key = mostSpecific.first()
|
val key = mostSpecific.first()
|
||||||
@@ -227,7 +228,8 @@ class FirTypeIntersectionScopeContext(
|
|||||||
|
|
||||||
is FirPropertySymbol ->
|
is FirPropertySymbol ->
|
||||||
createIntersectionOverrideProperty(
|
createIntersectionOverrideProperty(
|
||||||
mostSpecificSymbols, extractedOverridesSymbols, newModality, newVisibility, containsMultipleNonSubsumed
|
mostSpecificSymbols, extractedOverridesSymbols, nonSubsumedNonPhantomOverrides, newModality,
|
||||||
|
newVisibility, containsMultipleNonSubsumed,
|
||||||
)
|
)
|
||||||
|
|
||||||
is FirFieldSymbol -> {
|
is FirFieldSymbol -> {
|
||||||
@@ -368,6 +370,7 @@ class FirTypeIntersectionScopeContext(
|
|||||||
private fun createIntersectionOverrideProperty(
|
private fun createIntersectionOverrideProperty(
|
||||||
mostSpecific: Collection<FirCallableSymbol<*>>,
|
mostSpecific: Collection<FirCallableSymbol<*>>,
|
||||||
overrides: Collection<FirCallableSymbol<*>>,
|
overrides: Collection<FirCallableSymbol<*>>,
|
||||||
|
nonSubsumedNonPhantomOverrides: List<FirCallableSymbol<*>>,
|
||||||
newModality: Modality?,
|
newModality: Modality?,
|
||||||
newVisibility: Visibility,
|
newVisibility: Visibility,
|
||||||
containsMultipleNonSubsumed: Boolean,
|
containsMultipleNonSubsumed: Boolean,
|
||||||
@@ -378,6 +381,14 @@ class FirTypeIntersectionScopeContext(
|
|||||||
containsMultipleNonSubsumed,
|
containsMultipleNonSubsumed,
|
||||||
::FirIntersectionOverridePropertySymbol,
|
::FirIntersectionOverridePropertySymbol,
|
||||||
) { symbol, fir, deferredReturnTypeCalculation, returnType ->
|
) { symbol, fir, deferredReturnTypeCalculation, returnType ->
|
||||||
|
// Only setters's visibilities are calculated properly, because
|
||||||
|
// getters' visibilities must be the same as the ones of their
|
||||||
|
// properties and those we've already calculated.
|
||||||
|
val setters = nonSubsumedNonPhantomOverrides.mapNotNull {
|
||||||
|
(it as? FirPropertySymbol)?.unwrapSubstitutionOverrides()?.setterSymbol
|
||||||
|
}
|
||||||
|
val setterVisibility = chooseIntersectionVisibilityOrNull(setters) ?: Visibilities.Unknown
|
||||||
|
|
||||||
FirFakeOverrideGenerator.createCopyForFirProperty(
|
FirFakeOverrideGenerator.createCopyForFirProperty(
|
||||||
symbol, fir, derivedClassLookupTag = null, session,
|
symbol, fir, derivedClassLookupTag = null, session,
|
||||||
FirDeclarationOrigin.IntersectionOverride,
|
FirDeclarationOrigin.IntersectionOverride,
|
||||||
@@ -390,6 +401,7 @@ class FirTypeIntersectionScopeContext(
|
|||||||
// anyway and their uses should result in an overload resolution error.
|
// anyway and their uses should result in an overload resolution error.
|
||||||
newReturnType = returnType,
|
newReturnType = returnType,
|
||||||
newSource = dispatchReceiverType.toSymbol(session)?.source,
|
newSource = dispatchReceiverType.toSymbol(session)?.source,
|
||||||
|
newSetterVisibility = setterVisibility,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
-22
@@ -1,22 +0,0 @@
|
|||||||
// ISSUE: KT-66046
|
|
||||||
|
|
||||||
abstract class I1 {
|
|
||||||
abstract var a: Int
|
|
||||||
protected set
|
|
||||||
}
|
|
||||||
|
|
||||||
interface I2 {
|
|
||||||
var a: Int
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class <!CANNOT_WEAKEN_ACCESS_PRIVILEGE!>C<!> : I1(), I2
|
|
||||||
|
|
||||||
abstract class I3 {
|
|
||||||
protected abstract fun foo(): Int
|
|
||||||
}
|
|
||||||
|
|
||||||
interface I4 {
|
|
||||||
fun foo(): Int
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class B : I3(), I4
|
|
||||||
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// ISSUE: KT-66046
|
// ISSUE: KT-66046
|
||||||
|
|
||||||
abstract class I1 {
|
abstract class I1 {
|
||||||
|
|||||||
Reference in New Issue
Block a user