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(),
|
||||||
new Label(),
|
new Label(),
|
||||||
contextKind,
|
contextKind,
|
||||||
typeMapper
|
typeMapper,
|
||||||
);
|
0);
|
||||||
|
|
||||||
mv.visitEnd();
|
mv.visitEnd();
|
||||||
return;
|
return;
|
||||||
@@ -457,8 +457,11 @@ public class FunctionCodegen {
|
|||||||
|
|
||||||
Type thisType = getThisTypeForFunction(functionDescriptor, context, typeMapper);
|
Type thisType = getThisTypeForFunction(functionDescriptor, context, typeMapper);
|
||||||
generateLocalVariableTable(
|
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) {
|
if (context.isInlineMethodContext() && functionFakeIndex != -1) {
|
||||||
mv.visitLocalVariable(
|
mv.visitLocalVariable(
|
||||||
JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_FUNCTION + functionDescriptor.getName().asString(),
|
JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_FUNCTION + functionDescriptor.getName().asString(),
|
||||||
@@ -499,11 +502,13 @@ public class FunctionCodegen {
|
|||||||
@NotNull Label methodBegin,
|
@NotNull Label methodBegin,
|
||||||
@NotNull Label methodEnd,
|
@NotNull Label methodEnd,
|
||||||
@NotNull OwnerKind ownerKind,
|
@NotNull OwnerKind ownerKind,
|
||||||
@NotNull KotlinTypeMapper typeMapper
|
@NotNull KotlinTypeMapper typeMapper,
|
||||||
|
int shiftForDestructuringVariables
|
||||||
) {
|
) {
|
||||||
generateLocalVariablesForParameters(mv, jvmMethodSignature, thisType, methodBegin, methodEnd,
|
generateLocalVariablesForParameters(mv, jvmMethodSignature, thisType, methodBegin, methodEnd,
|
||||||
functionDescriptor.getValueParameters(),
|
functionDescriptor.getValueParameters(),
|
||||||
AsmUtil.isStaticMethod(ownerKind, functionDescriptor), typeMapper);
|
AsmUtil.isStaticMethod(ownerKind, functionDescriptor), typeMapper, shiftForDestructuringVariables
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void generateLocalVariablesForParameters(
|
public static void generateLocalVariablesForParameters(
|
||||||
@@ -515,6 +520,22 @@ public class FunctionCodegen {
|
|||||||
Collection<ValueParameterDescriptor> valueParameters,
|
Collection<ValueParameterDescriptor> valueParameters,
|
||||||
boolean isStatic,
|
boolean isStatic,
|
||||||
KotlinTypeMapper typeMapper
|
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();
|
Iterator<ValueParameterDescriptor> valueParameterIterator = valueParameters.iterator();
|
||||||
List<JvmMethodParameterSignature> params = jvmMethodSignature.getValueParameters();
|
List<JvmMethodParameterSignature> params = jvmMethodSignature.getValueParameters();
|
||||||
@@ -557,6 +578,7 @@ public class FunctionCodegen {
|
|||||||
shift += type.getSize();
|
shift += type.getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shift += shiftForDestructuringVariables;
|
||||||
for (ValueParameterDescriptor parameter : valueParameters) {
|
for (ValueParameterDescriptor parameter : valueParameters) {
|
||||||
List<VariableDescriptor> destructuringVariables = ValueParameterDescriptorImpl.getDestructuringVariablesOrNull(parameter);
|
List<VariableDescriptor> destructuringVariables = ValueParameterDescriptorImpl.getDestructuringVariablesOrNull(parameter);
|
||||||
if (destructuringVariables == null) continue;
|
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");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/destructuringDeclInLambdaParam/stdlibUsages.kt");
|
||||||
doTest(fileName);
|
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")
|
@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");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/destructuringDeclInLambdaParam/stdlibUsages.kt");
|
||||||
doTest(fileName);
|
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")
|
@TestMetadata("compiler/testData/codegen/box/diagnostics")
|
||||||
|
|||||||
@@ -1906,6 +1906,18 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("extension.kt")
|
||||||
public void testExtension() throws Exception {
|
public void testExtension() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/simple/extension.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/simple/extension.kt");
|
||||||
|
|||||||
@@ -53,6 +53,12 @@ public class CheckLocalVariablesTableTestGenerated extends AbstractCheckLocalVar
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("destructuringInlineLambda.kt")
|
||||||
|
public void testDestructuringInlineLambda() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/checkLocalVariablesTable/destructuringInlineLambda.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("inlineLambdaWithItParam.kt")
|
@TestMetadata("inlineLambdaWithItParam.kt")
|
||||||
public void testInlineLambdaWithItParam() throws Exception {
|
public void testInlineLambdaWithItParam() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/checkLocalVariablesTable/inlineLambdaWithItParam.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/checkLocalVariablesTable/inlineLambdaWithItParam.kt");
|
||||||
|
|||||||
+12
@@ -1906,6 +1906,18 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("extension.kt")
|
||||||
public void testExtension() throws Exception {
|
public void testExtension() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/simple/extension.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/simple/extension.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user