From 2c102ecd570e156994da543fe3c3b755abda0c2b Mon Sep 17 00:00:00 2001 From: Jiaxiang Chen Date: Tue, 14 May 2019 09:30:20 +0900 Subject: [PATCH] Replicate old backend's naming logic for captured receiver parameter and extension receiver parameters. Context for determine if a value parameter is captured from outer context is not directly available after lowering, hence introduce a new IrDeclarationOrigin for captured receiver parameter to avoid duplicate calculation. --- .../common/lower/LocalDeclarationsLowering.kt | 16 ++++++++++++-- .../backend/jvm/codegen/ExpressionCodegen.kt | 21 +++++++++++++++---- .../checkLocalVariablesTable/kt11117.kt | 1 - .../receiverParameter.kt | 10 +++++++++ ...CheckLocalVariablesTableTestGenerated.java | 5 +++++ ...CheckLocalVariablesTableTestGenerated.java | 5 +++++ 6 files changed, 51 insertions(+), 7 deletions(-) create mode 100644 compiler/testData/checkLocalVariablesTable/receiverParameter.kt diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/LocalDeclarationsLowering.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/LocalDeclarationsLowering.kt index 3edfc951d1c..2db5e999fae 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/LocalDeclarationsLowering.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/LocalDeclarationsLowering.kt @@ -12,6 +12,7 @@ import org.jetbrains.kotlin.backend.common.ScopeWithIr import org.jetbrains.kotlin.backend.common.descriptors.* import org.jetbrains.kotlin.backend.common.ir.* import org.jetbrains.kotlin.descriptors.Modality +import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.ir.IrElement @@ -55,6 +56,8 @@ val IrDeclaration.parents: Sequence object BOUND_VALUE_PARAMETER: IrDeclarationOriginImpl("BOUND_VALUE_PARAMETER") +object BOUND_RECEIVER_PARAMETER: IrDeclarationOriginImpl("BOUND_RECEIVER_PARAMETER") + class LocalDeclarationsLowering( val context: BackendContext, val localNameProvider: LocalNameProvider = LocalNameProvider.DEFAULT, @@ -530,8 +533,17 @@ class LocalDeclarationsLowering( val parameterDescriptor = WrappedValueParameterDescriptor() val p = capturedValue.owner IrValueParameterImpl( - p.startOffset, p.endOffset, BOUND_VALUE_PARAMETER, IrValueParameterSymbolImpl(parameterDescriptor), - suggestNameForCapturedValue(p), i, p.type, null, isCrossinline = false, isNoinline = false + p.startOffset, + p.endOffset, + if (p.descriptor is ReceiverParameterDescriptor && newDeclaration is IrConstructor) + BOUND_RECEIVER_PARAMETER else BOUND_VALUE_PARAMETER, + IrValueParameterSymbolImpl(parameterDescriptor), + suggestNameForCapturedValue(p), + i, + p.type, + null, + isCrossinline = false, + isNoinline = false ).also { parameterDescriptor.bind(it) it.parent = newDeclaration diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt index d5852bfbaee..208b3d361ff 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.backend.jvm.codegen import org.jetbrains.kotlin.backend.common.ir.returnType +import org.jetbrains.kotlin.backend.common.lower.BOUND_RECEIVER_PARAMETER import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin import org.jetbrains.kotlin.backend.jvm.intrinsics.IrIntrinsicMethods import org.jetbrains.kotlin.backend.jvm.intrinsics.JavaClassProperty @@ -23,6 +24,7 @@ import org.jetbrains.kotlin.codegen.pseudoInsns.fakeAlwaysFalseIfeq import org.jetbrains.kotlin.codegen.pseudoInsns.fixStackAndJump import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter import org.jetbrains.kotlin.config.isReleaseCoroutines +import org.jetbrains.kotlin.config.languageVersionSettings import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ConstructorDescriptor import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor @@ -208,18 +210,29 @@ class ExpressionCodegen( } val extensionReceiverParameter = irFunction.extensionReceiverParameter if (extensionReceiverParameter != null) { - writeValueParameterInLocalVariableTable(extensionReceiverParameter, startLabel, endLabel) + writeValueParameterInLocalVariableTable(extensionReceiverParameter, startLabel, endLabel, true) } for (param in irFunction.valueParameters) { - writeValueParameterInLocalVariableTable(param, startLabel, endLabel) + writeValueParameterInLocalVariableTable(param, startLabel, endLabel, false) } } - private fun writeValueParameterInLocalVariableTable(param: IrValueParameter, startLabel: Label, endLabel: Label) { + private fun writeValueParameterInLocalVariableTable(param: IrValueParameter, startLabel: Label, endLabel: Label, isReceiver: Boolean) { // TODO: old code has a special treatment for destructuring lambda parameters. // There is no (easy) way to reproduce it with IR structures. // Does not show up in tests, but might come to bite us at some point. - val name = param.name.asString() + + // If the parameter is an extension receiver parameter or a captured extension receiver from enclosing, + // then generate name accordingly. + val name = if (param.origin == BOUND_RECEIVER_PARAMETER || isReceiver) { + getNameForReceiverParameter( + irFunction.descriptor, + typeMapper.kotlinTypeMapper.bindingContext, + context.configuration.languageVersionSettings + ) + } else { + param.name.asString() + } val type = typeMapper.mapType(param) // NOTE: we expect all value parameters to be present in the frame. diff --git a/compiler/testData/checkLocalVariablesTable/kt11117.kt b/compiler/testData/checkLocalVariablesTable/kt11117.kt index 8b214b5a8f4..6a6351cdfaf 100644 --- a/compiler/testData/checkLocalVariablesTable/kt11117.kt +++ b/compiler/testData/checkLocalVariablesTable/kt11117.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR class A(val value: String) fun A.test(): String { diff --git a/compiler/testData/checkLocalVariablesTable/receiverParameter.kt b/compiler/testData/checkLocalVariablesTable/receiverParameter.kt new file mode 100644 index 00000000000..bdce356a13f --- /dev/null +++ b/compiler/testData/checkLocalVariablesTable/receiverParameter.kt @@ -0,0 +1,10 @@ +class A() { + fun String.test() { + + } +} + + +// METHOD : A.test(Ljava/lang/String;)V +// VARIABLE : NAME=this TYPE=LA; INDEX=0 +// VARIABLE : NAME=$this$test TYPE=Ljava/lang/String; INDEX=1 diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/CheckLocalVariablesTableTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/CheckLocalVariablesTableTestGenerated.java index 42bec83bb2d..dde71e5c041 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/CheckLocalVariablesTableTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/CheckLocalVariablesTableTestGenerated.java @@ -104,6 +104,11 @@ public class CheckLocalVariablesTableTestGenerated extends AbstractCheckLocalVar runTest("compiler/testData/checkLocalVariablesTable/localFun.kt"); } + @TestMetadata("receiverParameter.kt") + public void testReceiverParameter() throws Exception { + runTest("compiler/testData/checkLocalVariablesTable/receiverParameter.kt"); + } + @TestMetadata("underscoreNames.kt") public void testUnderscoreNames() throws Exception { runTest("compiler/testData/checkLocalVariablesTable/underscoreNames.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrCheckLocalVariablesTableTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrCheckLocalVariablesTableTestGenerated.java index f5d466c916d..af312f6bc2f 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrCheckLocalVariablesTableTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrCheckLocalVariablesTableTestGenerated.java @@ -104,6 +104,11 @@ public class IrCheckLocalVariablesTableTestGenerated extends AbstractIrCheckLoca runTest("compiler/testData/checkLocalVariablesTable/localFun.kt"); } + @TestMetadata("receiverParameter.kt") + public void testReceiverParameter() throws Exception { + runTest("compiler/testData/checkLocalVariablesTable/receiverParameter.kt"); + } + @TestMetadata("underscoreNames.kt") public void testUnderscoreNames() throws Exception { runTest("compiler/testData/checkLocalVariablesTable/underscoreNames.kt");