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
@@ -20457,6 +20457,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/invokedynamic/sam/genericLambdaSignature.kt");
}
@Test
@TestMetadata("insideInitBlock.kt")
public void testInsideInitBlock() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/insideInitBlock.kt");
}
@Test
@TestMetadata("intReturnTypeAsNumber.kt")
public void testIntReturnTypeAsNumber() throws Exception {
@@ -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
}
}
@@ -0,0 +1,33 @@
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// SAM_CONVERSIONS: INDY
// FILE: insideInitBlock.kt
class Outer {
class Nested {
class PredicateSource(val condition: Boolean)
val value: String
init {
value = Test.test(PredicateSource::condition, PredicateSource(true))
}
}
}
fun box() = Outer.Nested().value
// FILE: Test.java
public class Test {
public static <T> String test(Predicate<T> predicate, T value) {
if (predicate.getResult(value) == true)
return "OK";
else
return "Failed";
}
}
// FILE: Predicate.java
public interface Predicate<T> {
Boolean getResult(T value);
}
@@ -20439,6 +20439,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/invokedynamic/sam/genericLambdaSignature.kt");
}
@Test
@TestMetadata("insideInitBlock.kt")
public void testInsideInitBlock() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/insideInitBlock.kt");
}
@Test
@TestMetadata("intReturnTypeAsNumber.kt")
public void testIntReturnTypeAsNumber() throws Exception {
@@ -20457,6 +20457,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/invokedynamic/sam/genericLambdaSignature.kt");
}
@Test
@TestMetadata("insideInitBlock.kt")
public void testInsideInitBlock() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/insideInitBlock.kt");
}
@Test
@TestMetadata("intReturnTypeAsNumber.kt")
public void testIntReturnTypeAsNumber() throws Exception {
@@ -17084,6 +17084,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/invokedynamic/sam/genericFunInterfaceWithPrimitive.kt");
}
@TestMetadata("insideInitBlock.kt")
public void testInsideInitBlock() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/insideInitBlock.kt");
}
@TestMetadata("intReturnTypeAsNumber.kt")
public void testIntReturnTypeAsNumber() throws Exception {
runTest("compiler/testData/codegen/box/invokedynamic/sam/intReturnTypeAsNumber.kt");