Put suspend lambda's parameters to LVT
#KT-26412 Fixed #KT-28534 Fixed
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@@ -460,7 +460,6 @@ public class FunctionCodegen {
|
||||
new Label(),
|
||||
contextKind,
|
||||
state,
|
||||
Collections.emptyList(),
|
||||
0);
|
||||
|
||||
mv.visitEnd();
|
||||
@@ -675,28 +674,9 @@ public class FunctionCodegen {
|
||||
);
|
||||
}
|
||||
|
||||
List<ValueParameterDescriptor> destructuredParametersForSuspendLambda = new ArrayList<>();
|
||||
if (context.getParentContext() instanceof ClosureContext) {
|
||||
if (context instanceof InlineLambdaContext) {
|
||||
CallableMemberDescriptor lambdaDescriptor = context.getContextDescriptor();
|
||||
if (lambdaDescriptor instanceof FunctionDescriptor &&
|
||||
((FunctionDescriptor) lambdaDescriptor).isSuspend()) {
|
||||
destructuredParametersForSuspendLambda.addAll(lambdaDescriptor.getValueParameters());
|
||||
}
|
||||
} else {
|
||||
FunctionDescriptor lambdaDescriptor = ((ClosureContext) context.getParentContext()).getOriginalSuspendLambdaDescriptor();
|
||||
if (lambdaDescriptor != null &&
|
||||
CoroutineCodegenUtilKt.isResumeImplMethodName(
|
||||
parentCodegen.state.getLanguageVersionSettings(), functionDescriptor.getName().asString()
|
||||
)) {
|
||||
destructuredParametersForSuspendLambda.addAll(lambdaDescriptor.getValueParameters());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
generateLocalVariableTable(
|
||||
mv, signature, functionDescriptor, thisType, methodBegin, methodEnd, context.getContextKind(), parentCodegen.state,
|
||||
destructuredParametersForSuspendLambda, (functionFakeIndex >= 0 ? 1 : 0) + (lambdaFakeIndex >= 0 ? 1 : 0)
|
||||
(functionFakeIndex >= 0 ? 1 : 0) + (lambdaFakeIndex >= 0 ? 1 : 0)
|
||||
);
|
||||
|
||||
//TODO: it's best to move all below logic to 'generateLocalVariableTable' method
|
||||
@@ -757,7 +737,6 @@ public class FunctionCodegen {
|
||||
@NotNull Label methodEnd,
|
||||
@NotNull OwnerKind ownerKind,
|
||||
@NotNull GenerationState state,
|
||||
@NotNull List<ValueParameterDescriptor> destructuredParametersForSuspendLambda,
|
||||
int shiftForDestructuringVariables
|
||||
) {
|
||||
if (functionDescriptor.isSuspend() && !(functionDescriptor instanceof AnonymousFunctionDescriptor)) {
|
||||
@@ -776,8 +755,7 @@ public class FunctionCodegen {
|
||||
)
|
||||
),
|
||||
unwrapped,
|
||||
thisType, methodBegin, methodEnd, ownerKind, state, destructuredParametersForSuspendLambda,
|
||||
shiftForDestructuringVariables
|
||||
thisType, methodBegin, methodEnd, ownerKind, state, shiftForDestructuringVariables
|
||||
);
|
||||
return;
|
||||
}
|
||||
@@ -786,7 +764,6 @@ public class FunctionCodegen {
|
||||
generateLocalVariablesForParameters(mv,
|
||||
jvmMethodSignature, functionDescriptor,
|
||||
thisType, methodBegin, methodEnd, functionDescriptor.getValueParameters(),
|
||||
destructuredParametersForSuspendLambda,
|
||||
AsmUtil.isStaticMethod(ownerKind, functionDescriptor), state, shiftForDestructuringVariables
|
||||
);
|
||||
}
|
||||
@@ -804,7 +781,7 @@ public class FunctionCodegen {
|
||||
) {
|
||||
generateLocalVariablesForParameters(
|
||||
mv, jvmMethodSignature, functionDescriptor,
|
||||
thisType, methodBegin, methodEnd, valueParameters, Collections.emptyList(), isStatic, state,
|
||||
thisType, methodBegin, methodEnd, valueParameters, isStatic, state,
|
||||
0);
|
||||
}
|
||||
|
||||
@@ -816,7 +793,6 @@ public class FunctionCodegen {
|
||||
@NotNull Label methodBegin,
|
||||
@NotNull Label methodEnd,
|
||||
Collection<ValueParameterDescriptor> valueParameters,
|
||||
@NotNull List<ValueParameterDescriptor> destructuredParametersForSuspendLambda,
|
||||
boolean isStatic,
|
||||
@NotNull GenerationState state,
|
||||
int shiftForDestructuringVariables
|
||||
@@ -868,9 +844,7 @@ public class FunctionCodegen {
|
||||
}
|
||||
|
||||
shift += shiftForDestructuringVariables;
|
||||
shift = generateDestructuredParameterEntries(mv, methodBegin, methodEnd, valueParameters, typeMapper, shift);
|
||||
shift = generateDestructuredParametersForSuspendLambda(mv, methodBegin, methodEnd, typeMapper, shift, destructuredParametersForSuspendLambda);
|
||||
generateDestructuredParameterEntries(mv, methodBegin, methodEnd, destructuredParametersForSuspendLambda, typeMapper, shift);
|
||||
generateDestructuredParameterEntries(mv, methodBegin, methodEnd, valueParameters, typeMapper, shift);
|
||||
}
|
||||
|
||||
private static int generateDestructuredParameterEntries(
|
||||
@@ -894,25 +868,6 @@ public class FunctionCodegen {
|
||||
return shift;
|
||||
}
|
||||
|
||||
private static int generateDestructuredParametersForSuspendLambda(
|
||||
@NotNull MethodVisitor mv,
|
||||
@NotNull Label methodBegin,
|
||||
@NotNull Label methodEnd,
|
||||
KotlinTypeMapper typeMapper,
|
||||
int shift,
|
||||
List<ValueParameterDescriptor> destructuredParametersForSuspendLambda
|
||||
) {
|
||||
for (ValueParameterDescriptor parameter : destructuredParametersForSuspendLambda) {
|
||||
String nameForDestructuredParameter = VariableAsmNameManglingUtils.getNameForDestructuredParameterOrNull(parameter);
|
||||
if (nameForDestructuredParameter == null) continue;
|
||||
|
||||
Type type = typeMapper.mapType(parameter.getType());
|
||||
mv.visitLocalVariable(nameForDestructuredParameter, type.getDescriptor(), null, methodBegin, methodEnd, shift);
|
||||
shift += type.getSize();
|
||||
}
|
||||
return shift;
|
||||
}
|
||||
|
||||
private static String computeParameterName(int i, ValueParameterDescriptor parameter) {
|
||||
PsiElement element = DescriptorToSourceUtils.descriptorToDeclaration(parameter);
|
||||
if (element instanceof KtParameter && UnderscoreUtilKt.isSingleUnderscore((KtParameter) element)) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@@ -20,7 +20,6 @@ import org.jetbrains.kotlin.codegen.inline.NUMBERED_FUNCTION_PREFIX
|
||||
import org.jetbrains.kotlin.codegen.inline.ReificationArgument
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.TypeIntrinsics
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.asSequence
|
||||
import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
@@ -315,15 +314,16 @@ fun MemberDescriptor.isToArrayFromCollection(): Boolean {
|
||||
fun FqName.topLevelClassInternalName() = JvmClassName.byClassId(ClassId(parent(), shortName())).internalName
|
||||
fun FqName.topLevelClassAsmType(): Type = Type.getObjectType(topLevelClassInternalName())
|
||||
|
||||
fun initializeVariablesForDestructuredLambdaParameters(codegen: ExpressionCodegen, valueParameters: List<ValueParameterDescriptor>) {
|
||||
fun initializeVariablesForDestructuredLambdaParameters(codegen: ExpressionCodegen, valueParameters: List<ValueParameterDescriptor>, endLabel: Label? = null) {
|
||||
// Do not write line numbers until destructuring happens
|
||||
// (otherwise destructuring variables will be uninitialized in the beginning of lambda)
|
||||
codegen.runWithShouldMarkLineNumbers(false) {
|
||||
for (parameterDescriptor in valueParameters) {
|
||||
if (parameterDescriptor !is ValueParameterDescriptorImpl.WithDestructuringDeclaration) continue
|
||||
|
||||
for (entry in parameterDescriptor.destructuringVariables.filterOutDescriptorsWithSpecialNames()) {
|
||||
codegen.myFrameMap.enter(entry, codegen.typeMapper.mapType(entry.type))
|
||||
val variables = parameterDescriptor.destructuringVariables.filterOutDescriptorsWithSpecialNames()
|
||||
val indices = variables.map {
|
||||
codegen.myFrameMap.enter(it, codegen.typeMapper.mapType(it.type))
|
||||
}
|
||||
|
||||
val destructuringDeclaration =
|
||||
@@ -335,6 +335,21 @@ fun initializeVariablesForDestructuredLambdaParameters(codegen: ExpressionCodege
|
||||
TransientReceiver(parameterDescriptor.type),
|
||||
codegen.findLocalOrCapturedValue(parameterDescriptor) ?: error("Local var not found for parameter $parameterDescriptor")
|
||||
)
|
||||
|
||||
if (endLabel != null) {
|
||||
val label = Label()
|
||||
codegen.v.mark(label)
|
||||
for ((index, entry) in indices.zip(variables)) {
|
||||
codegen.v.visitLocalVariable(
|
||||
entry.name.asString(),
|
||||
codegen.typeMapper.mapType(entry.type).descriptor,
|
||||
null,
|
||||
label,
|
||||
endLabel,
|
||||
index
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,11 +38,13 @@ import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
import org.jetbrains.kotlin.utils.sure
|
||||
import org.jetbrains.org.objectweb.asm.Label
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
import org.jetbrains.org.objectweb.asm.commons.Method
|
||||
import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
||||
|
||||
abstract class AbstractCoroutineCodegen(
|
||||
outerExpressionCodegen: ExpressionCodegen,
|
||||
@@ -176,6 +178,8 @@ class CoroutineCodegenForLambda private constructor(
|
||||
if (generateErasedCreate) getErasedCreateFunction() else getCreateFunction()
|
||||
}
|
||||
|
||||
private val endLabel = Label()
|
||||
|
||||
private fun getCreateFunction(): SimpleFunctionDescriptor = SimpleFunctionDescriptorImpl.create(
|
||||
funDescriptor.containingDeclaration,
|
||||
Annotations.EMPTY,
|
||||
@@ -425,12 +429,19 @@ class CoroutineCodegenForLambda private constructor(
|
||||
|
||||
val newIndex = myFrameMap.enter(parameter, mappedType)
|
||||
v.store(newIndex, mappedType)
|
||||
|
||||
val name =
|
||||
if (parameter is ReceiverParameterDescriptor) AsmUtil.RECEIVER_PARAMETER_NAME
|
||||
else (getNameForDestructuredParameterOrNull(parameter as ValueParameterDescriptor) ?: parameter.name.asString())
|
||||
val label = Label()
|
||||
v.mark(label)
|
||||
v.visitLocalVariable(name, mappedType.descriptor, null, label, endLabel, newIndex)
|
||||
}
|
||||
|
||||
initializeVariablesForDestructuredLambdaParameters(this, originalSuspendFunctionDescriptor.valueParameters)
|
||||
initializeVariablesForDestructuredLambdaParameters(this, originalSuspendFunctionDescriptor.valueParameters, endLabel)
|
||||
}
|
||||
|
||||
private fun allFunctionParameters() =
|
||||
private fun allFunctionParameters(): List<ParameterDescriptor> =
|
||||
originalSuspendFunctionDescriptor.extensionReceiverParameter.let(::listOfNotNull) +
|
||||
originalSuspendFunctionDescriptor.valueParameters
|
||||
|
||||
@@ -452,9 +463,10 @@ class CoroutineCodegenForLambda private constructor(
|
||||
object : FunctionGenerationStrategy.FunctionDefault(state, element as KtDeclarationWithBody) {
|
||||
|
||||
override fun wrapMethodVisitor(mv: MethodVisitor, access: Int, name: String, desc: String): MethodVisitor {
|
||||
if (forInline) return super.wrapMethodVisitor(mv, access, name, desc)
|
||||
val addEndLabelMethodVisitor = AddEndLabelMethodVisitor(mv, access, name, desc, endLabel)
|
||||
if (forInline) return super.wrapMethodVisitor(addEndLabelMethodVisitor, access, name, desc)
|
||||
return CoroutineTransformerMethodVisitor(
|
||||
mv, access, name, desc, null, null,
|
||||
addEndLabelMethodVisitor, access, name, desc, null, null,
|
||||
obtainClassBuilderForCoroutineState = { v },
|
||||
element = element,
|
||||
diagnostics = state.diagnostics,
|
||||
@@ -502,6 +514,22 @@ class CoroutineCodegenForLambda private constructor(
|
||||
}
|
||||
}
|
||||
|
||||
private class AddEndLabelMethodVisitor(
|
||||
delegate: MethodVisitor,
|
||||
access: Int,
|
||||
name: String,
|
||||
desc: String,
|
||||
private val endLabel: Label
|
||||
): TransformationMethodVisitor(delegate, access, name, desc, null, null) {
|
||||
override fun performTransformations(methodNode: MethodNode) {
|
||||
methodNode.instructions.add(
|
||||
withInstructionAdapter {
|
||||
mark(endLabel)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class CoroutineCodegenForNamedFunction private constructor(
|
||||
outerExpressionCodegen: ExpressionCodegen,
|
||||
element: KtElement,
|
||||
|
||||
+2
-2
@@ -13,8 +13,8 @@ suspend fun foo(data: Data, body: suspend (Data) -> Unit) {
|
||||
}
|
||||
|
||||
// METHOD : DataClassKt$test$2.invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
|
||||
// VARIABLE : NAME=this TYPE=LDataClassKt$test$2; INDEX=0
|
||||
// VARIABLE : NAME=result TYPE=Ljava/lang/Object; INDEX=1
|
||||
// VARIABLE : NAME=$dstr$x_param$y_param TYPE=LData; INDEX=2
|
||||
// VARIABLE : NAME=x_param TYPE=Ljava/lang/String; INDEX=3
|
||||
// VARIABLE : NAME=y_param TYPE=I INDEX=4
|
||||
// VARIABLE : NAME=this TYPE=LDataClassKt$test$2; INDEX=0
|
||||
// VARIABLE : NAME=result TYPE=Ljava/lang/Object; INDEX=1
|
||||
+2
-2
@@ -19,9 +19,9 @@ suspend fun B.bar(): String {
|
||||
suspend fun test() = B.bar()
|
||||
|
||||
// METHOD : ExtensionComponentsKt$bar$3.invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
|
||||
// VARIABLE : NAME=this TYPE=LExtensionComponentsKt$bar$3; INDEX=0
|
||||
// VARIABLE : NAME=result TYPE=Ljava/lang/Object; INDEX=1
|
||||
// VARIABLE : NAME=$dstr$x_param$y_param$z_param TYPE=LA; INDEX=2
|
||||
// VARIABLE : NAME=x_param TYPE=Ljava/lang/String; INDEX=3
|
||||
// VARIABLE : NAME=y_param TYPE=Ljava/lang/String; INDEX=4
|
||||
// VARIABLE : NAME=z_param TYPE=I INDEX=5
|
||||
// VARIABLE : NAME=this TYPE=LExtensionComponentsKt$bar$3; INDEX=0
|
||||
// VARIABLE : NAME=result TYPE=Ljava/lang/Object; INDEX=1
|
||||
+2
-2
@@ -8,8 +8,8 @@ suspend fun <X, Y> foo(a: A<X, Y>, block: suspend (A<X, Y>) -> String) = block(a
|
||||
suspend fun test() = foo(A("OK", 1)) { (x_param, y_param) -> x_param + (y_param.toString()) }
|
||||
|
||||
// METHOD : GenericKt$test$2.invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
|
||||
// VARIABLE : NAME=this TYPE=LGenericKt$test$2; INDEX=0
|
||||
// VARIABLE : NAME=result TYPE=Ljava/lang/Object; INDEX=1
|
||||
// VARIABLE : NAME=$dstr$x_param$y_param TYPE=LA; INDEX=2
|
||||
// VARIABLE : NAME=x_param TYPE=Ljava/lang/String; INDEX=3
|
||||
// VARIABLE : NAME=y_param TYPE=I INDEX=4
|
||||
// VARIABLE : NAME=this TYPE=LGenericKt$test$2; INDEX=0
|
||||
// VARIABLE : NAME=result TYPE=Ljava/lang/Object; INDEX=1
|
||||
+3
-4
@@ -7,11 +7,10 @@ suspend inline fun foo(a: A, block: suspend (A) -> String): String = block(a)
|
||||
suspend fun test() = foo(A("O", "K")) { (x_param, y_param) -> x_param + y_param }
|
||||
|
||||
// METHOD : InlineKt.test(Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
// VARIABLE : NAME=<name for destructuring parameter 0> TYPE=LA; INDEX=4
|
||||
// VARIABLE : NAME=$dstr$x_param$y_param TYPE=LA; INDEX=4
|
||||
// VARIABLE : NAME=continuation TYPE=Lkotlin/coroutines/Continuation; INDEX=3
|
||||
// VARIABLE : NAME=$dstr$x_param$y_param TYPE=LA; INDEX=6
|
||||
// VARIABLE : NAME=x_param TYPE=Ljava/lang/String; INDEX=7
|
||||
// VARIABLE : NAME=y_param TYPE=Ljava/lang/String; INDEX=8
|
||||
// VARIABLE : NAME=x_param TYPE=Ljava/lang/String; INDEX=6
|
||||
// VARIABLE : NAME=y_param TYPE=Ljava/lang/String; INDEX=7
|
||||
// VARIABLE : NAME=$i$a$-foo-InlineKt$test$2 TYPE=I INDEX=5
|
||||
// VARIABLE : NAME=a$iv TYPE=LA; INDEX=1
|
||||
// VARIABLE : NAME=$i$f$foo TYPE=I INDEX=2
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// WITH_RUNTIME
|
||||
data class Data(val x: String, val y: Int, val z: Int = 0)
|
||||
|
||||
suspend fun test() {
|
||||
foo(Data("A", 1)) { str, (x, _, z), i ->
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun foo(data: Data, body: suspend Long.(String, Data, Int) -> Unit) {
|
||||
1L.body("OK", data, 1)
|
||||
}
|
||||
|
||||
// METHOD : ParametersKt$test$2.invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
|
||||
// VARIABLE : NAME=$receiver TYPE=J INDEX=2
|
||||
// VARIABLE : NAME=str TYPE=Ljava/lang/String; INDEX=4
|
||||
// VARIABLE : NAME=$dstr$x$_u24__u24$z TYPE=LData; INDEX=5
|
||||
// VARIABLE : NAME=i TYPE=I INDEX=6
|
||||
// VARIABLE : NAME=x TYPE=Ljava/lang/String; INDEX=7
|
||||
// VARIABLE : NAME=z TYPE=I INDEX=8
|
||||
// VARIABLE : NAME=this TYPE=LParametersKt$test$2; INDEX=0
|
||||
// VARIABLE : NAME=result TYPE=Ljava/lang/Object; INDEX=1
|
||||
+2
-2
@@ -11,8 +11,8 @@ suspend fun foo(a: A, block: suspend (A) -> String): String = block(a)
|
||||
suspend fun test() = foo(A()) { (x_param, _, y_param) -> x_param + y_param }
|
||||
|
||||
// METHOD : UnderscoreNamesKt$test$2.invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
|
||||
// VARIABLE : NAME=this TYPE=LUnderscoreNamesKt$test$2; INDEX=0
|
||||
// VARIABLE : NAME=result TYPE=Ljava/lang/Object; INDEX=1
|
||||
// VARIABLE : NAME=$dstr$x_param$_u24__u24$y_param TYPE=LA; INDEX=2
|
||||
// VARIABLE : NAME=x_param TYPE=Ljava/lang/String; INDEX=3
|
||||
// VARIABLE : NAME=y_param TYPE=Ljava/lang/String; INDEX=4
|
||||
// VARIABLE : NAME=this TYPE=LUnderscoreNamesKt$test$2; INDEX=0
|
||||
// VARIABLE : NAME=result TYPE=Ljava/lang/Object; INDEX=1
|
||||
+15
-10
@@ -152,46 +152,51 @@ public class CheckLocalVariablesTableTestGenerated extends AbstractCheckLocalVar
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/checkLocalVariablesTable/destructuringInSuspendLambda")
|
||||
@TestMetadata("compiler/testData/checkLocalVariablesTable/parametersInSuspendLambda")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class DestructuringInSuspendLambda extends AbstractCheckLocalVariablesTableTest {
|
||||
public static class ParametersInSuspendLambda extends AbstractCheckLocalVariablesTableTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInDestructuringInSuspendLambda() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/checkLocalVariablesTable/destructuringInSuspendLambda"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
||||
public void testAllFilesPresentInParametersInSuspendLambda() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/checkLocalVariablesTable/parametersInSuspendLambda"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
||||
}
|
||||
|
||||
@TestMetadata("dataClass.kt")
|
||||
public void testDataClass() throws Exception {
|
||||
runTest("compiler/testData/checkLocalVariablesTable/destructuringInSuspendLambda/dataClass.kt");
|
||||
runTest("compiler/testData/checkLocalVariablesTable/parametersInSuspendLambda/dataClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("extensionComponents.kt")
|
||||
public void testExtensionComponents() throws Exception {
|
||||
runTest("compiler/testData/checkLocalVariablesTable/destructuringInSuspendLambda/extensionComponents.kt");
|
||||
runTest("compiler/testData/checkLocalVariablesTable/parametersInSuspendLambda/extensionComponents.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("generic.kt")
|
||||
public void testGeneric() throws Exception {
|
||||
runTest("compiler/testData/checkLocalVariablesTable/destructuringInSuspendLambda/generic.kt");
|
||||
runTest("compiler/testData/checkLocalVariablesTable/parametersInSuspendLambda/generic.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inline.kt")
|
||||
public void testInline() throws Exception {
|
||||
runTest("compiler/testData/checkLocalVariablesTable/destructuringInSuspendLambda/inline.kt");
|
||||
runTest("compiler/testData/checkLocalVariablesTable/parametersInSuspendLambda/inline.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("otherParameters.kt")
|
||||
public void testOtherParameters() throws Exception {
|
||||
runTest("compiler/testData/checkLocalVariablesTable/destructuringInSuspendLambda/otherParameters.kt");
|
||||
runTest("compiler/testData/checkLocalVariablesTable/parametersInSuspendLambda/otherParameters.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("parameters.kt")
|
||||
public void testParameters() throws Exception {
|
||||
runTest("compiler/testData/checkLocalVariablesTable/parametersInSuspendLambda/parameters.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("underscoreNames.kt")
|
||||
public void testUnderscoreNames() throws Exception {
|
||||
runTest("compiler/testData/checkLocalVariablesTable/destructuringInSuspendLambda/underscoreNames.kt");
|
||||
runTest("compiler/testData/checkLocalVariablesTable/parametersInSuspendLambda/underscoreNames.kt");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Generated
+15
-10
@@ -152,46 +152,51 @@ public class IrCheckLocalVariablesTableTestGenerated extends AbstractIrCheckLoca
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/checkLocalVariablesTable/destructuringInSuspendLambda")
|
||||
@TestMetadata("compiler/testData/checkLocalVariablesTable/parametersInSuspendLambda")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class DestructuringInSuspendLambda extends AbstractIrCheckLocalVariablesTableTest {
|
||||
public static class ParametersInSuspendLambda extends AbstractIrCheckLocalVariablesTableTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM_IR, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInDestructuringInSuspendLambda() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/checkLocalVariablesTable/destructuringInSuspendLambda"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM_IR, true);
|
||||
public void testAllFilesPresentInParametersInSuspendLambda() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/checkLocalVariablesTable/parametersInSuspendLambda"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@TestMetadata("dataClass.kt")
|
||||
public void testDataClass() throws Exception {
|
||||
runTest("compiler/testData/checkLocalVariablesTable/destructuringInSuspendLambda/dataClass.kt");
|
||||
runTest("compiler/testData/checkLocalVariablesTable/parametersInSuspendLambda/dataClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("extensionComponents.kt")
|
||||
public void testExtensionComponents() throws Exception {
|
||||
runTest("compiler/testData/checkLocalVariablesTable/destructuringInSuspendLambda/extensionComponents.kt");
|
||||
runTest("compiler/testData/checkLocalVariablesTable/parametersInSuspendLambda/extensionComponents.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("generic.kt")
|
||||
public void testGeneric() throws Exception {
|
||||
runTest("compiler/testData/checkLocalVariablesTable/destructuringInSuspendLambda/generic.kt");
|
||||
runTest("compiler/testData/checkLocalVariablesTable/parametersInSuspendLambda/generic.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inline.kt")
|
||||
public void testInline() throws Exception {
|
||||
runTest("compiler/testData/checkLocalVariablesTable/destructuringInSuspendLambda/inline.kt");
|
||||
runTest("compiler/testData/checkLocalVariablesTable/parametersInSuspendLambda/inline.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("otherParameters.kt")
|
||||
public void testOtherParameters() throws Exception {
|
||||
runTest("compiler/testData/checkLocalVariablesTable/destructuringInSuspendLambda/otherParameters.kt");
|
||||
runTest("compiler/testData/checkLocalVariablesTable/parametersInSuspendLambda/otherParameters.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("parameters.kt")
|
||||
public void testParameters() throws Exception {
|
||||
runTest("compiler/testData/checkLocalVariablesTable/parametersInSuspendLambda/parameters.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("underscoreNames.kt")
|
||||
public void testUnderscoreNames() throws Exception {
|
||||
runTest("compiler/testData/checkLocalVariablesTable/destructuringInSuspendLambda/underscoreNames.kt");
|
||||
runTest("compiler/testData/checkLocalVariablesTable/parametersInSuspendLambda/underscoreNames.kt");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+18
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@@ -802,8 +802,22 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
|
||||
wereChanges[0] = true;
|
||||
}
|
||||
}
|
||||
|
||||
Function0<List<VariableDescriptor>> destructuringVariablesAction = null;
|
||||
if (unsubstitutedValueParameter instanceof ValueParameterDescriptorImpl.WithDestructuringDeclaration) {
|
||||
final List<VariableDescriptor> destructuringVariables =
|
||||
((ValueParameterDescriptorImpl.WithDestructuringDeclaration) unsubstitutedValueParameter)
|
||||
.getDestructuringVariables();
|
||||
destructuringVariablesAction = new Function0<List<VariableDescriptor>>() {
|
||||
@Override
|
||||
public List<VariableDescriptor> invoke() {
|
||||
return destructuringVariables;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
result.add(
|
||||
new ValueParameterDescriptorImpl(
|
||||
ValueParameterDescriptorImpl.createWithDestructuringDeclarations(
|
||||
substitutedDescriptor,
|
||||
dropOriginal ? null : unsubstitutedValueParameter,
|
||||
unsubstitutedValueParameter.getIndex(),
|
||||
@@ -814,7 +828,8 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
|
||||
unsubstitutedValueParameter.isCrossinline(),
|
||||
unsubstitutedValueParameter.isNoinline(),
|
||||
substituteVarargElementType,
|
||||
preserveSourceElement ? unsubstitutedValueParameter.getSource() : SourceElement.NO_SOURCE
|
||||
preserveSourceElement ? unsubstitutedValueParameter.getSource() : SourceElement.NO_SOURCE,
|
||||
destructuringVariablesAction
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user