[FIR] Fir modality of FirPropertyAccessor
^KT-61798 Fixed Review: https://jetbrains.team/p/kt/reviews/14230/timeline Q: How resolved modality of an accessor affects expect/actual matching algorithm of properties? A: It's not expect/actual matching of properties, but expect/actual matching of properties setter. Declarations (setters in our case) in actual are allowed to have wider visibility but only if the appropriate expect is `final`. Before this commit, all property accessors were always `final` by mistake. After this commit, they have the modality derived from their containingProperty. Related problem: PositionStrategy for ACTUAL_WITHOUT_EXPECT can be improved KT-65720 The fix in `resolveModality` is similar to how `resolveVisibility` works Related tests: - ConfigurationCacheForAndroidIT.testKotlinAndroidProject - FirIdeNormalAnalysisSourceModuleCombinedDeclaredMemberScopeTestGenerated.testEnumClassWithAbstractMembers - FirIdeNormalAnalysisSourceModuleCombinedDeclaredMemberScopeTestGenerated.testEnumEntryInitializerWithOverriddenMember - FirIdeNormalAnalysisSourceModuleDeclaredMemberScopeTestGenerated.testDelegateInterfaceLibrary - FirIdeNormalAnalysisSourceModuleDeclaredMemberScopeTestGenerated.testEnumClassWithAbstractMembers - FirIdeNormalAnalysisSourceModuleDeclaredMemberScopeTestGenerated.testEnumEntryInitializerWithOverriddenMember - FirIdeNormalAnalysisSourceModuleMemberScopeTestGenerated.testEnumClassWithAbstractMembers - FirIdeNormalAnalysisSourceModuleMemberScopeTestGenerated.testEnumEntryInitializerWithOverriddenMember - FirIdeNormalAnalysisSourceModuleSymbolByPsiTestGenerated.testEnumEntryOverride - FirIdeNormalAnalysisSourceModuleSymbolByPsiTestGenerated.testEnumValueMember - FirStandaloneNormalAnalysisSourceModuleCombinedDeclaredMemberScopeTestGenerated.testEnumClassWithAbstractMembers - FirStandaloneNormalAnalysisSourceModuleCombinedDeclaredMemberScopeTestGenerated.testEnumEntryInitializerWithOverriddenMember - FirStandaloneNormalAnalysisSourceModuleDeclaredMemberScopeTestGenerated.testEnumClassWithAbstractMembers - FirStandaloneNormalAnalysisSourceModuleDeclaredMemberScopeTestGenerated.testEnumEntryInitializerWithOverriddenMember - FirStandaloneNormalAnalysisSourceModuleMemberScopeTestGenerated.testEnumClassWithAbstractMembers - FirStandaloneNormalAnalysisSourceModuleMemberScopeTestGenerated.testEnumEntryInitializerWithOverriddenMember - DiagnosticCompilerTestFE10TestdataTestGenerated*testChangeSetterVisibilityInOverride
This commit is contained in:
+1
-1
@@ -73,7 +73,7 @@ KtKotlinPropertySymbol:
|
|||||||
isExtension: false
|
isExtension: false
|
||||||
isInline: false
|
isInline: false
|
||||||
isOverride: false
|
isOverride: false
|
||||||
modality: FINAL
|
modality: ABSTRACT
|
||||||
origin: SOURCE
|
origin: SOURCE
|
||||||
receiverParameter: null
|
receiverParameter: null
|
||||||
returnType: KtUsualClassType:
|
returnType: KtUsualClassType:
|
||||||
|
|||||||
+1
-1
@@ -31,7 +31,7 @@ KtKotlinPropertySymbol:
|
|||||||
isExtension: false
|
isExtension: false
|
||||||
isInline: false
|
isInline: false
|
||||||
isOverride: true
|
isOverride: true
|
||||||
modality: FINAL
|
modality: OPEN
|
||||||
origin: SOURCE
|
origin: SOURCE
|
||||||
receiverParameter: null
|
receiverParameter: null
|
||||||
returnType: KtUsualClassType:
|
returnType: KtUsualClassType:
|
||||||
|
|||||||
+6
-6
@@ -122,7 +122,7 @@ KtKotlinPropertySymbol:
|
|||||||
isExtension: false
|
isExtension: false
|
||||||
isInline: false
|
isInline: false
|
||||||
isOverride: false
|
isOverride: false
|
||||||
modality: FINAL
|
modality: OPEN
|
||||||
origin: SOURCE
|
origin: SOURCE
|
||||||
receiverParameter: null
|
receiverParameter: null
|
||||||
returnType: KtUsualClassType:
|
returnType: KtUsualClassType:
|
||||||
@@ -173,7 +173,7 @@ KtKotlinPropertySymbol:
|
|||||||
isExtension: false
|
isExtension: false
|
||||||
isInline: false
|
isInline: false
|
||||||
isOverride: false
|
isOverride: false
|
||||||
modality: FINAL
|
modality: OPEN
|
||||||
origin: SOURCE
|
origin: SOURCE
|
||||||
parameter: KtValueParameterSymbol:
|
parameter: KtValueParameterSymbol:
|
||||||
annotationsList: []
|
annotationsList: []
|
||||||
@@ -290,7 +290,7 @@ KtKotlinPropertySymbol:
|
|||||||
isExtension: false
|
isExtension: false
|
||||||
isInline: false
|
isInline: false
|
||||||
isOverride: false
|
isOverride: false
|
||||||
modality: FINAL
|
modality: OPEN
|
||||||
origin: SOURCE
|
origin: SOURCE
|
||||||
receiverParameter: KtReceiverParameterSymbol:
|
receiverParameter: KtReceiverParameterSymbol:
|
||||||
annotationsList: []
|
annotationsList: []
|
||||||
@@ -439,7 +439,7 @@ KtKotlinPropertySymbol:
|
|||||||
isExtension: false
|
isExtension: false
|
||||||
isInline: false
|
isInline: false
|
||||||
isOverride: false
|
isOverride: false
|
||||||
modality: FINAL
|
modality: OPEN
|
||||||
origin: SOURCE
|
origin: SOURCE
|
||||||
receiverParameter: null
|
receiverParameter: null
|
||||||
returnType: KtUsualClassType:
|
returnType: KtUsualClassType:
|
||||||
@@ -530,7 +530,7 @@ KtKotlinPropertySymbol:
|
|||||||
isExtension: false
|
isExtension: false
|
||||||
isInline: false
|
isInline: false
|
||||||
isOverride: false
|
isOverride: false
|
||||||
modality: FINAL
|
modality: OPEN
|
||||||
origin: SOURCE
|
origin: SOURCE
|
||||||
receiverParameter: KtReceiverParameterSymbol:
|
receiverParameter: KtReceiverParameterSymbol:
|
||||||
annotationsList: []
|
annotationsList: []
|
||||||
@@ -601,7 +601,7 @@ KtKotlinPropertySymbol:
|
|||||||
isExtension: false
|
isExtension: false
|
||||||
isInline: false
|
isInline: false
|
||||||
isOverride: false
|
isOverride: false
|
||||||
modality: FINAL
|
modality: OPEN
|
||||||
origin: SOURCE
|
origin: SOURCE
|
||||||
parameter: KtValueParameterSymbol:
|
parameter: KtValueParameterSymbol:
|
||||||
annotationsList: []
|
annotationsList: []
|
||||||
|
|||||||
+1
-1
@@ -31,7 +31,7 @@ KtKotlinPropertySymbol:
|
|||||||
isExtension: false
|
isExtension: false
|
||||||
isInline: false
|
isInline: false
|
||||||
isOverride: false
|
isOverride: false
|
||||||
modality: FINAL
|
modality: ABSTRACT
|
||||||
origin: SOURCE
|
origin: SOURCE
|
||||||
receiverParameter: null
|
receiverParameter: null
|
||||||
returnType: KtUsualClassType:
|
returnType: KtUsualClassType:
|
||||||
|
|||||||
+1
-1
@@ -31,7 +31,7 @@ KtKotlinPropertySymbol:
|
|||||||
isExtension: false
|
isExtension: false
|
||||||
isInline: false
|
isInline: false
|
||||||
isOverride: true
|
isOverride: true
|
||||||
modality: FINAL
|
modality: OPEN
|
||||||
origin: SOURCE
|
origin: SOURCE
|
||||||
receiverParameter: null
|
receiverParameter: null
|
||||||
returnType: KtUsualClassType:
|
returnType: KtUsualClassType:
|
||||||
|
|||||||
analysis/analysis-api/testData/components/scopeProvider/memberScope/enumClassWithAbstractMembers.txt
Vendored
+1
-1
@@ -31,7 +31,7 @@ KtKotlinPropertySymbol:
|
|||||||
isExtension: false
|
isExtension: false
|
||||||
isInline: false
|
isInline: false
|
||||||
isOverride: false
|
isOverride: false
|
||||||
modality: FINAL
|
modality: ABSTRACT
|
||||||
origin: SOURCE
|
origin: SOURCE
|
||||||
receiverParameter: null
|
receiverParameter: null
|
||||||
returnType: KtUsualClassType:
|
returnType: KtUsualClassType:
|
||||||
|
|||||||
+1
-1
@@ -31,7 +31,7 @@ KtKotlinPropertySymbol:
|
|||||||
isExtension: false
|
isExtension: false
|
||||||
isInline: false
|
isInline: false
|
||||||
isOverride: true
|
isOverride: true
|
||||||
modality: FINAL
|
modality: OPEN
|
||||||
origin: SOURCE
|
origin: SOURCE
|
||||||
receiverParameter: null
|
receiverParameter: null
|
||||||
returnType: KtUsualClassType:
|
returnType: KtUsualClassType:
|
||||||
|
|||||||
@@ -166,7 +166,7 @@ KtKotlinPropertySymbol:
|
|||||||
isExtension: false
|
isExtension: false
|
||||||
isInline: false
|
isInline: false
|
||||||
isOverride: true
|
isOverride: true
|
||||||
modality: FINAL
|
modality: OPEN
|
||||||
origin: SOURCE
|
origin: SOURCE
|
||||||
receiverParameter: null
|
receiverParameter: null
|
||||||
returnType: KtUsualClassType:
|
returnType: KtUsualClassType:
|
||||||
@@ -497,7 +497,7 @@ KtKotlinPropertySymbol:
|
|||||||
isExtension: false
|
isExtension: false
|
||||||
isInline: false
|
isInline: false
|
||||||
isOverride: false
|
isOverride: false
|
||||||
modality: FINAL
|
modality: OPEN
|
||||||
origin: SOURCE
|
origin: SOURCE
|
||||||
receiverParameter: null
|
receiverParameter: null
|
||||||
returnType: KtUsualClassType:
|
returnType: KtUsualClassType:
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ KtKotlinPropertySymbol:
|
|||||||
isExtension: false
|
isExtension: false
|
||||||
isInline: false
|
isInline: false
|
||||||
isOverride: true
|
isOverride: true
|
||||||
modality: FINAL
|
modality: OPEN
|
||||||
origin: SOURCE
|
origin: SOURCE
|
||||||
receiverParameter: null
|
receiverParameter: null
|
||||||
returnType: KtUsualClassType:
|
returnType: KtUsualClassType:
|
||||||
@@ -278,7 +278,7 @@ KtKotlinPropertySymbol:
|
|||||||
isExtension: false
|
isExtension: false
|
||||||
isInline: false
|
isInline: false
|
||||||
isOverride: false
|
isOverride: false
|
||||||
modality: FINAL
|
modality: ABSTRACT
|
||||||
origin: SOURCE
|
origin: SOURCE
|
||||||
receiverParameter: null
|
receiverParameter: null
|
||||||
returnType: KtUsualClassType:
|
returnType: KtUsualClassType:
|
||||||
|
|||||||
+5
-5
@@ -10,10 +10,7 @@ import org.jetbrains.kotlin.fir.FirSession
|
|||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
|
import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
|
||||||
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl
|
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.effectiveVisibility
|
import org.jetbrains.kotlin.fir.declarations.utils.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isExpect
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isOverride
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.visibility
|
|
||||||
import org.jetbrains.kotlin.fir.extensions.FirStatusTransformerExtension
|
import org.jetbrains.kotlin.fir.extensions.FirStatusTransformerExtension
|
||||||
import org.jetbrains.kotlin.fir.extensions.extensionService
|
import org.jetbrains.kotlin.fir.extensions.extensionService
|
||||||
import org.jetbrains.kotlin.fir.extensions.statusTransformerExtensions
|
import org.jetbrains.kotlin.fir.extensions.statusTransformerExtensions
|
||||||
@@ -271,7 +268,7 @@ class FirStatusResolver(
|
|||||||
} else {
|
} else {
|
||||||
it
|
it
|
||||||
}
|
}
|
||||||
} ?: resolveModality(declaration, containingClass)
|
} ?: resolveModality(declaration, containingProperty, containingClass)
|
||||||
if (overriddenStatuses.isNotEmpty()) {
|
if (overriddenStatuses.isNotEmpty()) {
|
||||||
for (modifier in MODIFIERS_FROM_OVERRIDDEN) {
|
for (modifier in MODIFIERS_FROM_OVERRIDDEN) {
|
||||||
status[modifier] = status[modifier] || overriddenStatuses.fold(false) { acc, overriddenStatus ->
|
status[modifier] = status[modifier] || overriddenStatuses.fold(false) { acc, overriddenStatus ->
|
||||||
@@ -437,11 +434,13 @@ class FirStatusResolver(
|
|||||||
|
|
||||||
private fun resolveModality(
|
private fun resolveModality(
|
||||||
declaration: FirDeclaration,
|
declaration: FirDeclaration,
|
||||||
|
containingProperty: FirProperty?,
|
||||||
containingClass: FirClass?,
|
containingClass: FirClass?,
|
||||||
): Modality {
|
): Modality {
|
||||||
return when (declaration) {
|
return when (declaration) {
|
||||||
is FirRegularClass -> if (declaration.classKind == ClassKind.INTERFACE) Modality.ABSTRACT else Modality.FINAL
|
is FirRegularClass -> if (declaration.classKind == ClassKind.INTERFACE) Modality.ABSTRACT else Modality.FINAL
|
||||||
is FirCallableDeclaration -> {
|
is FirCallableDeclaration -> {
|
||||||
|
val containingPropertyModality = containingProperty?.modality
|
||||||
when {
|
when {
|
||||||
containingClass == null -> Modality.FINAL
|
containingClass == null -> Modality.FINAL
|
||||||
containingClass.classKind == ClassKind.INTERFACE -> {
|
containingClass.classKind == ClassKind.INTERFACE -> {
|
||||||
@@ -451,6 +450,7 @@ class FirStatusResolver(
|
|||||||
else -> Modality.OPEN
|
else -> Modality.OPEN
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
declaration is FirPropertyAccessor && containingPropertyModality != null -> containingPropertyModality
|
||||||
declaration.isOverride -> Modality.OPEN
|
declaration.isOverride -> Modality.OPEN
|
||||||
else -> Modality.FINAL
|
else -> Modality.FINAL
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -12,6 +12,6 @@ open class Base {
|
|||||||
// FILE: jvm.kt
|
// FILE: jvm.kt
|
||||||
|
|
||||||
actual open class Foo : Base() {
|
actual open class Foo : Base() {
|
||||||
override var foo: String = ""
|
override var <!ACTUAL_WITHOUT_EXPECT!>foo<!>: String = ""
|
||||||
public set
|
public set
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -12,6 +12,6 @@ expect open class Foo : Base
|
|||||||
// FILE: jvm.kt
|
// FILE: jvm.kt
|
||||||
|
|
||||||
actual open class Foo : Base() {
|
actual open class Foo : Base() {
|
||||||
override var foo: String = ""
|
override var <!ACTUAL_WITHOUT_EXPECT!>foo<!>: String = ""
|
||||||
public set
|
public set
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ FILE fqName:<root> fileName:/genericClassInDifferentModule_m2.kt
|
|||||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-bar> visibility:public modality:OPEN <> ($this:<root>.Derived1<T of <root>.Derived1>) returnType:T of <root>.Derived1
|
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-bar> visibility:public modality:OPEN <> ($this:<root>.Derived1<T of <root>.Derived1>) returnType:T of <root>.Derived1
|
||||||
correspondingProperty: PROPERTY name:bar visibility:public modality:OPEN [var]
|
correspondingProperty: PROPERTY name:bar visibility:public modality:OPEN [var]
|
||||||
overridden:
|
overridden:
|
||||||
public final fun <get-bar> (): T of <root>.Base declared in <root>.Base
|
public abstract fun <get-bar> (): T of <root>.Base declared in <root>.Base
|
||||||
$this: VALUE_PARAMETER name:<this> type:<root>.Derived1<T of <root>.Derived1>
|
$this: VALUE_PARAMETER name:<this> type:<root>.Derived1<T of <root>.Derived1>
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
RETURN type=kotlin.Nothing from='public open fun <get-bar> (): T of <root>.Derived1 declared in <root>.Derived1'
|
RETURN type=kotlin.Nothing from='public open fun <get-bar> (): T of <root>.Derived1 declared in <root>.Derived1'
|
||||||
@@ -96,7 +96,7 @@ FILE fqName:<root> fileName:/genericClassInDifferentModule_m2.kt
|
|||||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<set-bar> visibility:public modality:OPEN <> ($this:<root>.Derived1<T of <root>.Derived1>, <set-?>:T of <root>.Derived1) returnType:kotlin.Unit
|
FUN DEFAULT_PROPERTY_ACCESSOR name:<set-bar> visibility:public modality:OPEN <> ($this:<root>.Derived1<T of <root>.Derived1>, <set-?>:T of <root>.Derived1) returnType:kotlin.Unit
|
||||||
correspondingProperty: PROPERTY name:bar visibility:public modality:OPEN [var]
|
correspondingProperty: PROPERTY name:bar visibility:public modality:OPEN [var]
|
||||||
overridden:
|
overridden:
|
||||||
public final fun <set-bar> (value: T of <root>.Base): kotlin.Unit declared in <root>.Base
|
public abstract fun <set-bar> (value: T of <root>.Base): kotlin.Unit declared in <root>.Base
|
||||||
$this: VALUE_PARAMETER name:<this> type:<root>.Derived1<T of <root>.Derived1>
|
$this: VALUE_PARAMETER name:<this> type:<root>.Derived1<T of <root>.Derived1>
|
||||||
VALUE_PARAMETER name:<set-?> index:0 type:T of <root>.Derived1
|
VALUE_PARAMETER name:<set-?> index:0 type:T of <root>.Derived1
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
@@ -109,7 +109,7 @@ FILE fqName:<root> fileName:/genericClassInDifferentModule_m2.kt
|
|||||||
FUN name:<get-exn> visibility:public modality:OPEN <Z> ($this:<root>.Derived1<T of <root>.Derived1>, $receiver:Z of <root>.Derived1.<get-exn>) returnType:T of <root>.Derived1
|
FUN name:<get-exn> visibility:public modality:OPEN <Z> ($this:<root>.Derived1<T of <root>.Derived1>, $receiver:Z of <root>.Derived1.<get-exn>) returnType:T of <root>.Derived1
|
||||||
correspondingProperty: PROPERTY name:exn visibility:public modality:OPEN [var]
|
correspondingProperty: PROPERTY name:exn visibility:public modality:OPEN [var]
|
||||||
overridden:
|
overridden:
|
||||||
public final fun <get-exn> <Z> (): T of <root>.Base declared in <root>.Base
|
public abstract fun <get-exn> <Z> (): T of <root>.Base declared in <root>.Base
|
||||||
TYPE_PARAMETER name:Z index:0 variance: superTypes:[kotlin.Any?] reified:false
|
TYPE_PARAMETER name:Z index:0 variance: superTypes:[kotlin.Any?] reified:false
|
||||||
$this: VALUE_PARAMETER name:<this> type:<root>.Derived1<T of <root>.Derived1>
|
$this: VALUE_PARAMETER name:<this> type:<root>.Derived1<T of <root>.Derived1>
|
||||||
$receiver: VALUE_PARAMETER name:<this> type:Z of <root>.Derived1.<get-exn>
|
$receiver: VALUE_PARAMETER name:<this> type:Z of <root>.Derived1.<get-exn>
|
||||||
@@ -120,7 +120,7 @@ FILE fqName:<root> fileName:/genericClassInDifferentModule_m2.kt
|
|||||||
FUN name:<set-exn> visibility:public modality:OPEN <Z> ($this:<root>.Derived1<T of <root>.Derived1>, $receiver:Z of <root>.Derived1.<set-exn>, value:T of <root>.Derived1) returnType:kotlin.Unit
|
FUN name:<set-exn> visibility:public modality:OPEN <Z> ($this:<root>.Derived1<T of <root>.Derived1>, $receiver:Z of <root>.Derived1.<set-exn>, value:T of <root>.Derived1) returnType:kotlin.Unit
|
||||||
correspondingProperty: PROPERTY name:exn visibility:public modality:OPEN [var]
|
correspondingProperty: PROPERTY name:exn visibility:public modality:OPEN [var]
|
||||||
overridden:
|
overridden:
|
||||||
public final fun <set-exn> <Z> (value: T of <root>.Base): kotlin.Unit declared in <root>.Base
|
public abstract fun <set-exn> <Z> (value: T of <root>.Base): kotlin.Unit declared in <root>.Base
|
||||||
TYPE_PARAMETER name:Z index:0 variance: superTypes:[kotlin.Any?] reified:false
|
TYPE_PARAMETER name:Z index:0 variance: superTypes:[kotlin.Any?] reified:false
|
||||||
$this: VALUE_PARAMETER name:<this> type:<root>.Derived1<T of <root>.Derived1>
|
$this: VALUE_PARAMETER name:<this> type:<root>.Derived1<T of <root>.Derived1>
|
||||||
$receiver: VALUE_PARAMETER name:<this> type:Z of <root>.Derived1.<set-exn>
|
$receiver: VALUE_PARAMETER name:<this> type:Z of <root>.Derived1.<set-exn>
|
||||||
|
|||||||
Reference in New Issue
Block a user