Debugger: fix evaluate expression when breakpoint is set on function without body inside object
#KT-15855 Fixed
This commit is contained in:
committed by
Nikolay Krasko
parent
faac1c3156
commit
68f722b337
+10
-19
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
+10
@@ -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<String>) {
|
||||
aGet
|
||||
aGet2
|
||||
@@ -44,4 +52,6 @@ fun main(args: Array<String>) {
|
||||
foo(2)
|
||||
fooOneLine(2)
|
||||
fooEmpty(2)
|
||||
|
||||
A.fooWithoutBodyInsideObject()
|
||||
}
|
||||
Reference in New Issue
Block a user