Support single-underscore named variables in JVM backend
There are mainly two kind of changes: - skipping 'componentX' calls for destructuring entries named _ - fixing local variable table for them - skip entries for destructuring entries named _ - use $noName_<i> format for lambda parameters named _ #KT-3824 Fixed #KT-2783 Fixed
This commit is contained in:
@@ -44,7 +44,7 @@ class ClosureGenerationStrategy(
|
||||
for (parameterDescriptor in codegen.context.functionDescriptor.valueParameters) {
|
||||
if (parameterDescriptor !is ValueParameterDescriptorImpl.WithDestructuringDeclaration) continue
|
||||
|
||||
for (entry in parameterDescriptor.destructuringVariables) {
|
||||
for (entry in parameterDescriptor.destructuringVariables.filterOutDescriptorsWithSpecialNames()) {
|
||||
codegen.myFrameMap.enter(entry, codegen.typeMapper.mapType(entry.type))
|
||||
}
|
||||
|
||||
|
||||
@@ -775,9 +775,19 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
private void generateDestructuringDeclaration(@NotNull KtDestructuringDeclaration destructuringDeclaration) {
|
||||
final Label destructuringStartLabel = new Label();
|
||||
for (KtDestructuringDeclarationEntry variableDeclaration : destructuringDeclaration.getEntries()) {
|
||||
final VariableDescriptor componentDescriptor = bindingContext.get(VARIABLE, variableDeclaration);
|
||||
|
||||
List<VariableDescriptor> componentDescriptors =
|
||||
CollectionsKt.map(
|
||||
destructuringDeclaration.getEntries(),
|
||||
new Function1<KtDestructuringDeclarationEntry, VariableDescriptor>() {
|
||||
@Override
|
||||
public VariableDescriptor invoke(KtDestructuringDeclarationEntry entry) {
|
||||
return getVariableDescriptorNotNull(entry);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
for (final VariableDescriptor componentDescriptor : CodegenUtilKt.filterOutDescriptorsWithSpecialNames(componentDescriptors)) {
|
||||
@SuppressWarnings("ConstantConditions") final Type componentAsmType = asmType(componentDescriptor.getReturnType());
|
||||
final int componentVarIndex = myFrameMap.enter(componentDescriptor, componentAsmType);
|
||||
scheduleLeaveVariable(new Runnable() {
|
||||
@@ -1957,8 +1967,10 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
}
|
||||
|
||||
private void putLocalVariableIntoFrameMap(@NotNull KtVariableDeclaration statement) {
|
||||
VariableDescriptor variableDescriptor = bindingContext.get(VARIABLE, statement);
|
||||
assert variableDescriptor != null : "Couldn't find variable declaration in binding context " + statement.getText();
|
||||
VariableDescriptor variableDescriptor = getVariableDescriptorNotNull(statement);
|
||||
// Do not modify local variables table for variables like _ in val (_, y) = pair
|
||||
// They always will have special name
|
||||
if (variableDescriptor.getName().isSpecial()) return;
|
||||
|
||||
Type type = getVariableType(variableDescriptor);
|
||||
int index = myFrameMap.enter(variableDescriptor, type);
|
||||
@@ -2004,6 +2016,10 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
) {
|
||||
final VariableDescriptor variableDescriptor = getVariableDescriptorNotNull(statement);
|
||||
|
||||
// Do not modify local variables table for variables like _ in val (_, y) = pair
|
||||
// They always will have special name
|
||||
if (variableDescriptor.getName().isSpecial()) return;
|
||||
|
||||
final Type type = getVariableType(variableDescriptor);
|
||||
|
||||
final Label scopeStart = new Label();
|
||||
@@ -3902,6 +3918,12 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
ResolvedCall<FunctionDescriptor> resolvedCall = bindingContext.get(COMPONENT_RESOLVED_CALL, variableDeclaration);
|
||||
assert resolvedCall != null : "Resolved call is null for " + variableDeclaration.getText();
|
||||
Call call = makeFakeCall(receiver);
|
||||
|
||||
VariableDescriptor variableDescriptor = getVariableDescriptorNotNull(variableDeclaration);
|
||||
|
||||
// Do not call `componentX` for destructuring entry called _
|
||||
if (variableDescriptor.getName().isSpecial()) continue;
|
||||
|
||||
initializeLocalVariable(variableDeclaration, invokeFunction(call, resolvedCall, receiverStackValue));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,9 +46,11 @@ import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.psi.KtElement;
|
||||
import org.jetbrains.kotlin.psi.KtFunction;
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction;
|
||||
import org.jetbrains.kotlin.psi.KtParameter;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.resolve.calls.util.UnderscoreUtilKt;
|
||||
import org.jetbrains.kotlin.resolve.constants.ArrayValue;
|
||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
|
||||
import org.jetbrains.kotlin.resolve.constants.KClassValue;
|
||||
@@ -563,7 +565,7 @@ public class FunctionCodegen {
|
||||
|
||||
parameterName =
|
||||
destructuringVariables == null
|
||||
? parameter.getName().asString()
|
||||
? computeParameterName(i, parameter)
|
||||
: "$" + joinParameterNames(destructuringVariables);
|
||||
}
|
||||
else {
|
||||
@@ -583,7 +585,7 @@ public class FunctionCodegen {
|
||||
List<VariableDescriptor> destructuringVariables = ValueParameterDescriptorImpl.getDestructuringVariablesOrNull(parameter);
|
||||
if (destructuringVariables == null) continue;
|
||||
|
||||
for (VariableDescriptor entry : destructuringVariables) {
|
||||
for (VariableDescriptor entry : CodegenUtilKt.filterOutDescriptorsWithSpecialNames(destructuringVariables)) {
|
||||
Type type = typeMapper.mapType(entry.getType());
|
||||
mv.visitLocalVariable(entry.getName().asString(), type.getDescriptor(), null, methodBegin, methodEnd, shift);
|
||||
shift += type.getSize();
|
||||
@@ -591,10 +593,21 @@ public class FunctionCodegen {
|
||||
}
|
||||
}
|
||||
|
||||
private static String computeParameterName(int i, ValueParameterDescriptor parameter) {
|
||||
PsiElement element = DescriptorToSourceUtils.descriptorToDeclaration(parameter);
|
||||
if (element instanceof KtParameter && UnderscoreUtilKt.isSingleUnderscore((KtParameter) element)) {
|
||||
return "$noName_" + i;
|
||||
}
|
||||
|
||||
return parameter.getName().asString();
|
||||
}
|
||||
|
||||
private static String joinParameterNames(@NotNull List<VariableDescriptor> variables) {
|
||||
return org.jetbrains.kotlin.utils.StringsKt.join(CollectionsKt.map(variables, new Function1<VariableDescriptor, String>() {
|
||||
@Override
|
||||
public String invoke(VariableDescriptor descriptor) {
|
||||
// stub for anonymous destructuring declaration entry
|
||||
if (descriptor.getName().isSpecial()) return "$_$";
|
||||
return descriptor.getName().asString();
|
||||
}
|
||||
}), "_");
|
||||
|
||||
@@ -255,3 +255,5 @@ private fun CallableDescriptor.isJvmStaticIn(predicate: (DeclarationDescriptor)
|
||||
}
|
||||
else -> predicate(containingDeclaration) && hasJvmStaticAnnotation()
|
||||
}
|
||||
|
||||
fun Collection<VariableDescriptor>.filterOutDescriptorsWithSpecialNames() = filterNot { it.name.isSpecial }
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
data class A(val x: Double = 1.0, val y: String = "", val z: Char = '0')
|
||||
|
||||
fun foo(a: A, block: (A, String, Int) -> String): String = block(a, "", 1)
|
||||
|
||||
val arrayOfA: Array<A> = Array(1) { A() }
|
||||
|
||||
fun box() {
|
||||
|
||||
foo(A()) {
|
||||
(x, _, y), _, w ->
|
||||
|
||||
val (a, _, c) = A()
|
||||
val (_, `_`, d) = A()
|
||||
|
||||
for ((_, q) in arrayOfA) {
|
||||
|
||||
}
|
||||
|
||||
""
|
||||
}
|
||||
}
|
||||
|
||||
// METHOD : UnderscoreNamesKt$box$1.invoke(LA;Ljava/lang/String;I)Ljava/lang/String;
|
||||
// VARIABLE : NAME=q TYPE=Ljava/lang/String; INDEX=15
|
||||
// VARIABLE : NAME=d TYPE=C INDEX=11
|
||||
// VARIABLE : NAME=_ TYPE=Ljava/lang/String; INDEX=10
|
||||
// VARIABLE : NAME=c TYPE=C INDEX=9
|
||||
// VARIABLE : NAME=a TYPE=D INDEX=7
|
||||
// VARIABLE : NAME=this TYPE=LUnderscoreNamesKt$box$1; INDEX=0
|
||||
// VARIABLE : NAME=$x_$_$_y TYPE=LA; INDEX=1
|
||||
// VARIABLE : NAME=$noName_1 TYPE=Ljava/lang/String; INDEX=2
|
||||
// VARIABLE : NAME=w TYPE=I INDEX=3
|
||||
// VARIABLE : NAME=x TYPE=D INDEX=4
|
||||
// VARIABLE : NAME=y TYPE=C INDEX=6
|
||||
@@ -0,0 +1,3 @@
|
||||
fun foo(block: (String, String, String) -> String): String = block("O", "fail", "K")
|
||||
|
||||
fun box() = foo { x, _, y -> x + y }
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
class A {
|
||||
operator fun component1() = "O"
|
||||
operator fun component2(): String = throw RuntimeException("fail 0")
|
||||
operator fun component3() = "K"
|
||||
}
|
||||
|
||||
fun foo(a: A, block: (A) -> String): String = block(a)
|
||||
|
||||
fun box() = foo(A()) { (x, _, y) -> x + y }
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fun foo(block: (String, String, String) -> String): String = block("O", "fail", "K")
|
||||
|
||||
fun box() = foo(fun(x: String, _: String, y: String) = x + y)
|
||||
@@ -0,0 +1,14 @@
|
||||
class A {
|
||||
operator fun component1() = 1
|
||||
operator fun component2() = 2
|
||||
}
|
||||
|
||||
fun box() : String {
|
||||
val (_, b) = A()
|
||||
|
||||
val (a, _) = A()
|
||||
|
||||
val (`_`, c) = A()
|
||||
|
||||
return if (a == 1 && b == 2 && _ == 1 && c == 2) "OK" else "fail"
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
class Range(val from : C, val to: C) {
|
||||
operator fun iterator() = It(from, to)
|
||||
}
|
||||
|
||||
class It(val from: C, val to: C) {
|
||||
var c = from.i
|
||||
|
||||
operator fun next(): C {
|
||||
val next = C(c)
|
||||
c++
|
||||
return next
|
||||
}
|
||||
|
||||
operator fun hasNext(): Boolean = c <= to.i
|
||||
}
|
||||
|
||||
class C(val i : Int) {
|
||||
operator fun component1() = i + 1
|
||||
operator fun component2() = i + 2
|
||||
operator fun rangeTo(c: C) = Range(this, c)
|
||||
}
|
||||
|
||||
fun doTest(): String {
|
||||
var s = ""
|
||||
for ((a, _) in C(0)..C(2)) {
|
||||
s += "$a;"
|
||||
}
|
||||
|
||||
for ((_, b) in C(1)..C(3)) {
|
||||
s += "$b;"
|
||||
}
|
||||
|
||||
for ((_, `_`) in C(2)..C(4)) {
|
||||
s += "$_;"
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val s = doTest()
|
||||
return if (s == "1;2;3;3;4;5;4;5;6;") "OK" else "fail: $s"
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
class A {
|
||||
operator fun component1() = "O"
|
||||
operator fun component2(): String = throw RuntimeException("fail 0")
|
||||
operator fun component3() = "K"
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val aA = Array(1) { A() }
|
||||
|
||||
for ((x, _, z) in aA) {
|
||||
return x + z
|
||||
}
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+36
@@ -3445,6 +3445,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("underscoreParameters.kt")
|
||||
public void testUnderscoreParameters() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/underscoreParameters.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/closures/captureOuterProperty")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@@ -5776,6 +5782,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("underscoreNames.kt")
|
||||
public void testUnderscoreNames() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/destructuringDeclInLambdaParam/underscoreNames.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("withIndexed.kt")
|
||||
public void testWithIndexed() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/destructuringDeclInLambdaParam/withIndexed.kt");
|
||||
@@ -7238,6 +7250,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/functions/functionExpression/functionLiteralExpression.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("underscoreParameters.kt")
|
||||
public void testUnderscoreParameters() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/functions/functionExpression/underscoreParameters.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/functions/invoke")
|
||||
@@ -9043,6 +9061,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("UnderscoreNames.kt")
|
||||
public void testUnderscoreNames() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/UnderscoreNames.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("ValCapturedInFunctionLiteral.kt")
|
||||
public void testValCapturedInFunctionLiteral() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/ValCapturedInFunctionLiteral.kt");
|
||||
@@ -9189,6 +9213,18 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("UnderscoreNames.kt")
|
||||
public void testUnderscoreNames() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forRange/UnderscoreNames.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("UnderscoreNamesDontCallComponent.kt")
|
||||
public void testUnderscoreNamesDontCallComponent() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forRange/UnderscoreNamesDontCallComponent.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/multiDecl/forRange/explicitRangeTo")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
@@ -3445,6 +3445,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("underscoreParameters.kt")
|
||||
public void testUnderscoreParameters() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/underscoreParameters.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/closures/captureOuterProperty")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@@ -5776,6 +5782,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("underscoreNames.kt")
|
||||
public void testUnderscoreNames() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/destructuringDeclInLambdaParam/underscoreNames.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("withIndexed.kt")
|
||||
public void testWithIndexed() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/destructuringDeclInLambdaParam/withIndexed.kt");
|
||||
@@ -7238,6 +7250,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/functions/functionExpression/functionLiteralExpression.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("underscoreParameters.kt")
|
||||
public void testUnderscoreParameters() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/functions/functionExpression/underscoreParameters.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/functions/invoke")
|
||||
@@ -9043,6 +9061,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("UnderscoreNames.kt")
|
||||
public void testUnderscoreNames() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/UnderscoreNames.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("ValCapturedInFunctionLiteral.kt")
|
||||
public void testValCapturedInFunctionLiteral() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/ValCapturedInFunctionLiteral.kt");
|
||||
@@ -9189,6 +9213,18 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("UnderscoreNames.kt")
|
||||
public void testUnderscoreNames() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forRange/UnderscoreNames.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("UnderscoreNamesDontCallComponent.kt")
|
||||
public void testUnderscoreNamesDontCallComponent() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forRange/UnderscoreNamesDontCallComponent.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/multiDecl/forRange/explicitRangeTo")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
@@ -118,4 +118,10 @@ public class CheckLocalVariablesTableTestGenerated extends AbstractCheckLocalVar
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/checkLocalVariablesTable/localFun.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("underscoreNames.kt")
|
||||
public void testUnderscoreNames() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/checkLocalVariablesTable/underscoreNames.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
LineBreakpoint created at underscoreNames.kt:18 lambdaOrdinal = 1
|
||||
!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !OUTPUT_PATH!;!KOTLIN_RUNTIME!;!CUSTOM_LIBRARY!;!RT_JAR! underscoreNames.UnderscoreNamesKt
|
||||
Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||
underscoreNames.kt:18
|
||||
Compile bytecode for x
|
||||
Compile bytecode for y
|
||||
package underscoreNames
|
||||
data class A(val x: Double = 1.0, val y: String = "", val z: Char = '0')
|
||||
|
||||
fun foo(a: A, block: (A, String, Int) -> String): String = block(a, "", 1)
|
||||
|
||||
val arrayOfA: Array<A> = Array(1) { A() }
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
|
||||
foo(A()) {
|
||||
(x, _, y), _, w ->
|
||||
|
||||
val (a, _, c) = A()
|
||||
val (_, `_`, d) = A()
|
||||
|
||||
for ((_, q) in arrayOfA) {
|
||||
//Breakpoint! (lambdaOrdinal = 1)
|
||||
println(q)
|
||||
}
|
||||
|
||||
""
|
||||
}
|
||||
}
|
||||
|
||||
// PRINT_FRAME
|
||||
|
||||
// EXPRESSION: x
|
||||
// RESULT: 1.0: D
|
||||
|
||||
// EXPRESSION: y
|
||||
// RESULT: 48: C
|
||||
|
||||
|
||||
Compile bytecode for arrayOfA
|
||||
frame = invoke:18, UnderscoreNamesKt$main$1 {underscoreNames}
|
||||
this = this = {underscoreNames.UnderscoreNamesKt$main$1@uniqueID}Function3<underscoreNames.A, java.lang.String, java.lang.Integer, java.lang.String>
|
||||
field = arity: int = 3 (sp = Lambda.!EXT!)
|
||||
local = $x_$_$_y: underscoreNames.A = {underscoreNames.A@uniqueID}A(x=1.0, y=, z=0) (sp = null)
|
||||
field = x: double = 1.0 (sp = underscoreNames.kt, 2)
|
||||
field = y: java.lang.String = (sp = underscoreNames.kt, 2)
|
||||
field = value: char[] = {char[0]@uniqueID} (sp = String.!EXT!)
|
||||
field = hash: int = 0 (sp = String.!EXT!)
|
||||
field = z: char = '0' 48 (sp = underscoreNames.kt, 2)
|
||||
local = $noName_1: java.lang.String = (sp = null)
|
||||
field = value: char[] = {char[0]@uniqueID} (sp = String.!EXT!)
|
||||
field = hash: int = 0 (sp = String.!EXT!)
|
||||
local = w: int = 1 (sp = underscoreNames.kt, 11)
|
||||
local = x: double = 1.0 (sp = underscoreNames.kt, 11)
|
||||
local = y: char = '0' 48 (sp = underscoreNames.kt, 11)
|
||||
local = a: double = 1.0 (sp = underscoreNames.kt, 13)
|
||||
local = c: char = '0' 48 (sp = underscoreNames.kt, 13)
|
||||
local = _: java.lang.String = (sp = underscoreNames.kt, 14)
|
||||
field = value: char[] = {char[0]@uniqueID} (sp = String.!EXT!)
|
||||
field = hash: int = 0 (sp = String.!EXT!)
|
||||
local = d: char = '0' 48 (sp = underscoreNames.kt, 14)
|
||||
local = q: java.lang.String = (sp = underscoreNames.kt, 16)
|
||||
field = value: char[] = {char[0]@uniqueID} (sp = String.!EXT!)
|
||||
field = hash: int = 0 (sp = String.!EXT!)
|
||||
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||
|
||||
Process finished with exit code 0
|
||||
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package underscoreNames
|
||||
data class A(val x: Double = 1.0, val y: String = "", val z: Char = '0')
|
||||
|
||||
fun foo(a: A, block: (A, String, Int) -> String): String = block(a, "", 1)
|
||||
|
||||
val arrayOfA: Array<A> = Array(1) { A() }
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
|
||||
foo(A()) {
|
||||
(x, _, y), _, w ->
|
||||
|
||||
val (a, _, c) = A()
|
||||
val (_, `_`, d) = A()
|
||||
|
||||
for ((_, q) in arrayOfA) {
|
||||
//Breakpoint! (lambdaOrdinal = 1)
|
||||
println(q)
|
||||
}
|
||||
|
||||
""
|
||||
}
|
||||
}
|
||||
|
||||
// PRINT_FRAME
|
||||
|
||||
// EXPRESSION: x
|
||||
// RESULT: 1.0: D
|
||||
|
||||
// EXPRESSION: y
|
||||
// RESULT: 48: C
|
||||
|
||||
+6
@@ -842,6 +842,12 @@ public class KotlinEvaluateExpressionTestGenerated extends AbstractKotlinEvaluat
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/lambdas/twoLambdasOnOneLineSecond.kt");
|
||||
doSingleBreakpointTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("underscoreNames.kt")
|
||||
public void testUnderscoreNames() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/lambdas/underscoreNames.kt");
|
||||
doSingleBreakpointTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/renderer")
|
||||
|
||||
+6
@@ -52,4 +52,10 @@ public class FunctionExpressionTestGenerated extends AbstractFunctionExpressionT
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/functions/functionExpression/functionLiteralExpression.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("underscoreParameters.kt")
|
||||
public void testUnderscoreParameters() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/functions/functionExpression/underscoreParameters.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user