[JVM_IR] Fix accessibility bridges for static protected fields.
Super-qualifiers have to be taken into account. Otherwise, too few accessibility bridges will be generated which can lead to binary compatibility issues.
This commit is contained in:
committed by
Alexander Udalov
parent
62897a194b
commit
6a959fefd0
+47
-19
@@ -68,9 +68,11 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle
|
||||
}
|
||||
}
|
||||
|
||||
private data class FieldKey(val fieldSymbol: IrFieldSymbol, val parent: IrDeclarationParent, val superQualifierSymbol: IrClassSymbol?)
|
||||
|
||||
private val functionMap = mutableMapOf<Pair<IrFunctionSymbol, IrDeclarationParent>, IrFunctionSymbol>()
|
||||
private val getterMap = mutableMapOf<Pair<IrFieldSymbol, IrDeclarationParent>, IrSimpleFunctionSymbol>()
|
||||
private val setterMap = mutableMapOf<Pair<IrFieldSymbol, IrDeclarationParent>, IrSimpleFunctionSymbol>()
|
||||
private val getterMap = mutableMapOf<FieldKey, IrSimpleFunctionSymbol>()
|
||||
private val setterMap = mutableMapOf<FieldKey, IrSimpleFunctionSymbol>()
|
||||
|
||||
override fun visitFunctionAccess(expression: IrFunctionAccessExpression): IrExpression {
|
||||
if (expression.usesDefaultArguments()) {
|
||||
@@ -158,7 +160,9 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle
|
||||
symbol.owner.accessorParent(dispatchReceiverType?.classOrNull?.owner ?: symbol.owner.parent) as IrClass
|
||||
modifyGetterExpression(
|
||||
expression,
|
||||
getterMap.getOrPut(Pair(symbol, parent)) { makeGetterAccessorSymbol(symbol, parent) }
|
||||
getterMap.getOrPut(FieldKey(symbol, parent, expression.superQualifierSymbol)) {
|
||||
makeGetterAccessorSymbol(symbol, parent, expression.superQualifierSymbol)
|
||||
}
|
||||
)
|
||||
} else {
|
||||
expression
|
||||
@@ -175,7 +179,9 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle
|
||||
symbol.owner.accessorParent(dispatchReceiverType?.classOrNull?.owner ?: symbol.owner.parent) as IrClass
|
||||
modifySetterExpression(
|
||||
expression,
|
||||
setterMap.getOrPut(Pair(symbol, parent)) { makeSetterAccessorSymbol(symbol, parent) }
|
||||
setterMap.getOrPut(FieldKey(symbol, parent, expression.superQualifierSymbol)) {
|
||||
makeSetterAccessorSymbol(symbol, parent, expression.superQualifierSymbol)
|
||||
}
|
||||
)
|
||||
} else {
|
||||
expression
|
||||
@@ -348,12 +354,16 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle
|
||||
copyAllParamsToArgs(it, accessor)
|
||||
}
|
||||
|
||||
private fun makeGetterAccessorSymbol(fieldSymbol: IrFieldSymbol, parent: IrClass): IrSimpleFunctionSymbol =
|
||||
private fun makeGetterAccessorSymbol(
|
||||
fieldSymbol: IrFieldSymbol,
|
||||
parent: IrClass,
|
||||
superQualifierSymbol: IrClassSymbol?
|
||||
): IrSimpleFunctionSymbol =
|
||||
context.irFactory.buildFun {
|
||||
startOffset = parent.startOffset
|
||||
endOffset = parent.startOffset
|
||||
origin = JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR
|
||||
name = fieldSymbol.owner.accessorNameForGetter()
|
||||
name = fieldSymbol.owner.accessorNameForGetter(superQualifierSymbol)
|
||||
visibility = DescriptorVisibilities.PUBLIC
|
||||
modality = Modality.FINAL
|
||||
returnType = fieldSymbol.owner.type
|
||||
@@ -368,10 +378,14 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle
|
||||
)
|
||||
}
|
||||
|
||||
accessor.body = createAccessorBodyForGetter(fieldSymbol.owner, accessor)
|
||||
accessor.body = createAccessorBodyForGetter(fieldSymbol.owner, accessor, superQualifierSymbol)
|
||||
}.symbol
|
||||
|
||||
private fun createAccessorBodyForGetter(targetField: IrField, accessor: IrSimpleFunction): IrBody {
|
||||
private fun createAccessorBodyForGetter(
|
||||
targetField: IrField,
|
||||
accessor: IrSimpleFunction,
|
||||
superQualifierSymbol: IrClassSymbol?
|
||||
): IrBody {
|
||||
val maybeDispatchReceiver =
|
||||
if (targetField.isStatic) null
|
||||
else IrGetValueImpl(accessor.startOffset, accessor.endOffset, accessor.valueParameters[0].symbol)
|
||||
@@ -381,17 +395,22 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle
|
||||
accessor.startOffset, accessor.endOffset,
|
||||
targetField.symbol,
|
||||
targetField.type,
|
||||
maybeDispatchReceiver
|
||||
maybeDispatchReceiver,
|
||||
superQualifierSymbol = superQualifierSymbol
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private fun makeSetterAccessorSymbol(fieldSymbol: IrFieldSymbol, parent: IrClass): IrSimpleFunctionSymbol =
|
||||
private fun makeSetterAccessorSymbol(
|
||||
fieldSymbol: IrFieldSymbol,
|
||||
parent: IrClass,
|
||||
superQualifierSymbol: IrClassSymbol?
|
||||
): IrSimpleFunctionSymbol =
|
||||
context.irFactory.buildFun {
|
||||
startOffset = parent.startOffset
|
||||
endOffset = parent.startOffset
|
||||
origin = JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR
|
||||
name = fieldSymbol.owner.accessorNameForSetter()
|
||||
name = fieldSymbol.owner.accessorNameForSetter(superQualifierSymbol)
|
||||
visibility = DescriptorVisibilities.PUBLIC
|
||||
modality = Modality.FINAL
|
||||
returnType = context.irBuiltIns.unitType
|
||||
@@ -408,10 +427,14 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle
|
||||
|
||||
accessor.addValueParameter("<set-?>", fieldSymbol.owner.type, JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR)
|
||||
|
||||
accessor.body = createAccessorBodyForSetter(fieldSymbol.owner, accessor)
|
||||
accessor.body = createAccessorBodyForSetter(fieldSymbol.owner, accessor, superQualifierSymbol)
|
||||
}.symbol
|
||||
|
||||
private fun createAccessorBodyForSetter(targetField: IrField, accessor: IrSimpleFunction): IrBody {
|
||||
private fun createAccessorBodyForSetter(
|
||||
targetField: IrField,
|
||||
accessor: IrSimpleFunction,
|
||||
superQualifierSymbol: IrClassSymbol?
|
||||
): IrBody {
|
||||
val maybeDispatchReceiver =
|
||||
if (targetField.isStatic) null
|
||||
else IrGetValueImpl(accessor.startOffset, accessor.endOffset, accessor.valueParameters[0].symbol)
|
||||
@@ -426,7 +449,8 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle
|
||||
targetField.symbol,
|
||||
maybeDispatchReceiver,
|
||||
value,
|
||||
context.irBuiltIns.unitType
|
||||
context.irBuiltIns.unitType,
|
||||
superQualifierSymbol = superQualifierSymbol
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -565,22 +589,26 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle
|
||||
return Name.identifier("access\$$jvmName$suffix")
|
||||
}
|
||||
|
||||
private fun IrField.accessorNameForGetter(): Name {
|
||||
private fun IrField.accessorNameForGetter(superQualifierSymbol: IrClassSymbol?): Name {
|
||||
val getterName = JvmAbi.getterName(name.asString())
|
||||
return Name.identifier("access\$$getterName\$${fieldAccessorSuffix()}")
|
||||
return Name.identifier("access\$$getterName\$${fieldAccessorSuffix(superQualifierSymbol)}")
|
||||
}
|
||||
|
||||
private fun IrField.accessorNameForSetter(): Name {
|
||||
private fun IrField.accessorNameForSetter(superQualifierSymbol: IrClassSymbol?): Name {
|
||||
val setterName = JvmAbi.setterName(name.asString())
|
||||
return Name.identifier("access\$$setterName\$${fieldAccessorSuffix()}")
|
||||
return Name.identifier("access\$$setterName\$${fieldAccessorSuffix(superQualifierSymbol)}")
|
||||
}
|
||||
|
||||
private fun IrField.fieldAccessorSuffix(): String {
|
||||
private fun IrField.fieldAccessorSuffix(superQualifierSymbol: IrClassSymbol?): String {
|
||||
// Special _c_ompanion _p_roperty suffix for accessing companion backing field moved to outer
|
||||
if (origin == JvmLoweredDeclarationOrigin.COMPANION_PROPERTY_BACKING_FIELD && !parentAsClass.isCompanion) {
|
||||
return "cp"
|
||||
}
|
||||
|
||||
if (superQualifierSymbol != null) {
|
||||
return "p\$s${superQualifierSymbol.owner.syntheticAccessorToSuperSuffix()}"
|
||||
}
|
||||
|
||||
// Accesses to static protected fields that need an accessor must be due to being inherited, hence accessed on a
|
||||
// _s_upertype. If the field is static, the super class the access is on can be different and therefore
|
||||
// we generate a suffix to distinguish access to field with different receiver types in the super hierarchy.
|
||||
|
||||
Reference in New Issue
Block a user