Properly generate indices for destructured parameters in inline case
#KT-14399 Fixed
This commit is contained in:
@@ -216,8 +216,8 @@ public class FunctionCodegen {
|
||||
new Label(),
|
||||
new Label(),
|
||||
contextKind,
|
||||
typeMapper
|
||||
);
|
||||
typeMapper,
|
||||
0);
|
||||
|
||||
mv.visitEnd();
|
||||
return;
|
||||
@@ -457,8 +457,11 @@ public class FunctionCodegen {
|
||||
|
||||
Type thisType = getThisTypeForFunction(functionDescriptor, context, typeMapper);
|
||||
generateLocalVariableTable(
|
||||
mv, signature, functionDescriptor, thisType, methodBegin, methodEnd, context.getContextKind(), typeMapper);
|
||||
mv, signature, functionDescriptor, thisType, methodBegin, methodEnd, context.getContextKind(), typeMapper,
|
||||
(functionFakeIndex >= 0 ? 1 : 0) + (lambdaFakeIndex >= 0 ? 1 : 0)
|
||||
);
|
||||
|
||||
//TODO: it's best to move all below logic to 'generateLocalVariableTable' method
|
||||
if (context.isInlineMethodContext() && functionFakeIndex != -1) {
|
||||
mv.visitLocalVariable(
|
||||
JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_FUNCTION + functionDescriptor.getName().asString(),
|
||||
@@ -499,11 +502,13 @@ public class FunctionCodegen {
|
||||
@NotNull Label methodBegin,
|
||||
@NotNull Label methodEnd,
|
||||
@NotNull OwnerKind ownerKind,
|
||||
@NotNull KotlinTypeMapper typeMapper
|
||||
@NotNull KotlinTypeMapper typeMapper,
|
||||
int shiftForDestructuringVariables
|
||||
) {
|
||||
generateLocalVariablesForParameters(mv, jvmMethodSignature, thisType, methodBegin, methodEnd,
|
||||
functionDescriptor.getValueParameters(),
|
||||
AsmUtil.isStaticMethod(ownerKind, functionDescriptor), typeMapper);
|
||||
AsmUtil.isStaticMethod(ownerKind, functionDescriptor), typeMapper, shiftForDestructuringVariables
|
||||
);
|
||||
}
|
||||
|
||||
public static void generateLocalVariablesForParameters(
|
||||
@@ -515,6 +520,22 @@ public class FunctionCodegen {
|
||||
Collection<ValueParameterDescriptor> valueParameters,
|
||||
boolean isStatic,
|
||||
KotlinTypeMapper typeMapper
|
||||
) {
|
||||
generateLocalVariablesForParameters(
|
||||
mv, jvmMethodSignature, thisType, methodBegin, methodEnd, valueParameters, isStatic, typeMapper, 0
|
||||
);
|
||||
}
|
||||
|
||||
private static void generateLocalVariablesForParameters(
|
||||
@NotNull MethodVisitor mv,
|
||||
@NotNull JvmMethodSignature jvmMethodSignature,
|
||||
@Nullable Type thisType,
|
||||
@NotNull Label methodBegin,
|
||||
@NotNull Label methodEnd,
|
||||
Collection<ValueParameterDescriptor> valueParameters,
|
||||
boolean isStatic,
|
||||
KotlinTypeMapper typeMapper,
|
||||
int shiftForDestructuringVariables
|
||||
) {
|
||||
Iterator<ValueParameterDescriptor> valueParameterIterator = valueParameters.iterator();
|
||||
List<JvmMethodParameterSignature> params = jvmMethodSignature.getValueParameters();
|
||||
@@ -557,6 +578,7 @@ public class FunctionCodegen {
|
||||
shift += type.getSize();
|
||||
}
|
||||
|
||||
shift += shiftForDestructuringVariables;
|
||||
for (ValueParameterDescriptor parameter : valueParameters) {
|
||||
List<VariableDescriptor> destructuringVariables = ValueParameterDescriptorImpl.getDestructuringVariablesOrNull(parameter);
|
||||
if (destructuringVariables == null) continue;
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
inline fun foo(x: (Int, Station) -> Unit) {
|
||||
x(1, Station(null, "", 1))
|
||||
}
|
||||
|
||||
data class Station(
|
||||
val id: String?,
|
||||
val name: String,
|
||||
val distance: Int)
|
||||
|
||||
fun box(): String {
|
||||
foo { i, (a1, a2, a3) -> i + a3 }
|
||||
return "OK"
|
||||
}
|
||||
|
||||
// METHOD : DestructuringInlineLambdaKt.box()Ljava/lang/String;
|
||||
// VARIABLE : NAME=i TYPE=I INDEX=1
|
||||
// VARIABLE : NAME=$a1_a2_a3 TYPE=LStation; INDEX=0
|
||||
// VARIABLE : NAME=a1 TYPE=Ljava/lang/String; INDEX=2
|
||||
// VARIABLE : NAME=a2 TYPE=Ljava/lang/String; INDEX=3
|
||||
// VARIABLE : NAME=a3 TYPE=I INDEX=4
|
||||
// VARIABLE : NAME=$i$a$1$foo TYPE=I INDEX=5
|
||||
// VARIABLE : NAME=$i$f$foo TYPE=I INDEX=6
|
||||
@@ -0,0 +1,13 @@
|
||||
// WITH_RUNTIME
|
||||
data class Station(
|
||||
val id: String?,
|
||||
val name: String,
|
||||
val distance: Int)
|
||||
|
||||
fun box(): String {
|
||||
var result = ""
|
||||
// See KT-14399
|
||||
listOf(Station("O", "K", 56)).forEachIndexed { i, (id, name, distance) -> result += "$id$name$distance" }
|
||||
if (result != "OK56") return "fail: $result"
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
// FILE: 1.kt
|
||||
package test
|
||||
|
||||
inline fun foo(x: (Int, Station) -> Unit) {
|
||||
x(1, Station(null, "", 1))
|
||||
}
|
||||
|
||||
data class Station(
|
||||
val id: String?,
|
||||
val name: String,
|
||||
val distance: Int)
|
||||
|
||||
|
||||
// FILE: 2.kt
|
||||
import test.*
|
||||
|
||||
fun box(): String {
|
||||
foo { i, (a1, a2, a3) -> i + a3 }
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
// for android
|
||||
// FILE: 1.kt
|
||||
package test
|
||||
|
||||
var res = "fail"
|
||||
|
||||
inline fun foo(x: (Int, Station) -> Unit) {
|
||||
x(1, Station("a", "b", "c"))
|
||||
res = "O"
|
||||
}
|
||||
|
||||
inline fun foo2(x: (Int, StationInt) -> Unit) {
|
||||
x(1, StationInt(1, 2, 3))
|
||||
res += "K"
|
||||
}
|
||||
|
||||
data class Station(
|
||||
val id: String,
|
||||
val name: String,
|
||||
val distance: String)
|
||||
|
||||
data class StationInt(
|
||||
val id: Int,
|
||||
val name: Int,
|
||||
val distance: Int)
|
||||
|
||||
|
||||
// FILE: 2.kt
|
||||
import test.*
|
||||
|
||||
fun box(): String {
|
||||
foo { i, (a1, a2, a3) -> a3 + i }
|
||||
foo2 { i, (a1, a2, a3) -> i + a3 }
|
||||
return res
|
||||
}
|
||||
+6
@@ -5775,6 +5775,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/destructuringDeclInLambdaParam/stdlibUsages.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("withIndexed.kt")
|
||||
public void testWithIndexed() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/destructuringDeclInLambdaParam/withIndexed.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/diagnostics")
|
||||
|
||||
@@ -5775,6 +5775,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/destructuringDeclInLambdaParam/stdlibUsages.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("withIndexed.kt")
|
||||
public void testWithIndexed() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/destructuringDeclInLambdaParam/withIndexed.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/diagnostics")
|
||||
|
||||
@@ -1906,6 +1906,18 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("destructuring.kt")
|
||||
public void testDestructuring() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/simple/destructuring.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("destructuringIndexClash.kt")
|
||||
public void testDestructuringIndexClash() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/simple/destructuringIndexClash.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("extension.kt")
|
||||
public void testExtension() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/simple/extension.kt");
|
||||
|
||||
@@ -53,6 +53,12 @@ public class CheckLocalVariablesTableTestGenerated extends AbstractCheckLocalVar
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("destructuringInlineLambda.kt")
|
||||
public void testDestructuringInlineLambda() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/checkLocalVariablesTable/destructuringInlineLambda.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inlineLambdaWithItParam.kt")
|
||||
public void testInlineLambdaWithItParam() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/checkLocalVariablesTable/inlineLambdaWithItParam.kt");
|
||||
|
||||
+12
@@ -1906,6 +1906,18 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("destructuring.kt")
|
||||
public void testDestructuring() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/simple/destructuring.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("destructuringIndexClash.kt")
|
||||
public void testDestructuringIndexClash() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/simple/destructuringIndexClash.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("extension.kt")
|
||||
public void testExtension() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/simple/extension.kt");
|
||||
|
||||
Reference in New Issue
Block a user