FIR: Do not load inline flag when deserializing properties; there is
no `inline` flag for serialized properties. In order to test this, I added the changes to FirRenderer to make sure the flag is not loaded. However, this revealed that the `inline` status was propagated upward to the `FirProperty` during raw FIR building, causing test failures. I removed the upward propagation for `inline`. I also removed it for `external` because it is incorrect: `external` on properties (used in JS) should be separate from `external` on accessors (used in JNI interop for JVM). The `external` flags are also serialized separately for properties and accessors.
This commit is contained in:
committed by
teamcityserver
parent
030697d430
commit
efe3f7b87e
+12
-2
@@ -57,8 +57,18 @@ internal fun FirMemberDeclaration.isEffectivelyExternal(
|
|||||||
): Boolean {
|
): Boolean {
|
||||||
if (this.isExternal) return true
|
if (this.isExternal) return true
|
||||||
|
|
||||||
// NB: [MemberDescriptor.isEffectivelyExternal] checks property accessors for property and vice versa.
|
if (this is FirPropertyAccessor) {
|
||||||
// But, raw FIR creation already did such upward/downward propagation of modifiers.
|
// Check containing property
|
||||||
|
val property = context.containingDeclarations.last() as FirProperty
|
||||||
|
return property.isEffectivelyExternal(containingClass, context)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this is FirProperty) {
|
||||||
|
// Property is effectively external if all accessors are external
|
||||||
|
if (getter?.isExternal == true && (!isVar || setter?.isExternal == true)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return containingClass != null && isInsideExternalClass(containingClass, context)
|
return containingClass != null && isInsideExternalClass(containingClass, context)
|
||||||
}
|
}
|
||||||
|
|||||||
-1
@@ -337,7 +337,6 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) {
|
|||||||
isOverride = false
|
isOverride = false
|
||||||
isConst = Flags.IS_CONST.get(flags)
|
isConst = Flags.IS_CONST.get(flags)
|
||||||
isLateInit = Flags.IS_LATEINIT.get(flags)
|
isLateInit = Flags.IS_LATEINIT.get(flags)
|
||||||
isInline = Flags.IS_INLINE.get(flags)
|
|
||||||
isExternal = Flags.IS_EXTERNAL_PROPERTY.get(flags)
|
isExternal = Flags.IS_EXTERNAL_PROPERTY.get(flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-5
@@ -1099,17 +1099,13 @@ class DeclarationsConverter(
|
|||||||
}
|
}
|
||||||
} else null
|
} 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(isClassOrObject = false)).apply {
|
status = FirDeclarationStatusImpl(propertyVisibility, modifiers.getModality(isClassOrObject = false)).apply {
|
||||||
isExpect = modifiers.hasExpect() || classWrapper?.hasExpect() == true
|
isExpect = modifiers.hasExpect() || classWrapper?.hasExpect() == true
|
||||||
isActual = modifiers.hasActual()
|
isActual = modifiers.hasActual()
|
||||||
isOverride = modifiers.hasOverride()
|
isOverride = modifiers.hasOverride()
|
||||||
isConst = modifiers.isConst()
|
isConst = modifiers.isConst()
|
||||||
isLateInit = modifiers.hasLateinit()
|
isLateInit = modifiers.hasLateinit()
|
||||||
isInline = modifiers.hasInline() || (getter!!.isInline && setter?.isInline != false)
|
isExternal = modifiers.hasExternal()
|
||||||
isExternal = modifiers.hasExternal() || (getter!!.isExternal && setter?.isExternal != false)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val receiver = delegateExpression?.let {
|
val receiver = delegateExpression?.let {
|
||||||
|
|||||||
@@ -1341,17 +1341,13 @@ open class RawFirBuilder(
|
|||||||
getter = this@toFirProperty.getter.toFirPropertyAccessor(this@toFirProperty, propertyType, isGetter = true)
|
getter = this@toFirProperty.getter.toFirPropertyAccessor(this@toFirProperty, propertyType, isGetter = true)
|
||||||
setter = this@toFirProperty.setter.toFirPropertyAccessor(this@toFirProperty, propertyType, isGetter = false)
|
setter = this@toFirProperty.setter.toFirPropertyAccessor(this@toFirProperty, propertyType, isGetter = false)
|
||||||
|
|
||||||
// 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 {
|
status = FirDeclarationStatusImpl(visibility, modality).apply {
|
||||||
isExpect = hasExpectModifier() || containingClassOrObject?.hasExpectModifier() == true
|
isExpect = hasExpectModifier() || containingClassOrObject?.hasExpectModifier() == true
|
||||||
isActual = hasActualModifier()
|
isActual = hasActualModifier()
|
||||||
isOverride = hasModifier(OVERRIDE_KEYWORD)
|
isOverride = hasModifier(OVERRIDE_KEYWORD)
|
||||||
isConst = hasModifier(CONST_KEYWORD)
|
isConst = hasModifier(CONST_KEYWORD)
|
||||||
isLateInit = hasModifier(LATEINIT_KEYWORD)
|
isLateInit = hasModifier(LATEINIT_KEYWORD)
|
||||||
isInline = hasModifier(INLINE_KEYWORD) || (getter!!.isInline && setter?.isInline != false)
|
isExternal = hasModifier(EXTERNAL_KEYWORD)
|
||||||
isExternal = hasModifier(EXTERNAL_KEYWORD) || (getter!!.isExternal && setter?.isExternal != false)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val receiver = delegateExpression?.toFirExpression("Should have delegate")
|
val receiver = delegateExpression?.toFirExpression("Should have delegate")
|
||||||
|
|||||||
+1
-1
@@ -20,6 +20,6 @@ FILE: external.kt
|
|||||||
public? set(value: Int): R|kotlin/Unit| { LAZY_BLOCK }
|
public? set(value: Int): R|kotlin/Unit| { LAZY_BLOCK }
|
||||||
|
|
||||||
}
|
}
|
||||||
public? final? external var z: Int
|
public? final? var z: Int
|
||||||
public? external get(): Int
|
public? external get(): Int
|
||||||
public? external set(value: Int): R|kotlin/Unit|
|
public? external set(value: Int): R|kotlin/Unit|
|
||||||
|
|||||||
@@ -21,6 +21,6 @@ FILE: external.kt
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
public? final? external var z: Int
|
public? final? var z: Int
|
||||||
public? external get(): Int
|
public? external get(): Int
|
||||||
public? external set(value: Int): R|kotlin/Unit|
|
public? external set(value: Int): R|kotlin/Unit|
|
||||||
|
|||||||
@@ -314,50 +314,45 @@ class FirRenderer(builder: StringBuilder, private val mode: RenderMode = RenderM
|
|||||||
if (memberDeclaration.isExternal) {
|
if (memberDeclaration.isExternal) {
|
||||||
print("external ")
|
print("external ")
|
||||||
}
|
}
|
||||||
if (memberDeclaration is FirCallableMemberDeclaration<*>) {
|
if (memberDeclaration.isOverride) {
|
||||||
if (memberDeclaration.isOverride) {
|
print("override ")
|
||||||
print("override ")
|
|
||||||
}
|
|
||||||
if (memberDeclaration.isStatic) {
|
|
||||||
print("static ")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (memberDeclaration is FirRegularClass) {
|
if (memberDeclaration.isStatic) {
|
||||||
if (memberDeclaration.isInner) {
|
print("static ")
|
||||||
print("inner ")
|
}
|
||||||
}
|
if (memberDeclaration.isInner) {
|
||||||
if (memberDeclaration.isCompanion) {
|
print("inner ")
|
||||||
print("companion ")
|
}
|
||||||
}
|
|
||||||
if (memberDeclaration.isData) {
|
// `companion/data` modifiers are only valid for FirRegularClass, but we render them to make sure they are not
|
||||||
print("data ")
|
// incorrectly loaded for other declarations during deserialization.
|
||||||
}
|
if (memberDeclaration.status.isCompanion) {
|
||||||
if (memberDeclaration.isInline) {
|
print("companion ")
|
||||||
print("inline ")
|
}
|
||||||
}
|
if (memberDeclaration.status.isData) {
|
||||||
} else if (memberDeclaration is FirSimpleFunction) {
|
print("data ")
|
||||||
if (memberDeclaration.isOperator) {
|
}
|
||||||
print("operator ")
|
|
||||||
}
|
if (memberDeclaration.isInline) {
|
||||||
if (memberDeclaration.isInfix) {
|
print("inline ")
|
||||||
print("infix ")
|
}
|
||||||
}
|
if (memberDeclaration.isOperator) {
|
||||||
if (memberDeclaration.isInline) {
|
print("operator ")
|
||||||
print("inline ")
|
}
|
||||||
}
|
if (memberDeclaration.isInfix) {
|
||||||
if (memberDeclaration.isTailRec) {
|
print("infix ")
|
||||||
print("tailrec ")
|
}
|
||||||
}
|
if (memberDeclaration.isTailRec) {
|
||||||
if (memberDeclaration.isSuspend) {
|
print("tailrec ")
|
||||||
print("suspend ")
|
}
|
||||||
}
|
if (memberDeclaration.isSuspend) {
|
||||||
} else if (memberDeclaration is FirProperty) {
|
print("suspend ")
|
||||||
if (memberDeclaration.isConst) {
|
}
|
||||||
print("const ")
|
if (memberDeclaration.isConst) {
|
||||||
}
|
print("const ")
|
||||||
if (memberDeclaration.isLateInit) {
|
}
|
||||||
print("lateinit ")
|
if (memberDeclaration.isLateInit) {
|
||||||
}
|
print("lateinit ")
|
||||||
}
|
}
|
||||||
|
|
||||||
visitDeclaration(memberDeclaration)
|
visitDeclaration(memberDeclaration)
|
||||||
|
|||||||
@@ -49,16 +49,13 @@ inline val FirClass<*>.isEnumClass: Boolean
|
|||||||
inline val FirRegularClass.modality get() = status.modality
|
inline val FirRegularClass.modality get() = status.modality
|
||||||
inline val FirRegularClass.isSealed get() = status.modality == Modality.SEALED
|
inline val FirRegularClass.isSealed get() = status.modality == Modality.SEALED
|
||||||
inline val FirRegularClass.isAbstract get() = status.modality == Modality.ABSTRACT
|
inline val FirRegularClass.isAbstract get() = status.modality == Modality.ABSTRACT
|
||||||
|
inline val FirRegularClass.isFun get() = status.isFun
|
||||||
|
inline val FirRegularClass.isCompanion get() = status.isCompanion
|
||||||
|
inline val FirRegularClass.isData get() = status.isData
|
||||||
|
|
||||||
inline val FirRegularClass.canHaveAbstractDeclaration: Boolean
|
inline val FirRegularClass.canHaveAbstractDeclaration: Boolean
|
||||||
get() = isAbstract || isSealed || isEnumClass
|
get() = isAbstract || isSealed || isEnumClass
|
||||||
|
|
||||||
inline val FirRegularClass.isInner get() = status.isInner
|
|
||||||
inline val FirRegularClass.isCompanion get() = status.isCompanion
|
|
||||||
inline val FirRegularClass.isData get() = status.isData
|
|
||||||
inline val FirRegularClass.isInline get() = status.isInline
|
|
||||||
inline val FirRegularClass.isFun get() = status.isFun
|
|
||||||
|
|
||||||
inline val FirMemberDeclaration.modality get() = status.modality
|
inline val FirMemberDeclaration.modality get() = status.modality
|
||||||
inline val FirMemberDeclaration.isAbstract get() = status.modality == Modality.ABSTRACT
|
inline val FirMemberDeclaration.isAbstract get() = status.modality == Modality.ABSTRACT
|
||||||
inline val FirMemberDeclaration.isOpen get() = status.modality == Modality.OPEN
|
inline val FirMemberDeclaration.isOpen get() = status.modality == Modality.OPEN
|
||||||
@@ -92,7 +89,6 @@ inline val FirMemberDeclaration.isConst: Boolean get() = status.isConst
|
|||||||
inline val FirMemberDeclaration.isLateInit: Boolean get() = status.isLateInit
|
inline val FirMemberDeclaration.isLateInit: Boolean get() = status.isLateInit
|
||||||
inline val FirMemberDeclaration.isFromSealedClass: Boolean get() = status.isFromSealedClass
|
inline val FirMemberDeclaration.isFromSealedClass: Boolean get() = status.isFromSealedClass
|
||||||
inline val FirMemberDeclaration.isFromEnumClass: Boolean get() = status.isFromEnumClass
|
inline val FirMemberDeclaration.isFromEnumClass: Boolean get() = status.isFromEnumClass
|
||||||
inline val FirMemberDeclaration.isFun: Boolean get() = status.isFun
|
|
||||||
|
|
||||||
inline val FirFunction<*>.hasBody get() = body != null
|
inline val FirFunction<*>.hasBody get() = body != null
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user