Print source file location/contents if possible (EA-120038)
This commit is contained in:
@@ -18,7 +18,7 @@ package org.jetbrains.kotlin.idea.debugger.evaluate
|
|||||||
|
|
||||||
import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil
|
import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil
|
||||||
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl
|
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl
|
||||||
import com.intellij.debugger.jdi.StackFrameProxyImpl
|
import com.intellij.openapi.diagnostic.Attachment
|
||||||
import com.sun.jdi.ClassType
|
import com.sun.jdi.ClassType
|
||||||
import com.sun.jdi.InvalidStackFrameException
|
import com.sun.jdi.InvalidStackFrameException
|
||||||
import com.sun.jdi.ObjectReference
|
import com.sun.jdi.ObjectReference
|
||||||
@@ -30,14 +30,17 @@ import org.jetbrains.kotlin.codegen.AsmUtil
|
|||||||
import org.jetbrains.kotlin.codegen.inline.INLINE_FUN_VAR_SUFFIX
|
import org.jetbrains.kotlin.codegen.inline.INLINE_FUN_VAR_SUFFIX
|
||||||
import org.jetbrains.kotlin.codegen.inline.INLINE_TRANSFORMATION_SUFFIX
|
import org.jetbrains.kotlin.codegen.inline.INLINE_TRANSFORMATION_SUFFIX
|
||||||
import org.jetbrains.kotlin.codegen.inline.NUMBERED_FUNCTION_PREFIX
|
import org.jetbrains.kotlin.codegen.inline.NUMBERED_FUNCTION_PREFIX
|
||||||
|
import org.jetbrains.kotlin.idea.debugger.DebuggerUtils
|
||||||
import org.jetbrains.kotlin.idea.debugger.isInsideInlineFunctionBody
|
import org.jetbrains.kotlin.idea.debugger.isInsideInlineFunctionBody
|
||||||
import org.jetbrains.kotlin.idea.debugger.numberOfInlinedFunctions
|
import org.jetbrains.kotlin.idea.debugger.numberOfInlinedFunctions
|
||||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||||
|
import org.jetbrains.kotlin.idea.util.attachment.mergeAttachments
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
|
|
||||||
class FrameVisitor(context: EvaluationContextImpl) {
|
class FrameVisitor(val context: EvaluationContextImpl) {
|
||||||
private val scope = context.debugProcess.searchScope
|
private val scope = context.debugProcess.searchScope
|
||||||
private val frame = context.frameProxy
|
private val frame = context.frameProxy
|
||||||
|
|
||||||
@@ -95,7 +98,31 @@ class FrameVisitor(context: EvaluationContextImpl) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun fail(message: String, shouldFail: Boolean): Value? {
|
private fun fail(message: String, shouldFail: Boolean): Value? {
|
||||||
return if (shouldFail) throw EvaluateExceptionUtil.createEvaluateException(message) else null
|
if (!shouldFail) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
val location = frame?.location()
|
||||||
|
|
||||||
|
val locationText = location?.run { "Location: ${sourceName()}:${lineNumber()}" } ?: "No location available"
|
||||||
|
|
||||||
|
val sourceName = location?.sourceName()
|
||||||
|
val declaringTypeName = location?.declaringType()?.name()?.replace('.', '/')?.let { JvmClassName.byInternalName(it) }
|
||||||
|
|
||||||
|
val sourceFile = if (sourceName != null && declaringTypeName != null) {
|
||||||
|
DebuggerUtils.findSourceFileForClassIncludeLibrarySources(context.project, scope, declaringTypeName, sourceName)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
|
val sourceFileText = runReadAction { sourceFile?.text }
|
||||||
|
|
||||||
|
if (sourceName != null && sourceFileText != null) {
|
||||||
|
val attachments = mergeAttachments(Attachment(sourceName, sourceFileText), Attachment("location.txt", locationText))
|
||||||
|
LOG.error(message, attachments)
|
||||||
|
}
|
||||||
|
|
||||||
|
throw EvaluateExceptionUtil.createEvaluateException(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun findThis(asmType: Type?): Value? {
|
private fun findThis(asmType: Type?): Value? {
|
||||||
|
|||||||
Vendored
+1
-1
@@ -23,7 +23,7 @@ class Outer {
|
|||||||
// outer isn't captured in lambda
|
// outer isn't captured in lambda
|
||||||
lambda {
|
lambda {
|
||||||
// EXPRESSION: foo() + 2
|
// EXPRESSION: foo() + 2
|
||||||
// RESULT: Cannot find local variable: name = this
|
// RESULT: java.lang.AssertionError : Cannot find local variable: name = this
|
||||||
//Breakpoint!
|
//Breakpoint!
|
||||||
val a = 1
|
val a = 1
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -16,7 +16,7 @@ fun main(args: Array<String>) {
|
|||||||
|
|
||||||
fun myLocalFun3() {
|
fun myLocalFun3() {
|
||||||
// EXPRESSION: myLocalFun1() + 1
|
// EXPRESSION: myLocalFun1() + 1
|
||||||
// RESULT: Cannot find local variable: name = myLocalFun1
|
// RESULT: java.lang.AssertionError : Cannot find local variable: name = myLocalFun1
|
||||||
//Breakpoint!
|
//Breakpoint!
|
||||||
myLocalFun1() + 1
|
myLocalFun1() + 1
|
||||||
}
|
}
|
||||||
@@ -56,7 +56,7 @@ fun main(args: Array<String>) {
|
|||||||
i = 1
|
i = 1
|
||||||
fun myLocalFun7() {
|
fun myLocalFun7() {
|
||||||
// EXPRESSION: myLocalFun6() + 1
|
// EXPRESSION: myLocalFun6() + 1
|
||||||
// RESULT: Cannot find local variable: name = myLocalFun6
|
// RESULT: java.lang.AssertionError : Cannot find local variable: name = myLocalFun6
|
||||||
//Breakpoint!
|
//Breakpoint!
|
||||||
myLocalFun6() + 1
|
myLocalFun6() + 1
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -15,4 +15,4 @@ fun foo(f: () -> Unit) {
|
|||||||
// PRINT_FRAME
|
// PRINT_FRAME
|
||||||
|
|
||||||
// EXPRESSION: val1
|
// EXPRESSION: val1
|
||||||
// RESULT: Cannot find local variable: name = val1
|
// RESULT: java.lang.AssertionError : Cannot find local variable: name = val1
|
||||||
+1
-1
@@ -20,7 +20,7 @@ fun foo(f: () -> Unit) {
|
|||||||
// PRINT_FRAME
|
// PRINT_FRAME
|
||||||
|
|
||||||
// EXPRESSION: val1
|
// EXPRESSION: val1
|
||||||
// RESULT: Cannot find local variable: name = val1
|
// RESULT: java.lang.AssertionError : Cannot find local variable: name = val1
|
||||||
frame = invoke:7, FrameLambdaNotUsedKt$main$1 {frameLambdaNotUsed}
|
frame = invoke:7, FrameLambdaNotUsedKt$main$1 {frameLambdaNotUsed}
|
||||||
this = this = {frameLambdaNotUsed.FrameLambdaNotUsedKt$main$1@uniqueID}Function0<kotlin.Unit>
|
this = this = {frameLambdaNotUsed.FrameLambdaNotUsedKt$main$1@uniqueID}Function0<kotlin.Unit>
|
||||||
field = arity: int = 0 (sp = Lambda.!EXT!)
|
field = arity: int = 0 (sp = Lambda.!EXT!)
|
||||||
|
|||||||
Reference in New Issue
Block a user