From 0d5913287f026b43b556ad3c76deb21739080fb5 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Thu, 23 Mar 2017 16:31:46 +0300 Subject: [PATCH] Add line numbers for suspend function to enhance stepping (KT-16025) Stop at function start on step into. Step at function end on step out. Both cases should actually be skipped by debugger, but this is postponed till new backend generation for suspend functions is ready. #KT-16025 Fixed --- .../SuspendFunctionGenerationStrategy.kt | 14 ++++---- .../debugger/tinyApp/outs/siSuspendFun.out | 14 ++++++++ .../debugger/tinyApp/outs/souSuspendFun.out | 14 ++++++++ .../src/stepping/stepInto/siSuspendFun.kt | 34 +++++++++++++++++++ .../src/stepping/stepOut/souSuspendFun.kt | 33 ++++++++++++++++++ .../debugger/KotlinSteppingTestGenerated.java | 12 +++++++ 6 files changed, 113 insertions(+), 8 deletions(-) create mode 100644 idea/testData/debugger/tinyApp/outs/siSuspendFun.out create mode 100644 idea/testData/debugger/tinyApp/outs/souSuspendFun.out create mode 100644 idea/testData/debugger/tinyApp/src/stepping/stepInto/siSuspendFun.kt create mode 100644 idea/testData/debugger/tinyApp/src/stepping/stepOut/souSuspendFun.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/SuspendFunctionGenerationStrategy.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/SuspendFunctionGenerationStrategy.kt index 417d568ff3e..fe16a57acdb 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/SuspendFunctionGenerationStrategy.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/SuspendFunctionGenerationStrategy.kt @@ -33,20 +33,18 @@ class SuspendFunctionGenerationStrategy( override fun doGenerateBody(codegen: ExpressionCodegen, signature: JvmMethodSignature) { if (!originalSuspendDescriptor.containsNonTailSuspensionCalls(state.bindingContext)) { - return codegen.returnExpression(declaration.bodyExpression) + codegen.returnExpression(declaration.bodyExpression) + return } val coroutineCodegen = CoroutineCodegen.create(codegen, originalSuspendDescriptor, declaration, state) coroutineCodegen.generate() + codegen.markLineNumber(declaration, false) codegen.putClosureInstanceOnStack(coroutineCodegen, null).put(Type.getObjectType(coroutineCodegen.className), codegen.v) + codegen.v.invokeDoResumeWithUnit(coroutineCodegen.v.thisName) - with(codegen.v) { - invokeDoResumeWithUnit(coroutineCodegen.v.thisName) - - codegen.markLineNumber(declaration, true) - - areturn(AsmTypes.OBJECT_TYPE) - } + codegen.markLineNumber(declaration, true) + codegen.v.areturn(AsmTypes.OBJECT_TYPE) } } diff --git a/idea/testData/debugger/tinyApp/outs/siSuspendFun.out b/idea/testData/debugger/tinyApp/outs/siSuspendFun.out new file mode 100644 index 00000000000..bc00109bdbd --- /dev/null +++ b/idea/testData/debugger/tinyApp/outs/siSuspendFun.out @@ -0,0 +1,14 @@ +LineBreakpoint created at siSuspendFun.kt:29 +Run Java +Connected to the target VM +siSuspendFun.kt:29 +siSuspendFun.kt:21 +siSuspendFun.kt:22 +siSuspendFun.kt:18 +siSuspendFun.kt:18 +siSuspendFun.kt:14 +siSuspendFun.kt:10 +siSuspendFun.kt:6 +Disconnected from the target VM + +Process finished with exit code 0 diff --git a/idea/testData/debugger/tinyApp/outs/souSuspendFun.out b/idea/testData/debugger/tinyApp/outs/souSuspendFun.out new file mode 100644 index 00000000000..8fa89777e34 --- /dev/null +++ b/idea/testData/debugger/tinyApp/outs/souSuspendFun.out @@ -0,0 +1,14 @@ +LineBreakpoint created at souSuspendFun.kt:7 +Run Java +Connected to the target VM +souSuspendFun.kt:7 +souSuspendFun.kt:11 +souSuspendFun.kt:15 +souSuspendFun.kt:19 +souSuspendFun.kt:19 +souSuspendFun.kt:23 +souSuspendFun.kt:25 +souSuspendFun.kt:29 +Disconnected from the target VM + +Process finished with exit code 0 diff --git a/idea/testData/debugger/tinyApp/src/stepping/stepInto/siSuspendFun.kt b/idea/testData/debugger/tinyApp/src/stepping/stepInto/siSuspendFun.kt new file mode 100644 index 00000000000..238deb8927d --- /dev/null +++ b/idea/testData/debugger/tinyApp/src/stepping/stepInto/siSuspendFun.kt @@ -0,0 +1,34 @@ +package siSuspendFun + +import forTests.builder + +private fun foo(): Int { + return 42 // 8 +} + +// One line suspend wihtout doResume +suspend fun fourth() = foo() // 7 + +// Multiline suspend without doResume +suspend fun third() : Int? { + return fourth() // 6 +} + +// One line suspend with doResume +suspend fun second(): Int = third()?.let { return it } ?: 0 // 4 (FIX IT!) 5 + +// Multiline suspend with doResume +suspend fun first(): Int { // 2 (FIX IT!) + second() // 3 + return 12 +} + +fun main(args: Array) { + builder { + //Breakpoint! + first() // 1 + foo() + } +} + +// STEP_INTO: 7 \ No newline at end of file diff --git a/idea/testData/debugger/tinyApp/src/stepping/stepOut/souSuspendFun.kt b/idea/testData/debugger/tinyApp/src/stepping/stepOut/souSuspendFun.kt new file mode 100644 index 00000000000..eb1170d41e3 --- /dev/null +++ b/idea/testData/debugger/tinyApp/src/stepping/stepOut/souSuspendFun.kt @@ -0,0 +1,33 @@ +package souSuspendFun + +import forTests.builder + +private fun foo(): Int { + //Breakpoint! + return 42 // 1 +} + +// One line suspend wihtout doResume +suspend fun fourth() = foo() // 2 + +// Multiline suspend without doResume +suspend fun third() : Int? { + return fourth() // 3 +} + +// One line suspend with doResume +suspend fun second(): Int = third()?.let { return it } ?: 0 // 4 5 (FIX IT) + +// Multiline suspend with doResume +suspend fun first(): Int { + second() // 6 + return 12 +} // 7 (FIX IT) + +fun main(args: Array) { + builder { + first() // 8 + } +} + +// STEP_OUT: 7 \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/debugger/KotlinSteppingTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/debugger/KotlinSteppingTestGenerated.java index 670e9c36de1..8b8fe9bc9df 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/debugger/KotlinSteppingTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/debugger/KotlinSteppingTestGenerated.java @@ -272,6 +272,12 @@ public class KotlinSteppingTestGenerated extends AbstractKotlinSteppingTest { doStepIntoTest(fileName); } + @TestMetadata("siSuspendFun.kt") + public void testSiSuspendFun() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/stepInto/siSuspendFun.kt"); + doStepIntoTest(fileName); + } + @TestMetadata("skipSimpleGetter.kt") public void testSkipSimpleGetter() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/stepInto/skipSimpleGetter.kt"); @@ -353,6 +359,12 @@ public class KotlinSteppingTestGenerated extends AbstractKotlinSteppingTest { doStepOutTest(fileName); } + @TestMetadata("souSuspendFun.kt") + public void testSouSuspendFun() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/stepOut/souSuspendFun.kt"); + doStepOutTest(fileName); + } + @TestMetadata("stepOutInlineFunction.kt") public void testStepOutInlineFunction() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/stepOut/stepOutInlineFunction.kt");