From e7a744b315b456fe0ca870ab9952ae4d373c841d Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Fri, 6 Feb 2015 15:50:14 +0300 Subject: [PATCH] Make JetTypeMapper aware of SAM constructor arguments This obsoletes 'replaceName' workaround that was present in ClosureCodegen but missing in other crucial call sites of mapSignature, e.g. generation of EnclosingMethod info #KT-6691 Fixed --- .../kotlin/codegen/ClosureCodegen.java | 3 +-- .../kotlin/codegen/state/JetTypeMapper.java | 21 ++++++++++++++-- .../jvm/jvmSignature/JvmMethodSignature.java | 7 ------ .../lambda/kt6691_lambdaInSamConstructor.kt | 24 +++++++++++++++++++ ...lackBoxWithStdlibCodegenTestGenerated.java | 6 +++++ 5 files changed, 50 insertions(+), 11 deletions(-) create mode 100644 compiler/testData/codegen/boxWithStdlib/reflection/enclosing/lambda/kt6691_lambdaInSamConstructor.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java index ab453ddb330..c7a76467b86 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java @@ -161,8 +161,7 @@ public class ClosureCodegen extends MemberCodegen { erasedInterfaceFunction = samType.getAbstractMethod().getOriginal(); } - JvmMethodSignature jvmMethodSignature = - typeMapper.mapSignature(funDescriptor).replaceName(erasedInterfaceFunction.getName().toString()); + JvmMethodSignature jvmMethodSignature = typeMapper.mapSignature(funDescriptor); generateBridge(typeMapper.mapSignature(erasedInterfaceFunction).getAsmMethod(), jvmMethodSignature.getAsmMethod()); functionCodegen.generateMethod(OtherOrigin(element, funDescriptor), jvmMethodSignature, funDescriptor, strategy); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/JetTypeMapper.java index 2582bbe697f..f5997e7a76b 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/JetTypeMapper.java @@ -38,7 +38,10 @@ import org.jetbrains.kotlin.load.kotlin.nativeDeclarations.NativeDeclarationsPac import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.name.FqNameUnsafe; import org.jetbrains.kotlin.name.SpecialNames; +import org.jetbrains.kotlin.psi.JetExpression; import org.jetbrains.kotlin.psi.JetFile; +import org.jetbrains.kotlin.psi.JetFunctionLiteral; +import org.jetbrains.kotlin.psi.JetFunctionLiteralExpression; import org.jetbrains.kotlin.resolve.BindingContext; import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils; import org.jetbrains.kotlin.resolve.DescriptorUtils; @@ -584,7 +587,7 @@ public class JetTypeMapper { } @NotNull - private static String mapFunctionName(@NotNull FunctionDescriptor descriptor) { + private String mapFunctionName(@NotNull FunctionDescriptor descriptor) { String platformName = getPlatformName(descriptor); if (platformName != null) return platformName; @@ -601,7 +604,21 @@ public class JetTypeMapper { return PropertyCodegen.setterName(property.getName()); } } - else if (isLocalNamedFun(descriptor) || descriptor instanceof AnonymousFunctionDescriptor) { + else if (isLocalNamedFun(descriptor)) { + return "invoke"; + } + else if (descriptor instanceof AnonymousFunctionDescriptor) { + PsiElement element = DescriptorToSourceUtils.callableDescriptorToDeclaration(descriptor); + if (element instanceof JetFunctionLiteral) { + PsiElement expression = element.getParent(); + if (expression instanceof JetFunctionLiteralExpression) { + SamType samType = bindingContext.get(SAM_VALUE, (JetExpression) expression); + if (samType != null) { + return samType.getAbstractMethod().getName().asString(); + } + } + } + return "invoke"; } else { diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/jvmSignature/JvmMethodSignature.java b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/jvmSignature/JvmMethodSignature.java index 2a7afbed5f7..ee01f671761 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/jvmSignature/JvmMethodSignature.java +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/jvmSignature/JvmMethodSignature.java @@ -58,13 +58,6 @@ public class JvmMethodSignature { return asmMethod.getReturnType(); } - @NotNull - public JvmMethodSignature replaceName(@NotNull String newName) { - return newName.equals(asmMethod.getName()) ? - this : - new JvmMethodSignature(new Method(newName, asmMethod.getDescriptor()), genericsSignature, valueParameters); - } - @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/compiler/testData/codegen/boxWithStdlib/reflection/enclosing/lambda/kt6691_lambdaInSamConstructor.kt b/compiler/testData/codegen/boxWithStdlib/reflection/enclosing/lambda/kt6691_lambdaInSamConstructor.kt new file mode 100644 index 00000000000..fd9007d3f42 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/reflection/enclosing/lambda/kt6691_lambdaInSamConstructor.kt @@ -0,0 +1,24 @@ +var lambda = {} + +class A { + val prop = Runnable { + lambda = { println("") } + } +} + +fun box(): String { + A().prop.run() + + val javaClass = lambda.javaClass + + val enclosingMethod = javaClass.getEnclosingMethod() + if (enclosingMethod?.getName() != "run") return "method: $enclosingMethod" + + val enclosingClass = javaClass.getEnclosingClass()!!.getName() + if (enclosingClass != "A\$prop\$1") return "enclosing class: $enclosingClass" + + val declaringClass = javaClass.getDeclaringClass() + if (declaringClass != null) return "anonymous function has a declaring class: $declaringClass" + + return "OK" +} diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java index 9cce3b2d4c4..b7f96509760 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java @@ -2492,6 +2492,12 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxWithStdlib/reflection/enclosing/lambda"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("kt6691_lambdaInSamConstructor.kt") + public void testKt6691_lambdaInSamConstructor() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/enclosing/lambda/kt6691_lambdaInSamConstructor.kt"); + doTestWithStdlib(fileName); + } + @TestMetadata("lambdaInConstructor.kt") public void testLambdaInConstructor() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/enclosing/lambda/lambdaInConstructor.kt");