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
+6
@@ -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 {
|
||||
|
||||
+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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
+6
@@ -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 {
|
||||
|
||||
+6
@@ -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 {
|
||||
|
||||
+5
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user