diff --git a/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/extractFunctionForDebuggerUtil.kt b/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/extractFunctionForDebuggerUtil.kt index a1844056c2b..86e29bf8307 100644 --- a/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/extractFunctionForDebuggerUtil.kt +++ b/idea/src/org/jetbrains/kotlin/idea/debugger/evaluate/extractFunctionForDebuggerUtil.kt @@ -24,11 +24,9 @@ import com.intellij.psi.PsiElement import com.intellij.psi.PsiFile import com.intellij.util.ExceptionUtil import org.jetbrains.kotlin.idea.actions.internal.KotlinInternalMode -import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.analyzeFullyAndGetResult import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils import org.jetbrains.kotlin.idea.core.replaced -import org.jetbrains.kotlin.idea.intentions.InsertExplicitTypeArgumentsIntention import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.* import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.AnalysisResult.ErrorMessage import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.AnalysisResult.Status @@ -42,7 +40,6 @@ import org.jetbrains.kotlin.psi.codeFragmentUtil.suppressDiagnosticsInDebugMode import org.jetbrains.kotlin.psi.psiUtil.findDescendantOfType import org.jetbrains.kotlin.psi.psiUtil.forEachDescendantOfType import org.jetbrains.kotlin.renderer.DescriptorRenderer -import org.jetbrains.kotlin.resolve.BindingContext.IMPLICIT_RECEIVER_SMARTCAST import org.jetbrains.kotlin.resolve.BindingContext.SMARTCAST fun getFunctionForExtractedFragment( @@ -290,12 +287,12 @@ private fun findElementBefore(contextElement: PsiElement): PsiElement? { contextElement is KtProperty && !contextElement.isLocal -> { val delegateExpressionOrInitializer = contextElement.delegateExpressionOrInitializer if (delegateExpressionOrInitializer != null) { - wrapInRunFun(delegateExpressionOrInitializer) + wrapInLambdaCall(delegateExpressionOrInitializer) } else { val getter = contextElement.getter!! if (!getter.hasBlockBody()) { - wrapInRunFun(getter.bodyExpression!!) + wrapInLambdaCall(getter.bodyExpression!!) } else { (getter.bodyExpression as KtBlockExpression).statements.first() @@ -323,7 +320,7 @@ private fun findElementBefore(contextElement: PsiElement): PsiElement? { newBlock.rBrace } contextElement is KtDeclarationWithBody && !contextElement.hasBlockBody() -> { - wrapInRunFun(contextElement.bodyExpression!!) + wrapInLambdaCall(contextElement.bodyExpression!!) } contextElement is KtDeclarationWithBody && contextElement.hasBlockBody() -> { val block = contextElement.bodyExpression as KtBlockExpression @@ -336,7 +333,7 @@ private fun findElementBefore(contextElement: PsiElement): PsiElement? { entryExpression.statements.firstOrNull() ?: entryExpression.lastChild } else { - wrapInRunFun(entryExpression!!) + wrapInLambdaCall(entryExpression!!) } } else -> { @@ -345,18 +342,12 @@ private fun findElementBefore(contextElement: PsiElement): PsiElement? { } } -private fun replaceByRunFunction(expression: KtExpression): KtCallExpression { - val callExpression = KtPsiFactory(expression).createExpression("run { \n${expression.text} \n}") as KtCallExpression - val replaced = expression.replaced(callExpression) - val typeArguments = InsertExplicitTypeArgumentsIntention.createTypeArguments(replaced, replaced.analyze()) - if (typeArguments?.arguments?.isNotEmpty() ?: false) { - val calleeExpression = replaced.calleeExpression - replaced.addAfter(typeArguments!!, calleeExpression) - } - return replaced +private fun replaceByLambdaCall(expression: KtExpression): KtCallExpression { + val callExpression = KtPsiFactory(expression).createExpression("{ \n${expression.text} \n}()") as KtCallExpression + return expression.replaced(callExpression) } -private fun wrapInRunFun(expression: KtExpression): PsiElement? { - val replacedBody = replaceByRunFunction(expression) - return replacedBody.lambdaArguments.first().getLambdaExpression().bodyExpression?.firstChild +private fun wrapInLambdaCall(expression: KtExpression): PsiElement? { + val replacedBody = replaceByLambdaCall(expression) + return (replacedBody.calleeExpression as? KtLambdaExpression)?.bodyExpression?.firstChild } diff --git a/idea/testData/debugger/tinyApp/outs/withoutBodyFunctions.out b/idea/testData/debugger/tinyApp/outs/withoutBodyFunctions.out index f846910f068..249938a5489 100644 --- a/idea/testData/debugger/tinyApp/outs/withoutBodyFunctions.out +++ b/idea/testData/debugger/tinyApp/outs/withoutBodyFunctions.out @@ -4,6 +4,7 @@ LineBreakpoint created at withoutBodyFunctions.kt:21 LineBreakpoint created at withoutBodyFunctions.kt:27 LineBreakpoint created at withoutBodyFunctions.kt:32 LineBreakpoint created at withoutBodyFunctions.kt:37 +LineBreakpoint created at withoutBodyFunctions.kt:43 !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! withoutBodyFunctions.WithoutBodyFunctionsKt Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' withoutBodyFunctions.kt:9 @@ -18,6 +19,8 @@ withoutBodyFunctions.kt:32 Compile bytecode for i withoutBodyFunctions.kt:37 Compile bytecode for i +withoutBodyFunctions.kt:43 +Compile bytecode for test2() Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' Process finished with exit code 0 diff --git a/idea/testData/debugger/tinyApp/src/evaluate/multipleBreakpoints/withoutBodyFunctions.kt b/idea/testData/debugger/tinyApp/src/evaluate/multipleBreakpoints/withoutBodyFunctions.kt index 8a5a3bbf5d0..5156a91c951 100644 --- a/idea/testData/debugger/tinyApp/src/evaluate/multipleBreakpoints/withoutBodyFunctions.kt +++ b/idea/testData/debugger/tinyApp/src/evaluate/multipleBreakpoints/withoutBodyFunctions.kt @@ -36,6 +36,14 @@ fun fooOneLine(i: Int): Int { return 1 } //Breakpoint! fun fooEmpty(i: Int) {} +object A { + // EXPRESSION: test2() + // RESULT: 2: I + //Breakpoint! + @JvmStatic fun fooWithoutBodyInsideObject() = test2() + fun test2() = 2 +} + fun main(args: Array) { aGet aGet2 @@ -44,4 +52,6 @@ fun main(args: Array) { foo(2) fooOneLine(2) fooEmpty(2) + + A.fooWithoutBodyInsideObject() } \ No newline at end of file