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");