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.
This commit is contained in:
Jiaxiang Chen
2019-05-14 09:30:20 +09:00
committed by Yan Zhulanow
parent 9760c156a4
commit 2c102ecd57
6 changed files with 51 additions and 7 deletions
@@ -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<IrDeclarationParent>
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
@@ -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.
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
class A(val value: String)
fun A.test(): String {
@@ -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
@@ -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");
@@ -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");