JVM_IR KT-45868 look for parent for delegating lambda in scope stack
This commit is contained in:
committed by
TeamCityServer
parent
c2a5b0b6e2
commit
ed88aa43a4
+14
-1
@@ -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)
|
||||
|
||||
+12
-10
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user