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");
|
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
|
@Test
|
||||||
@TestMetadata("intReturnTypeAsNumber.kt")
|
@TestMetadata("intReturnTypeAsNumber.kt")
|
||||||
public void testIntReturnTypeAsNumber() throws Exception {
|
public void testIntReturnTypeAsNumber() throws Exception {
|
||||||
|
|||||||
+14
-1
@@ -132,6 +132,19 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext)
|
|||||||
FunctionReferenceBuilder(expression).build()
|
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:
|
// Handle SAM conversions which wrap a function reference:
|
||||||
// class sam$n(private val receiver: R) : Interface { override fun method(...) = receiver.target(...) }
|
// 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
|
invokable.statements.last() as IrFunctionReference
|
||||||
} else if (shouldGenerateIndySamConversions && canGenerateIndySamConversionOnFunctionalExpression(samSuperType, invokable)) {
|
} else if (shouldGenerateIndySamConversions && canGenerateIndySamConversionOnFunctionalExpression(samSuperType, invokable)) {
|
||||||
val lambdaBlock = SamDelegatingLambdaBuilder(context)
|
val lambdaBlock = SamDelegatingLambdaBuilder(context)
|
||||||
.build(invokable, samSuperType, currentScope!!.scope.scopeOwnerSymbol)
|
.build(invokable, samSuperType, currentScope!!.scope.scopeOwnerSymbol, getDeclarationParentForDelegatingLambda())
|
||||||
val lambdaMetafactoryArguments = LambdaMetafactoryArgumentsBuilder(context, crossinlineLambdas)
|
val lambdaMetafactoryArguments = LambdaMetafactoryArgumentsBuilder(context, crossinlineLambdas)
|
||||||
.getLambdaMetafactoryArgumentsOrNull(lambdaBlock.ref, samSuperType, false)
|
.getLambdaMetafactoryArgumentsOrNull(lambdaBlock.ref, samSuperType, false)
|
||||||
?: return super.visitTypeOperator(expression)
|
?: return super.visitTypeOperator(expression)
|
||||||
|
|||||||
+12
-10
@@ -63,17 +63,18 @@ internal class NullableDelegatingLambdaBlock(
|
|||||||
|
|
||||||
|
|
||||||
internal class SamDelegatingLambdaBuilder(private val jvmContext: JvmBackendContext) {
|
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())
|
return if (superType.isNullable() && expression.type.isNullable())
|
||||||
buildNullableDelegatingLambda(expression, superType, scopeSymbol)
|
buildNullableDelegatingLambda(expression, superType, scopeSymbol, parent)
|
||||||
else
|
else
|
||||||
buildRegularDelegatingLambda(expression, superType, scopeSymbol)
|
buildRegularDelegatingLambda(expression, superType, scopeSymbol, parent)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildRegularDelegatingLambda(
|
private fun buildRegularDelegatingLambda(
|
||||||
expression: IrExpression,
|
expression: IrExpression,
|
||||||
superType: IrType,
|
superType: IrType,
|
||||||
scopeSymbol: IrSymbol
|
scopeSymbol: IrSymbol,
|
||||||
|
parent: IrDeclarationParent
|
||||||
): SamDelegatingLambdaBlock {
|
): SamDelegatingLambdaBlock {
|
||||||
lateinit var ref: IrFunctionReference
|
lateinit var ref: IrFunctionReference
|
||||||
val block = jvmContext.createJvmIrBuilder(scopeSymbol, expression.startOffset, expression.endOffset).run {
|
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) {
|
irBlock(origin = IrStatementOrigin.LAMBDA) {
|
||||||
val tmp = irTemporary(expression)
|
val tmp = irTemporary(expression)
|
||||||
val lambda = createDelegatingLambda(scopeSymbol, expression, superType, tmp)
|
val lambda = createDelegatingLambda(expression, superType, tmp, parent)
|
||||||
.also { +it }
|
.also { +it }
|
||||||
ref = createDelegatingLambdaReference(expression, lambda)
|
ref = createDelegatingLambdaReference(expression, lambda)
|
||||||
.also { +it }
|
.also { +it }
|
||||||
@@ -99,7 +100,8 @@ internal class SamDelegatingLambdaBuilder(private val jvmContext: JvmBackendCont
|
|||||||
private fun buildNullableDelegatingLambda(
|
private fun buildNullableDelegatingLambda(
|
||||||
expression: IrExpression,
|
expression: IrExpression,
|
||||||
superType: IrType,
|
superType: IrType,
|
||||||
scopeSymbol: IrSymbol
|
scopeSymbol: IrSymbol,
|
||||||
|
parent: IrDeclarationParent
|
||||||
): SamDelegatingLambdaBlock {
|
): SamDelegatingLambdaBlock {
|
||||||
lateinit var ref: IrFunctionReference
|
lateinit var ref: IrFunctionReference
|
||||||
lateinit var ifExpr: IrExpression
|
lateinit var ifExpr: IrExpression
|
||||||
@@ -119,7 +121,7 @@ internal class SamDelegatingLambdaBuilder(private val jvmContext: JvmBackendCont
|
|||||||
irBlock(origin = IrStatementOrigin.LAMBDA) {
|
irBlock(origin = IrStatementOrigin.LAMBDA) {
|
||||||
val tmp = irTemporary(expression)
|
val tmp = irTemporary(expression)
|
||||||
ifNotNullBlock = irBlock {
|
ifNotNullBlock = irBlock {
|
||||||
val lambda = createDelegatingLambda(scopeSymbol, expression, superType, tmp)
|
val lambda = createDelegatingLambda(expression, superType, tmp, parent)
|
||||||
.also { +it }
|
.also { +it }
|
||||||
ref = createDelegatingLambdaReference(expression, lambda)
|
ref = createDelegatingLambdaReference(expression, lambda)
|
||||||
.also { +it }
|
.also { +it }
|
||||||
@@ -133,10 +135,10 @@ internal class SamDelegatingLambdaBuilder(private val jvmContext: JvmBackendCont
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun createDelegatingLambda(
|
private fun createDelegatingLambda(
|
||||||
scopeSymbol: IrSymbol,
|
|
||||||
expression: IrExpression,
|
expression: IrExpression,
|
||||||
superType: IrType,
|
superType: IrType,
|
||||||
tmp: IrVariable
|
tmp: IrVariable,
|
||||||
|
parent: IrDeclarationParent
|
||||||
): IrSimpleFunction {
|
): IrSimpleFunction {
|
||||||
val superMethod = superType.getSingleAbstractMethod()
|
val superMethod = superType.getSingleAbstractMethod()
|
||||||
?: throw AssertionError("SAM type expected: ${superType.render()}")
|
?: 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");
|
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
|
@Test
|
||||||
@TestMetadata("intReturnTypeAsNumber.kt")
|
@TestMetadata("intReturnTypeAsNumber.kt")
|
||||||
public void testIntReturnTypeAsNumber() throws Exception {
|
public void testIntReturnTypeAsNumber() throws Exception {
|
||||||
|
|||||||
+6
@@ -20457,6 +20457,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/invokedynamic/sam/genericLambdaSignature.kt");
|
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
|
@Test
|
||||||
@TestMetadata("intReturnTypeAsNumber.kt")
|
@TestMetadata("intReturnTypeAsNumber.kt")
|
||||||
public void testIntReturnTypeAsNumber() throws Exception {
|
public void testIntReturnTypeAsNumber() throws Exception {
|
||||||
|
|||||||
+5
@@ -17084,6 +17084,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
runTest("compiler/testData/codegen/box/invokedynamic/sam/genericFunInterfaceWithPrimitive.kt");
|
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")
|
@TestMetadata("intReturnTypeAsNumber.kt")
|
||||||
public void testIntReturnTypeAsNumber() throws Exception {
|
public void testIntReturnTypeAsNumber() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/invokedynamic/sam/intReturnTypeAsNumber.kt");
|
runTest("compiler/testData/codegen/box/invokedynamic/sam/intReturnTypeAsNumber.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user