Debugger: Handle closure receivers came from outer callables properly (KT-31709)
This commit is contained in:
@@ -1118,9 +1118,20 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
|
|
||||||
KotlinType captureReceiver = closure.getCapturedReceiverFromOuterContext();
|
KotlinType captureReceiver = closure.getCapturedReceiverFromOuterContext();
|
||||||
if (captureReceiver != null) {
|
if (captureReceiver != null) {
|
||||||
StackValue capturedReceiver =
|
StackValue capturedReceiver = functionReferenceReceiver;
|
||||||
functionReferenceReceiver != null ? functionReferenceReceiver :
|
if (capturedReceiver == null) {
|
||||||
generateExtensionReceiver(unwrapOriginalReceiverOwnerForSuspendLambda(context));
|
CallableDescriptor descriptor = unwrapOriginalReceiverOwnerForSuspendLambda(context);
|
||||||
|
if (descriptor.getExtensionReceiverParameter() != null) {
|
||||||
|
capturedReceiver = generateExtensionReceiver(descriptor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (capturedReceiver == null) {
|
||||||
|
CallableDescriptor descriptor = closure.getEnclosingCallableDescriptorWithReceiver();
|
||||||
|
if (descriptor != null) {
|
||||||
|
capturedReceiver = generateExtensionReceiver(descriptor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert capturedReceiver != null : "Captured receiver is null for closure " + closure;
|
||||||
callGenerator.putCapturedValueOnStack(capturedReceiver, capturedReceiver.type, paramIndex++);
|
callGenerator.putCapturedValueOnStack(capturedReceiver, capturedReceiver.type, paramIndex++);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.codegen.context.EnclosedValueDescriptor;
|
import org.jetbrains.kotlin.codegen.context.EnclosedValueDescriptor;
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings;
|
import org.jetbrains.kotlin.config.LanguageVersionSettings;
|
||||||
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor;
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||||
@@ -52,4 +53,7 @@ public interface CalculatedClosure {
|
|||||||
boolean isSuspend();
|
boolean isSuspend();
|
||||||
|
|
||||||
boolean isSuspendLambda();
|
boolean isSuspendLambda();
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
CallableDescriptor getEnclosingCallableDescriptorWithReceiver();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,7 +92,9 @@ public final class MutableClosure implements CalculatedClosure {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (captureEnclosingReceiver) {
|
if (captureEnclosingReceiver) {
|
||||||
ReceiverParameterDescriptor parameter = getEnclosingReceiverDescriptor();
|
CallableDescriptor descriptor = getEnclosingCallableDescriptorWithReceiver();
|
||||||
|
assert descriptor != null : "Receiver callable descriptor should exist";
|
||||||
|
ReceiverParameterDescriptor parameter = descriptor.getExtensionReceiverParameter();
|
||||||
assert parameter != null : "Receiver parameter should exist in " + enclosingFunWithReceiverDescriptor;
|
assert parameter != null : "Receiver parameter should exist in " + enclosingFunWithReceiverDescriptor;
|
||||||
return parameter.getType();
|
return parameter.getType();
|
||||||
}
|
}
|
||||||
@@ -190,7 +192,8 @@ public final class MutableClosure implements CalculatedClosure {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public ReceiverParameterDescriptor getEnclosingReceiverDescriptor() {
|
@Override
|
||||||
return enclosingFunWithReceiverDescriptor != null ? enclosingFunWithReceiverDescriptor.getExtensionReceiverParameter() : null;
|
public CallableDescriptor getEnclosingCallableDescriptorWithReceiver() {
|
||||||
|
return enclosingFunWithReceiverDescriptor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -138,7 +138,10 @@ public interface LocalLookup {
|
|||||||
MutableClosure closure,
|
MutableClosure closure,
|
||||||
Type classType
|
Type classType
|
||||||
) {
|
) {
|
||||||
ReceiverParameterDescriptor enclosingReceiverDescriptor = closure.getEnclosingReceiverDescriptor();
|
CallableDescriptor enclosingCallableWithReceiver = closure.getEnclosingCallableDescriptorWithReceiver();
|
||||||
|
ReceiverParameterDescriptor enclosingReceiverDescriptor =
|
||||||
|
enclosingCallableWithReceiver != null ? enclosingCallableWithReceiver.getExtensionReceiverParameter() : null;
|
||||||
|
|
||||||
if (enclosingReceiverDescriptor != d) {
|
if (enclosingReceiverDescriptor != d) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
//WITH_RUNTIME
|
||||||
|
|
||||||
|
// IGNORE_BACKEND: JVM_IR
|
||||||
|
// IGNORE_BACKEND: JS_IR
|
||||||
|
|
||||||
|
class Environment(
|
||||||
|
val fieldAccessedInsideChild: Int,
|
||||||
|
val how: Environment.() -> Unit
|
||||||
|
)
|
||||||
|
fun box(): String {
|
||||||
|
Environment(
|
||||||
|
3,
|
||||||
|
{
|
||||||
|
class Child {
|
||||||
|
val a = fieldAccessedInsideChild
|
||||||
|
}
|
||||||
|
class Parent {
|
||||||
|
val children: List<Child> =
|
||||||
|
(0..4).map { Child() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+5
@@ -10616,6 +10616,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
runTest("compiler/testData/codegen/box/extensionFunctions/kt1953_class.kt");
|
runTest("compiler/testData/codegen/box/extensionFunctions/kt1953_class.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt23675.kt")
|
||||||
|
public void testKt23675() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/extensionFunctions/kt23675.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kt3285.kt")
|
@TestMetadata("kt3285.kt")
|
||||||
public void testKt3285() throws Exception {
|
public void testKt3285() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/extensionFunctions/kt3285.kt");
|
runTest("compiler/testData/codegen/box/extensionFunctions/kt3285.kt");
|
||||||
|
|||||||
+5
@@ -10616,6 +10616,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
runTest("compiler/testData/codegen/box/extensionFunctions/kt1953_class.kt");
|
runTest("compiler/testData/codegen/box/extensionFunctions/kt1953_class.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt23675.kt")
|
||||||
|
public void testKt23675() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/extensionFunctions/kt23675.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kt3285.kt")
|
@TestMetadata("kt3285.kt")
|
||||||
public void testKt3285() throws Exception {
|
public void testKt3285() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/extensionFunctions/kt3285.kt");
|
runTest("compiler/testData/codegen/box/extensionFunctions/kt3285.kt");
|
||||||
|
|||||||
+5
@@ -9501,6 +9501,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/extensionFunctions/kt1953_class.kt");
|
runTest("compiler/testData/codegen/box/extensionFunctions/kt1953_class.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt23675.kt")
|
||||||
|
public void testKt23675() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/extensionFunctions/kt23675.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kt3285.kt")
|
@TestMetadata("kt3285.kt")
|
||||||
public void testKt3285() throws Exception {
|
public void testKt3285() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/extensionFunctions/kt3285.kt");
|
runTest("compiler/testData/codegen/box/extensionFunctions/kt3285.kt");
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package kt31709
|
||||||
|
|
||||||
|
data class A(val a: Int)
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
with(A(2)) {
|
||||||
|
//Breakpoint!
|
||||||
|
listOf(1, 2, 3, 4, 5).filter { it > a }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXPRESSION: listOf(1, 2, 3, 4, 5).filter { it > a }
|
||||||
|
// RESULT: instance of java.util.ArrayList(id=ID): Ljava/util/ArrayList;
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
LineBreakpoint created at kt31709.kt:8
|
||||||
|
Run Java
|
||||||
|
Connected to the target VM
|
||||||
|
kt31709.kt:8
|
||||||
|
Compile bytecode for listOf(1, 2, 3, 4, 5).filter { it > a }
|
||||||
|
kt31709.kt:8
|
||||||
|
resuming kt31709.kt:8
|
||||||
|
resuming kt31709.kt:8
|
||||||
|
resuming kt31709.kt:8
|
||||||
|
resuming kt31709.kt:8
|
||||||
|
Disconnected from the target VM
|
||||||
|
|
||||||
|
Process finished with exit code 0
|
||||||
Generated
+5
@@ -286,6 +286,11 @@ public class KotlinEvaluateExpressionTestGenerated extends AbstractKotlinEvaluat
|
|||||||
runTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/kt29179.kt");
|
runTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/kt29179.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt31709.kt")
|
||||||
|
public void testKt31709() throws Exception {
|
||||||
|
runTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/kt31709.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kt5554OnlyIntsShouldBeCoerced.kt")
|
@TestMetadata("kt5554OnlyIntsShouldBeCoerced.kt")
|
||||||
public void testKt5554OnlyIntsShouldBeCoerced() throws Exception {
|
public void testKt5554OnlyIntsShouldBeCoerced() throws Exception {
|
||||||
runTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/kt5554OnlyIntsShouldBeCoerced.kt");
|
runTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/kt5554OnlyIntsShouldBeCoerced.kt");
|
||||||
|
|||||||
Generated
+5
@@ -8241,6 +8241,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/extensionFunctions/kt1953_class.kt");
|
runTest("compiler/testData/codegen/box/extensionFunctions/kt1953_class.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt23675.kt")
|
||||||
|
public void testKt23675() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/extensionFunctions/kt23675.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kt3285.kt")
|
@TestMetadata("kt3285.kt")
|
||||||
public void testKt3285() throws Exception {
|
public void testKt3285() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/extensionFunctions/kt3285.kt");
|
runTest("compiler/testData/codegen/box/extensionFunctions/kt3285.kt");
|
||||||
|
|||||||
+5
@@ -9326,6 +9326,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/extensionFunctions/kt1953_class.kt");
|
runTest("compiler/testData/codegen/box/extensionFunctions/kt1953_class.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt23675.kt")
|
||||||
|
public void testKt23675() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/extensionFunctions/kt23675.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kt3285.kt")
|
@TestMetadata("kt3285.kt")
|
||||||
public void testKt3285() throws Exception {
|
public void testKt3285() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/extensionFunctions/kt3285.kt");
|
runTest("compiler/testData/codegen/box/extensionFunctions/kt3285.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user