JVM IR: Use dispatchReceiver to calculate owner in MethodSignatureMapper

This commit is contained in:
Steven Schäfer
2020-02-03 13:33:04 +01:00
committed by Georgy Bronnikov
parent 0e243ca295
commit 12e31a1760
4 changed files with 31 additions and 12 deletions
@@ -31,6 +31,7 @@ interface JvmLoweredDeclarationOrigin : IrDeclarationOrigin {
object ENUM_MAPPINGS_FOR_WHEN : IrDeclarationOriginImpl("ENUM_MAPPINGS_FOR_WHEN", isSynthetic = true)
object SYNTHETIC_INLINE_CLASS_MEMBER : IrDeclarationOriginImpl("SYNTHETIC_INLINE_CLASS_MEMBER", isSynthetic = true)
object INLINE_CLASS_GENERATED_IMPL_METHOD : IrDeclarationOriginImpl("INLINE_CLASS_GENERATED_IMPL_METHOD")
object STATIC_INLINE_CLASS_REPLACEMENT : IrDeclarationOriginImpl("STATIC_INLINE_CLASS_REPLACEMENT")
object GENERATED_ASSERTION_ENABLED_FIELD : IrDeclarationOriginImpl("GENERATED_ASSERTION_ENABLED_FIELD", isSynthetic = true)
object GENERATED_MAIN_FOR_PARAMETERLESS_MAIN_METHOD : IrDeclarationOriginImpl("GENERATED_MAIN_FOR_PARAMETERLESS_MAIN_METHOD", isSynthetic = true)
object SUSPEND_IMPL_STATIC_FUNCTION : IrDeclarationOriginImpl("SUSPEND_IMPL_STATIC_FUNCTION", isSynthetic = true)
@@ -33,6 +33,9 @@ fun IrTypeMapper.mapSupertype(irType: IrType, sw: JvmSignatureWriter): Type =
fun IrTypeMapper.mapClass(irClass: IrClass): Type =
mapType(irClass.defaultType, TypeMappingMode.CLASS_DECLARATION)
fun IrTypeMapper.mapOwner(irClass: IrClass): Type =
mapType(irClass.defaultType, TypeMappingMode.GENERIC_ARGUMENT)
fun IrTypeMapper.mapTypeAsDeclaration(irType: IrType): Type =
mapType(irType, TypeMappingMode.CLASS_DECLARATION)
@@ -293,10 +293,18 @@ class MethodSignatureMapper(private val context: JvmBackendContext) {
if (valueArgumentsCount > 0) (getValueArgument(0) as? IrConst<*>)?.value as? Boolean ?: true else null
}
private fun IrFunctionAccessExpression.computeCalleeParent(): IrClass {
if (this is IrCall) {
superQualifierSymbol?.let { return it.owner }
}
return dispatchReceiver?.type?.classOrNull?.owner
?: symbol.owner.parentAsClass // Static call or type parameter
}
fun mapToCallableMethod(caller: IrFunction, expression: IrFunctionAccessExpression): IrCallableMethod {
val callee = expression.symbol.owner
val calleeParent = callee.parentAsClass
val owner = typeMapper.mapClass(calleeParent)
val calleeParent = expression.computeCalleeParent()
val owner = typeMapper.mapOwner(calleeParent)
if (callee !is IrSimpleFunction) {
check(callee is IrConstructor) { "Function must be a simple function or a constructor: ${callee.render()}" }
@@ -326,6 +334,8 @@ class MethodSignatureMapper(private val context: JvmBackendContext) {
// Do not remap special builtin methods when called from a bridge. The bridges are there to provide the
// remapped name or signature and forward to the actually declared method.
if (caller.origin == IrDeclarationOrigin.BRIDGE || caller.origin == IrDeclarationOrigin.BRIDGE_SPECIAL) return null
// Do not remap calls to static replacements of inline class methods, since they have completely different signatures.
if (callee.origin == JvmLoweredDeclarationOrigin.STATIC_INLINE_CLASS_REPLACEMENT) return null
val overriddenSpecialBuiltinFunction = callee.descriptor.original.getOverriddenBuiltinReflectingJvmDescriptor()
if (overriddenSpecialBuiltinFunction != null && !superCall) {
return mapSignatureSkipGeneric(context.referenceFunction(overriddenSpecialBuiltinFunction.original).owner)
@@ -126,12 +126,8 @@ class MemoizedInlineClassReplacements {
}
private fun createMethodReplacement(function: IrFunction): IrSimpleFunction =
buildReplacement(function) {
buildReplacement(function, function.origin) {
require(function.dispatchReceiverParameter != null && function is IrSimpleFunction)
overriddenSymbols = function.overriddenSymbols.map {
getReplacementFunction(it.owner)?.symbol ?: it
}
val newValueParameters = ArrayList<IrValueParameter>()
for ((index, parameter) in function.explicitParameters.withIndex()) {
val name = if (parameter == function.extensionReceiverParameter) Name.identifier("\$receiver") else parameter.name
@@ -151,7 +147,7 @@ class MemoizedInlineClassReplacements {
}
private fun createStaticReplacement(function: IrFunction): IrSimpleFunction =
buildReplacement(function) {
buildReplacement(function, JvmLoweredDeclarationOrigin.STATIC_INLINE_CLASS_REPLACEMENT) {
val newValueParameters = ArrayList<IrValueParameter>()
for ((index, parameter) in function.explicitParameters.withIndex()) {
val name = when (parameter) {
@@ -172,11 +168,13 @@ class MemoizedInlineClassReplacements {
valueParameters = newValueParameters
}
private fun buildReplacement(function: IrFunction, body: IrFunctionImpl.() -> Unit) =
private fun buildReplacement(function: IrFunction, replacementOrigin: IrDeclarationOrigin, body: IrFunctionImpl.() -> Unit) =
buildFunWithDescriptorForInlining(function.descriptor) {
updateFrom(function)
if (function.origin == IrDeclarationOrigin.GENERATED_INLINE_CLASS_MEMBER) {
origin = JvmLoweredDeclarationOrigin.INLINE_CLASS_GENERATED_IMPL_METHOD
origin = if (function.origin == IrDeclarationOrigin.GENERATED_INLINE_CLASS_MEMBER) {
JvmLoweredDeclarationOrigin.INLINE_CLASS_GENERATED_IMPL_METHOD
} else {
replacementOrigin
}
name = mangledNameFor(function)
returnType = function.returnType
@@ -184,9 +182,16 @@ class MemoizedInlineClassReplacements {
parent = function.parent
annotations += function.annotations
copyTypeParameters(function.allTypeParameters)
correspondingPropertySymbol = function.safeAs<IrSimpleFunction>()?.correspondingPropertySymbol
metadata = function.metadata
function.safeAs<IrFunctionBase<*>>()?.metadata = null
if (function is IrSimpleFunction) {
correspondingPropertySymbol = function.correspondingPropertySymbol
overriddenSymbols = function.overriddenSymbols.map {
getReplacementFunction(it.owner)?.symbol ?: it
}
}
body()
}
}