FIR: inherit property accessor modifiers from property and vice versa
This commit is contained in:
committed by
Mikhail Glukhikh
parent
6f957c7b31
commit
f64f9c2144
+6
-4
@@ -602,7 +602,9 @@ class Fir2IrDeclarationStorage(
|
||||
Name.special("<$prefix-${correspondingProperty.name}>"),
|
||||
propertyAccessor?.visibility ?: correspondingProperty.visibility,
|
||||
correspondingProperty.modality, accessorReturnType,
|
||||
isInline = false, isExternal = false, isTailrec = false, isSuspend = false, isExpect = false,
|
||||
isInline = propertyAccessor?.isInline == true,
|
||||
isExternal = propertyAccessor?.isExternal == true,
|
||||
isTailrec = false, isSuspend = false, isExpect = false,
|
||||
isFakeOverride = origin == IrDeclarationOrigin.FAKE_OVERRIDE,
|
||||
isOperator = false
|
||||
).apply {
|
||||
@@ -659,7 +661,8 @@ class Fir2IrDeclarationStorage(
|
||||
IrFieldImpl(
|
||||
startOffset, endOffset, origin, symbol,
|
||||
name, inferredType,
|
||||
visibility, isFinal = isFinal, isExternal = false,
|
||||
visibility, isFinal = isFinal,
|
||||
isExternal = property.isExternal,
|
||||
isStatic = property.isStatic || parent !is IrClass,
|
||||
isFakeOverride = origin == IrDeclarationOrigin.FAKE_OVERRIDE
|
||||
).also {
|
||||
@@ -712,8 +715,7 @@ class Fir2IrDeclarationStorage(
|
||||
isConst = property.isConst,
|
||||
isLateinit = property.isLateInit,
|
||||
isDelegated = property.delegate != null,
|
||||
// TODO
|
||||
isExternal = false,
|
||||
isExternal = property.isExternal,
|
||||
isExpect = property.isExpect,
|
||||
isFakeOverride = origin == IrDeclarationOrigin.FAKE_OVERRIDE
|
||||
).apply {
|
||||
|
||||
+24
-11
@@ -940,16 +940,8 @@ class DeclarationsConverter(
|
||||
}
|
||||
|
||||
val propertyVisibility = modifiers.getVisibility()
|
||||
status = FirDeclarationStatusImpl(propertyVisibility, modifiers.getModality()).apply {
|
||||
isExpect = modifiers.hasExpect()
|
||||
isActual = modifiers.hasActual()
|
||||
isOverride = modifiers.hasOverride()
|
||||
isConst = modifiers.isConst()
|
||||
isLateInit = modifiers.hasLateinit()
|
||||
}
|
||||
|
||||
|
||||
val convertedAccessors = accessors.map { convertGetterOrSetter(it, returnType, propertyVisibility) }
|
||||
val convertedAccessors = accessors.map { convertGetterOrSetter(it, returnType, propertyVisibility, modifiers) }
|
||||
this.getter = convertedAccessors.find { it.isGetter }
|
||||
?: FirDefaultPropertyGetter(null, session, FirDeclarationOrigin.Source, returnType, propertyVisibility)
|
||||
this.setter =
|
||||
@@ -958,6 +950,19 @@ class DeclarationsConverter(
|
||||
?: FirDefaultPropertySetter(null, session, FirDeclarationOrigin.Source, returnType, propertyVisibility)
|
||||
} else null
|
||||
|
||||
// Upward propagation of `inline` and `external` modifiers (from accessors to property)
|
||||
// Note that, depending on `var` or `val`, checking setter's modifiers should be careful: for `val`, setter doesn't
|
||||
// exist (null); for `var`, the retrieval of the specific modifier is supposed to be `true`
|
||||
status = FirDeclarationStatusImpl(propertyVisibility, modifiers.getModality()).apply {
|
||||
isExpect = modifiers.hasExpect()
|
||||
isActual = modifiers.hasActual()
|
||||
isOverride = modifiers.hasOverride()
|
||||
isConst = modifiers.isConst()
|
||||
isLateInit = modifiers.hasLateinit()
|
||||
isInline = modifiers.hasInline() || (getter!!.isInline && setter?.isInline != false)
|
||||
isExternal = modifiers.hasExternal() || (getter!!.isExternal && setter?.isExternal != false)
|
||||
}
|
||||
|
||||
val receiver = delegateExpression?.let {
|
||||
expressionConverter.getAsFirExpression<FirExpression>(it, "Should have delegate")
|
||||
}
|
||||
@@ -1031,7 +1036,8 @@ class DeclarationsConverter(
|
||||
private fun convertGetterOrSetter(
|
||||
getterOrSetter: LighterASTNode,
|
||||
propertyTypeRef: FirTypeRef,
|
||||
propertyVisibility: Visibility
|
||||
propertyVisibility: Visibility,
|
||||
propertyModifiers: Modifier
|
||||
): FirPropertyAccessor {
|
||||
var modifiers = Modifier()
|
||||
var isGetter = true
|
||||
@@ -1060,6 +1066,12 @@ class DeclarationsConverter(
|
||||
if (accessorVisibility == Visibilities.UNKNOWN) {
|
||||
accessorVisibility = propertyVisibility
|
||||
}
|
||||
val status =
|
||||
// Downward propagation of `inline` and `external` modifiers (from property to its accessors)
|
||||
FirDeclarationStatusImpl(accessorVisibility, Modality.FINAL).apply {
|
||||
isInline = propertyModifiers.hasInline() || modifiers.hasInline()
|
||||
isExternal = propertyModifiers.hasExternal() || modifiers.hasExternal()
|
||||
}
|
||||
val sourceElement = getterOrSetter.toFirSourceElement()
|
||||
if (block == null && expression == null) {
|
||||
return FirDefaultPropertyAccessor
|
||||
@@ -1073,6 +1085,7 @@ class DeclarationsConverter(
|
||||
)
|
||||
.also {
|
||||
it.annotations += modifiers.annotations
|
||||
it.status = status
|
||||
}
|
||||
}
|
||||
val target = FirFunctionTarget(labelName = null, isLambda = false)
|
||||
@@ -1083,7 +1096,7 @@ class DeclarationsConverter(
|
||||
returnTypeRef = returnType ?: if (isGetter) propertyTypeRef else implicitUnitType
|
||||
symbol = FirPropertyAccessorSymbol()
|
||||
this.isGetter = isGetter
|
||||
status = FirDeclarationStatusImpl(accessorVisibility, Modality.FINAL)
|
||||
this.status = status
|
||||
context.firFunctionTargets += target
|
||||
annotations += modifiers.annotations
|
||||
|
||||
|
||||
@@ -261,6 +261,14 @@ class RawFirBuilder(
|
||||
): FirPropertyAccessor {
|
||||
val accessorVisibility =
|
||||
if (this?.visibility != null && this.visibility != Visibilities.UNKNOWN) this.visibility else property.visibility
|
||||
// Downward propagation of `inline` and `external` modifiers (from property to its accessors)
|
||||
val status =
|
||||
FirDeclarationStatusImpl(accessorVisibility, Modality.FINAL).apply {
|
||||
isInline = property.hasModifier(INLINE_KEYWORD) ||
|
||||
this@toFirPropertyAccessor?.hasModifier(INLINE_KEYWORD) == true
|
||||
isExternal = property.hasModifier(EXTERNAL_KEYWORD) ||
|
||||
this@toFirPropertyAccessor?.hasModifier(EXTERNAL_KEYWORD) == true
|
||||
}
|
||||
if (this == null || !hasBody()) {
|
||||
val propertySource = property.toFirSourceElement()
|
||||
return FirDefaultPropertyAccessor
|
||||
@@ -276,6 +284,7 @@ class RawFirBuilder(
|
||||
if (this != null) {
|
||||
it.extractAnnotationsFrom(this)
|
||||
}
|
||||
it.status = status
|
||||
}
|
||||
}
|
||||
val source = this.toFirSourceElement()
|
||||
@@ -290,7 +299,7 @@ class RawFirBuilder(
|
||||
returnTypeReference.toFirOrUnitType()
|
||||
}
|
||||
this.isGetter = isGetter
|
||||
status = FirDeclarationStatusImpl(accessorVisibility, Modality.FINAL)
|
||||
this.status = status
|
||||
extractAnnotationsTo(this)
|
||||
this@RawFirBuilder.context.firFunctionTargets += accessorTarget
|
||||
extractValueParametersTo(this, propertyTypeRef)
|
||||
@@ -1078,19 +1087,25 @@ class RawFirBuilder(
|
||||
expression = { delegateExpression }.toFirExpression("Should have delegate")
|
||||
}
|
||||
} else null
|
||||
|
||||
getter = this@toFirProperty.getter.toFirPropertyAccessor(this@toFirProperty, propertyType, isGetter = true)
|
||||
setter = if (isVar) {
|
||||
this@toFirProperty.setter.toFirPropertyAccessor(this@toFirProperty, propertyType, isGetter = false)
|
||||
} else null
|
||||
|
||||
// Upward propagation of `inline` and `external` modifiers (from accessors to property)
|
||||
// Note that, depending on `var` or `val`, checking setter's modifiers should be careful: for `val`, setter doesn't
|
||||
// exist (null); for `var`, the retrieval of the specific modifier is supposed to be `true`
|
||||
status = FirDeclarationStatusImpl(visibility, modality).apply {
|
||||
isExpect = hasExpectModifier()
|
||||
isActual = hasActualModifier()
|
||||
isOverride = hasModifier(OVERRIDE_KEYWORD)
|
||||
isConst = hasModifier(CONST_KEYWORD)
|
||||
isLateInit = hasModifier(LATEINIT_KEYWORD)
|
||||
isInline = hasModifier(INLINE_KEYWORD) || (getter!!.isInline && setter?.isInline != false)
|
||||
isExternal = hasModifier(EXTERNAL_KEYWORD) || (getter!!.isExternal && setter?.isExternal != false)
|
||||
}
|
||||
|
||||
getter = this@toFirProperty.getter.toFirPropertyAccessor(this@toFirProperty, propertyType, isGetter = true)
|
||||
setter = if (isVar) {
|
||||
this@toFirProperty.setter.toFirPropertyAccessor(this@toFirProperty, propertyType, isGetter = false)
|
||||
} else null
|
||||
|
||||
val receiver = delegateExpression?.toFirExpression("Should have delegate")
|
||||
generateAccessorsByDelegate(
|
||||
delegateBuilder,
|
||||
@@ -1350,6 +1365,7 @@ class RawFirBuilder(
|
||||
else -> null
|
||||
}
|
||||
val hasSubject = subjectExpression != null
|
||||
|
||||
@OptIn(FirContractViolation::class)
|
||||
val ref = FirExpressionRef<FirWhenExpression>()
|
||||
return buildWhenExpression {
|
||||
|
||||
@@ -63,6 +63,8 @@ inline val FirMemberDeclaration.isFromEnumClass: Boolean get() = status.isFromEn
|
||||
|
||||
inline val FirPropertyAccessor.modality get() = status.modality
|
||||
inline val FirPropertyAccessor.visibility get() = status.visibility
|
||||
inline val FirPropertyAccessor.isInline get() = status.isInline
|
||||
inline val FirPropertyAccessor.isExternal get() = status.isExternal
|
||||
inline val FirPropertyAccessor.allowsToHaveFakeOverride: Boolean
|
||||
get() = !Visibilities.isPrivate(visibility) && visibility != Visibilities.INVISIBLE_FAKE
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
// IGNORE_BACKEND: ANDROID
|
||||
|
||||
|
||||
+2
-2
@@ -29,12 +29,12 @@ FILE fqName:<root> fileName:/implicitCastToTypeParameter.kt
|
||||
public open fun toString (): kotlin.String declared in kotlin.Any
|
||||
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
|
||||
PROPERTY name:asT visibility:public modality:FINAL [val]
|
||||
FUN name:<get-asT> visibility:public modality:FINAL <T> ($receiver:<root>.Foo<T of <root>.<get-asT>>) returnType:T of <root>.<get-asT>?
|
||||
FUN name:<get-asT> visibility:public modality:FINAL <T> ($receiver:<root>.Foo<T of <root>.<get-asT>>) returnType:T of <root>.<get-asT>? [inline]
|
||||
correspondingProperty: PROPERTY name:asT visibility:public modality:FINAL [val]
|
||||
TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any]
|
||||
$receiver: VALUE_PARAMETER name:<this> type:<root>.Foo<T of <root>.<get-asT>>
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-asT> <T> (): T of <root>.<get-asT>? declared in <root>'
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-asT> <T> (): T of <root>.<get-asT>? [inline] declared in <root>'
|
||||
WHEN type=T of <root>.<get-asT>? origin=IF
|
||||
BRANCH
|
||||
if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=T of <root>.<get-asT>
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
FILE fqName:<root> fileName:/typeParameterClassLiteral.kt
|
||||
FUN name:classRefFun visibility:public modality:FINAL <T> () returnType:kotlin.reflect.KClass<T of <root>.classRefFun> [inline]
|
||||
TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any]
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun classRefFun <T> (): kotlin.reflect.KClass<T of <root>.classRefFun> [inline] declared in <root>'
|
||||
CLASS_REFERENCE 'TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any]' type=kotlin.reflect.KClass<T of <root>.classRefFun>
|
||||
FUN name:classRefExtFun visibility:public modality:FINAL <T> ($receiver:kotlin.Any) returnType:kotlin.reflect.KClass<T of <root>.classRefExtFun> [inline]
|
||||
TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any]
|
||||
$receiver: VALUE_PARAMETER name:<this> type:kotlin.Any
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun classRefExtFun <T> (): kotlin.reflect.KClass<T of <root>.classRefExtFun> [inline] declared in <root>'
|
||||
CLASS_REFERENCE 'TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any]' type=kotlin.reflect.KClass<T of <root>.classRefExtFun>
|
||||
PROPERTY name:classRefExtVal visibility:public modality:FINAL [val]
|
||||
FUN name:<get-classRefExtVal> visibility:public modality:FINAL <T> ($receiver:T of <root>.<get-classRefExtVal>) returnType:kotlin.reflect.KClass<T of <root>.<get-classRefExtVal>>
|
||||
correspondingProperty: PROPERTY name:classRefExtVal visibility:public modality:FINAL [val]
|
||||
TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any]
|
||||
$receiver: VALUE_PARAMETER name:<this> type:T of <root>.<get-classRefExtVal>
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-classRefExtVal> <T> (): kotlin.reflect.KClass<T of <root>.<get-classRefExtVal>> declared in <root>'
|
||||
CLASS_REFERENCE 'TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any]' type=kotlin.reflect.KClass<T of <root>.<get-classRefExtVal>>
|
||||
CLASS CLASS name:Host modality:FINAL visibility:public superTypes:[kotlin.Any]
|
||||
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.Host
|
||||
CONSTRUCTOR visibility:public <> () returnType:<root>.Host [primary]
|
||||
BLOCK_BODY
|
||||
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in kotlin.Any'
|
||||
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Host modality:FINAL visibility:public superTypes:[kotlin.Any]'
|
||||
FUN name:classRefGenericMemberFun visibility:public modality:FINAL <TF> ($this:<root>.Host) returnType:kotlin.reflect.KClass<TF of <root>.Host.classRefGenericMemberFun> [inline]
|
||||
TYPE_PARAMETER name:TF index:0 variance: superTypes:[kotlin.Any]
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.Host
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun classRefGenericMemberFun <TF> (): kotlin.reflect.KClass<TF of <root>.Host.classRefGenericMemberFun> [inline] declared in <root>.Host'
|
||||
CLASS_REFERENCE 'TYPE_PARAMETER name:TF index:0 variance: superTypes:[kotlin.Any]' type=kotlin.reflect.KClass<TF of <root>.Host.classRefGenericMemberFun>
|
||||
FUN name:classRefGenericMemberExtFun visibility:public modality:FINAL <TF> ($this:<root>.Host, $receiver:kotlin.Any) returnType:kotlin.reflect.KClass<TF of <root>.Host.classRefGenericMemberExtFun> [inline]
|
||||
TYPE_PARAMETER name:TF index:0 variance: superTypes:[kotlin.Any]
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.Host
|
||||
$receiver: VALUE_PARAMETER name:<this> type:kotlin.Any
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun classRefGenericMemberExtFun <TF> (): kotlin.reflect.KClass<TF of <root>.Host.classRefGenericMemberExtFun> [inline] declared in <root>.Host'
|
||||
CLASS_REFERENCE 'TYPE_PARAMETER name:TF index:0 variance: superTypes:[kotlin.Any]' type=kotlin.reflect.KClass<TF of <root>.Host.classRefGenericMemberExtFun>
|
||||
PROPERTY name:classRefGenericMemberExtVal visibility:public modality:FINAL [val]
|
||||
FUN name:<get-classRefGenericMemberExtVal> visibility:public modality:FINAL <TV> ($this:<root>.Host, $receiver:TV of <root>.Host.<get-classRefGenericMemberExtVal>) returnType:kotlin.reflect.KClass<TV of <root>.Host.<get-classRefGenericMemberExtVal>>
|
||||
correspondingProperty: PROPERTY name:classRefGenericMemberExtVal visibility:public modality:FINAL [val]
|
||||
TYPE_PARAMETER name:TV index:0 variance: superTypes:[kotlin.Any]
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.Host
|
||||
$receiver: VALUE_PARAMETER name:<this> type:TV of <root>.Host.<get-classRefGenericMemberExtVal>
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-classRefGenericMemberExtVal> <TV> (): kotlin.reflect.KClass<TV of <root>.Host.<get-classRefGenericMemberExtVal>> declared in <root>.Host'
|
||||
CLASS_REFERENCE 'TYPE_PARAMETER name:TV index:0 variance: superTypes:[kotlin.Any]' type=kotlin.reflect.KClass<TV of <root>.Host.<get-classRefGenericMemberExtVal>>
|
||||
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
|
||||
overridden:
|
||||
public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any
|
||||
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
|
||||
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
|
||||
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override]
|
||||
overridden:
|
||||
public open fun hashCode (): kotlin.Int declared in kotlin.Any
|
||||
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
|
||||
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override]
|
||||
overridden:
|
||||
public open fun toString (): kotlin.String declared in kotlin.Any
|
||||
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
inline fun <reified T : Any> classRefFun() = T::class
|
||||
|
||||
inline fun <reified T : Any> Any.classRefExtFun() = T::class
|
||||
|
||||
Reference in New Issue
Block a user