JVM_IR KT-45868 look for parent for delegating lambda in scope stack

This commit is contained in:
Dmitry Petrov
2021-04-08 19:46:53 +03:00
committed by TeamCityServer
parent c2a5b0b6e2
commit ed88aa43a4
7 changed files with 82 additions and 11 deletions
@@ -132,6 +132,19 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext)
FunctionReferenceBuilder(expression).build()
}
private fun getDeclarationParentForDelegatingLambda(): IrDeclarationParent {
for (s in allScopes.asReversed()) {
val scopeOwner = s.scope.scopeOwnerSymbol.owner
if (scopeOwner is IrDeclarationParent) {
return scopeOwner
}
}
throw AssertionError(
"No IrDeclarationParent found in scopes:\n" +
allScopes.joinToString(separator = "\n") { " " + it.scope.scopeOwnerSymbol.owner.render() }
)
}
// Handle SAM conversions which wrap a function reference:
// class sam$n(private val receiver: R) : Interface { override fun method(...) = receiver.target(...) }
//
@@ -153,7 +166,7 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext)
invokable.statements.last() as IrFunctionReference
} else if (shouldGenerateIndySamConversions && canGenerateIndySamConversionOnFunctionalExpression(samSuperType, invokable)) {
val lambdaBlock = SamDelegatingLambdaBuilder(context)
.build(invokable, samSuperType, currentScope!!.scope.scopeOwnerSymbol)
.build(invokable, samSuperType, currentScope!!.scope.scopeOwnerSymbol, getDeclarationParentForDelegatingLambda())
val lambdaMetafactoryArguments = LambdaMetafactoryArgumentsBuilder(context, crossinlineLambdas)
.getLambdaMetafactoryArgumentsOrNull(lambdaBlock.ref, samSuperType, false)
?: return super.visitTypeOperator(expression)
@@ -63,17 +63,18 @@ internal class NullableDelegatingLambdaBlock(
internal class SamDelegatingLambdaBuilder(private val jvmContext: JvmBackendContext) {
fun build(expression: IrExpression, superType: IrType, scopeSymbol: IrSymbol): SamDelegatingLambdaBlock {
fun build(expression: IrExpression, superType: IrType, scopeSymbol: IrSymbol, parent: IrDeclarationParent): SamDelegatingLambdaBlock {
return if (superType.isNullable() && expression.type.isNullable())
buildNullableDelegatingLambda(expression, superType, scopeSymbol)
buildNullableDelegatingLambda(expression, superType, scopeSymbol, parent)
else
buildRegularDelegatingLambda(expression, superType, scopeSymbol)
buildRegularDelegatingLambda(expression, superType, scopeSymbol, parent)
}
private fun buildRegularDelegatingLambda(
expression: IrExpression,
superType: IrType,
scopeSymbol: IrSymbol
scopeSymbol: IrSymbol,
parent: IrDeclarationParent
): SamDelegatingLambdaBlock {
lateinit var ref: IrFunctionReference
val block = jvmContext.createJvmIrBuilder(scopeSymbol, expression.startOffset, expression.endOffset).run {
@@ -86,7 +87,7 @@ internal class SamDelegatingLambdaBuilder(private val jvmContext: JvmBackendCont
irBlock(origin = IrStatementOrigin.LAMBDA) {
val tmp = irTemporary(expression)
val lambda = createDelegatingLambda(scopeSymbol, expression, superType, tmp)
val lambda = createDelegatingLambda(expression, superType, tmp, parent)
.also { +it }
ref = createDelegatingLambdaReference(expression, lambda)
.also { +it }
@@ -99,7 +100,8 @@ internal class SamDelegatingLambdaBuilder(private val jvmContext: JvmBackendCont
private fun buildNullableDelegatingLambda(
expression: IrExpression,
superType: IrType,
scopeSymbol: IrSymbol
scopeSymbol: IrSymbol,
parent: IrDeclarationParent
): SamDelegatingLambdaBlock {
lateinit var ref: IrFunctionReference
lateinit var ifExpr: IrExpression
@@ -119,7 +121,7 @@ internal class SamDelegatingLambdaBuilder(private val jvmContext: JvmBackendCont
irBlock(origin = IrStatementOrigin.LAMBDA) {
val tmp = irTemporary(expression)
ifNotNullBlock = irBlock {
val lambda = createDelegatingLambda(scopeSymbol, expression, superType, tmp)
val lambda = createDelegatingLambda(expression, superType, tmp, parent)
.also { +it }
ref = createDelegatingLambdaReference(expression, lambda)
.also { +it }
@@ -133,10 +135,10 @@ internal class SamDelegatingLambdaBuilder(private val jvmContext: JvmBackendCont
}
private fun createDelegatingLambda(
scopeSymbol: IrSymbol,
expression: IrExpression,
superType: IrType,
tmp: IrVariable
tmp: IrVariable,
parent: IrDeclarationParent
): IrSimpleFunction {
val superMethod = superType.getSingleAbstractMethod()
?: throw AssertionError("SAM type expected: ${superType.render()}")
@@ -176,7 +178,7 @@ internal class SamDelegatingLambdaBuilder(private val jvmContext: JvmBackendCont
}
)
}
lambda.parent = scopeSymbol.owner as IrDeclarationParent
lambda.parent = parent
}
}