Properly link properties and their getter/setters.
This allows removing a hack in the MethodSignatureMapper. When introducing non-getter methods that dispatch to a getter we have to be careful to use the right name. DeepCopyIrTreeWithSymbols should create the link between new properties and their new getter/setter.
This commit is contained in:
committed by
Alexander Udalov
parent
ac11bc6710
commit
8bc360fa0c
+1
-16
@@ -92,22 +92,7 @@ class MethodSignatureMapper(private val context: JvmBackendContext) {
|
|||||||
return mangleMemberNameIfRequired(accessorName, function)
|
return mangleMemberNameIfRequired(accessorName, function)
|
||||||
}
|
}
|
||||||
|
|
||||||
val functionName = workaroundPropertyAccessorName(function) ?: function.name.asString()
|
return mangleMemberNameIfRequired(function.name.asString(), function)
|
||||||
return mangleMemberNameIfRequired(functionName, function)
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is a dirty hack which is needed to correctly map names of property accessors whose correspondingPropertySymbol was lost.
|
|
||||||
// The reason it's needed is that it sometimes gets lost during DeepCopyIrTreeWithSymbols because that algorithm doesn't copy
|
|
||||||
// the link to the property when transforming a simple function. This can be fixed but might require a lot of changes in backends,
|
|
||||||
// and will likely be unneeded as soon as we have proper properties in the IR (IrProperty which is a declaration parent).
|
|
||||||
// TODO: remove this hack as soon as IrProperty is a declaration parent
|
|
||||||
private fun workaroundPropertyAccessorName(function: IrFunction): String? {
|
|
||||||
val name = function.name.asString()
|
|
||||||
val ifGetter = name.removeSurrounding("<get-", ">")
|
|
||||||
if (ifGetter != name) return JvmAbi.getterName(ifGetter)
|
|
||||||
val ifSetter = name.removeSurrounding("<set-", ">")
|
|
||||||
if (ifSetter != name) return JvmAbi.setterName(ifSetter)
|
|
||||||
return null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun mangleMemberNameIfRequired(name: String, function: IrFunction): String {
|
private fun mangleMemberNameIfRequired(name: String, function: IrFunction): String {
|
||||||
|
|||||||
@@ -341,6 +341,14 @@ private class BridgeLowering(val context: JvmBackendContext) : FileLoweringPass,
|
|||||||
returnType = irFunction.returnType
|
returnType = irFunction.returnType
|
||||||
isFakeOverride = false
|
isFakeOverride = false
|
||||||
}.apply {
|
}.apply {
|
||||||
|
// If the function is a property accessor, link in the new function as the new accessor for the property.
|
||||||
|
correspondingPropertySymbol = irFunction.correspondingPropertySymbol?.also {
|
||||||
|
if (irFunction.isGetter) {
|
||||||
|
it.owner.getter = this
|
||||||
|
} else {
|
||||||
|
it.owner.setter = this
|
||||||
|
}
|
||||||
|
}
|
||||||
copyParametersWithErasure(this@addAbstractMethodStub, irFunction, needsArgumentBoxing)
|
copyParametersWithErasure(this@addAbstractMethodStub, irFunction, needsArgumentBoxing)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+9
-1
@@ -41,6 +41,7 @@ import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
|||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
import org.jetbrains.kotlin.load.java.JavaVisibilities
|
import org.jetbrains.kotlin.load.java.JavaVisibilities
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||||
|
|
||||||
internal val generateMultifileFacadesPhase = namedIrModulePhase(
|
internal val generateMultifileFacadesPhase = namedIrModulePhase(
|
||||||
@@ -217,7 +218,14 @@ private fun IrSimpleFunction.createMultifileDelegateIfNeeded(
|
|||||||
val function = buildFun {
|
val function = buildFun {
|
||||||
updateFrom(target)
|
updateFrom(target)
|
||||||
isFakeOverride = shouldGeneratePartHierarchy
|
isFakeOverride = shouldGeneratePartHierarchy
|
||||||
name = target.name
|
name = if (shouldGeneratePartHierarchy) {
|
||||||
|
target.name
|
||||||
|
} else {
|
||||||
|
// Generating a bridge. If the bridge is targeting a property getter
|
||||||
|
// we need to take care to get the name right. The bridge is not a
|
||||||
|
// property getter itself.
|
||||||
|
Name.identifier(context.methodSignatureMapper.mapFunctionName(target))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function.copyParameterDeclarationsFrom(target)
|
function.copyParameterDeclarationsFrom(target)
|
||||||
|
|||||||
+5
-1
@@ -34,6 +34,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrTypeOperatorCallImpl
|
|||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.annotations.JVM_STATIC_ANNOTATION_FQ_NAME
|
import org.jetbrains.kotlin.resolve.annotations.JVM_STATIC_ANNOTATION_FQ_NAME
|
||||||
|
|
||||||
internal val jvmStaticAnnotationPhase = makeIrFilePhase(
|
internal val jvmStaticAnnotationPhase = makeIrFilePhase(
|
||||||
@@ -92,7 +93,10 @@ private class CompanionObjectJvmStaticLowering(val context: JvmBackendContext) :
|
|||||||
addFunction {
|
addFunction {
|
||||||
returnType = target.returnType
|
returnType = target.returnType
|
||||||
origin = JvmLoweredDeclarationOrigin.JVM_STATIC_WRAPPER
|
origin = JvmLoweredDeclarationOrigin.JVM_STATIC_WRAPPER
|
||||||
name = target.name
|
// The proxy needs to have the same name as what it is targeting. If that is a property accessor,
|
||||||
|
// we need to make sure that the name is mapped correctly. The static method is not a property accessor,
|
||||||
|
// so we do not have a property to link it up to. Therefore, we compute the right name now.
|
||||||
|
name = Name.identifier(context.methodSignatureMapper.mapFunctionName(target))
|
||||||
modality = if (isInterface) Modality.OPEN else target.modality
|
modality = if (isInterface) Modality.OPEN else target.modality
|
||||||
visibility = target.visibility
|
visibility = target.visibility
|
||||||
isSuspend = target.isSuspend
|
isSuspend = target.isSuspend
|
||||||
|
|||||||
@@ -221,10 +221,13 @@ open class DeepCopyIrTreeWithSymbols(
|
|||||||
isExternal = declaration.isExternal
|
isExternal = declaration.isExternal
|
||||||
).apply {
|
).apply {
|
||||||
transformAnnotations(declaration)
|
transformAnnotations(declaration)
|
||||||
this.backingField = declaration.backingField?.transform()
|
this.backingField = declaration.backingField?.transform()?.also {
|
||||||
this.getter = declaration.getter?.transform()
|
it.correspondingPropertySymbol = symbol
|
||||||
this.setter = declaration.setter?.transform()
|
}
|
||||||
this.backingField?.let {
|
this.getter = declaration.getter?.transform()?.also {
|
||||||
|
it.correspondingPropertySymbol = symbol
|
||||||
|
}
|
||||||
|
this.setter = declaration.setter?.transform()?.also {
|
||||||
it.correspondingPropertySymbol = symbol
|
it.correspondingPropertySymbol = symbol
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,10 +53,6 @@ fun box(
|
|||||||
c2.size
|
c2.size
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
// 8 public final bridge size\(\)I
|
// 8 public final bridge size\(\)I
|
||||||
// 8 INVOKEVIRTUAL A[0-9]+\.size \(\)I
|
// 8 INVOKEVIRTUAL A[0-9]+\.size \(\)I
|
||||||
// 1 INVOKEINTERFACE A9+\.size \(\)I
|
// 1 INVOKEINTERFACE A9+\.size \(\)I
|
||||||
|
|||||||
Reference in New Issue
Block a user