Evaluate expression: support captured vals
This commit is contained in:
+1
-1
@@ -84,7 +84,7 @@ class KotlinEvaluateExpressionCache(val project: Project) {
|
||||
private fun canBeEvaluatedInThisContext(compiledData: CompiledDataDescriptor, context: EvaluationContextImpl): Boolean {
|
||||
return compiledData.parameters.all { (p): Boolean ->
|
||||
val (name, jetType) = p
|
||||
val value = context.getFrameProxy()?.getStackFrame()?.findLocalVariable(name, failIfNotFound = false)
|
||||
val value = context.findLocalVariable(name, asmType = null, checkType = false, failIfNotFound = false)
|
||||
if (value == null) return@all false
|
||||
|
||||
val thisDescriptor = value.asmType.getClassDescriptor()
|
||||
|
||||
@@ -61,6 +61,11 @@ import org.jetbrains.jet.plugin.debugger.evaluate.KotlinEvaluateExpressionCache.
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext
|
||||
import com.sun.jdi.StackFrame
|
||||
import com.sun.jdi.VirtualMachine
|
||||
import org.jetbrains.jet.codegen.AsmUtil
|
||||
import com.sun.jdi.InvalidStackFrameException
|
||||
|
||||
private val RECEIVER_NAME = "\$receiver"
|
||||
private val THIS_NAME = "this"
|
||||
|
||||
object KotlinEvaluationBuilder: EvaluatorBuilder {
|
||||
override fun build(codeFragment: PsiElement, position: SourcePosition?): ExpressionEvaluator {
|
||||
@@ -94,14 +99,13 @@ class KotlinEvaluator(val codeFragment: JetCodeFragment,
|
||||
isCompiledDataFromCache = false
|
||||
extractAndCompile(fragment, position)
|
||||
}
|
||||
val args = context.getArgumentsByNames(compiledData.parameters.getParameterNames())
|
||||
val result = runEval4j(context, compiledData, args)
|
||||
val result = runEval4j(context, compiledData)
|
||||
|
||||
val virtualMachine = context.getDebugProcess().getVirtualMachineProxy().getVirtualMachine()
|
||||
|
||||
// If bytecode was taken from cache and exception was thrown - recompile bytecode and run eval4j again
|
||||
if (isCompiledDataFromCache && result is ExceptionThrown && result.kind == ExceptionThrown.ExceptionKind.BROKEN_CODE) {
|
||||
return runEval4j(context, extractAndCompile(codeFragment, sourcePosition), args).toJdiValue(virtualMachine)
|
||||
return runEval4j(context, extractAndCompile(codeFragment, sourcePosition)).toJdiValue(virtualMachine)
|
||||
}
|
||||
|
||||
return result.toJdiValue(virtualMachine)
|
||||
@@ -140,17 +144,14 @@ class KotlinEvaluator(val codeFragment: JetCodeFragment,
|
||||
return CompiledDataDescriptor(outputFiles.first().asByteArray(), sourcePosition, funName, extractedFunction.getParametersForDebugger())
|
||||
}
|
||||
|
||||
private fun runEval4j(
|
||||
context: EvaluationContextImpl,
|
||||
compiledData: CompiledDataDescriptor,
|
||||
args: List<Value>
|
||||
): InterpreterResult {
|
||||
private fun runEval4j(context: EvaluationContextImpl, compiledData: CompiledDataDescriptor): InterpreterResult {
|
||||
val virtualMachine = context.getDebugProcess().getVirtualMachineProxy().getVirtualMachine()
|
||||
|
||||
var resultValue: InterpreterResult? = null
|
||||
ClassReader(compiledData.bytecodes).accept(object : ClassVisitor(ASM5) {
|
||||
override fun visitMethod(access: Int, name: String, desc: String, signature: String?, exceptions: Array<out String>?): MethodVisitor? {
|
||||
if (name == compiledData.funName) {
|
||||
val args = context.getArgumentsForEval4j(compiledData.parameters.getParameterNames(), Type.getArgumentTypes(desc))
|
||||
return object : MethodNode(Opcodes.ASM5, access, name, desc, signature, exceptions) {
|
||||
override fun visitEnd() {
|
||||
resultValue = interpreterLoop(
|
||||
@@ -182,10 +183,6 @@ class KotlinEvaluator(val codeFragment: JetCodeFragment,
|
||||
return jdiValue.asJdiValue(vm, jdiValue.asmType)
|
||||
}
|
||||
|
||||
private fun SuspendContext.getInvokePolicy(): Int {
|
||||
return if (getSuspendPolicy() == EventRequest.SUSPEND_EVENT_THREAD) ObjectReference.INVOKE_SINGLE_THREADED else 0
|
||||
}
|
||||
|
||||
private fun JetNamedFunction.getParametersForDebugger(): ParametersDescriptor {
|
||||
return ApplicationManager.getApplication()?.runReadAction(Computable {
|
||||
val parameters = ParametersDescriptor()
|
||||
@@ -194,7 +191,7 @@ class KotlinEvaluator(val codeFragment: JetCodeFragment,
|
||||
if (descriptor != null) {
|
||||
val receiver = descriptor.getReceiverParameter()
|
||||
if (receiver != null) {
|
||||
parameters.add("this", receiver.getType())
|
||||
parameters.add(THIS_NAME, receiver.getType())
|
||||
}
|
||||
|
||||
descriptor.getValueParameters().forEach {
|
||||
@@ -206,12 +203,8 @@ class KotlinEvaluator(val codeFragment: JetCodeFragment,
|
||||
})!!
|
||||
}
|
||||
|
||||
private fun EvaluationContextImpl.getArgumentsByNames(parameterNames: List<String>): List<Value> {
|
||||
val frames = getFrameProxy()?.getStackFrame()
|
||||
if (frames != null) {
|
||||
return parameterNames.map { frames.findLocalVariable(it)!! }
|
||||
}
|
||||
return Collections.emptyList()
|
||||
private fun EvaluationContextImpl.getArgumentsForEval4j(parameterNames: List<String>, parameterTypes: Array<Type>): List<Value> {
|
||||
return parameterNames.zip(parameterTypes).map { this.findLocalVariable(it.first, it.second, checkType = false, failIfNotFound = true)!! }
|
||||
}
|
||||
|
||||
private fun createClassFileFactory(codeFragment: JetCodeFragment, extractedFunction: JetNamedFunction): ClassFileFactory {
|
||||
@@ -301,22 +294,87 @@ fun checkForSyntacticErrors(file: JetFile) {
|
||||
}
|
||||
}
|
||||
|
||||
fun StackFrame.findLocalVariable(name: String, failIfNotFound: Boolean = true): Value? {
|
||||
return try {
|
||||
private fun SuspendContext.getInvokePolicy(): Int {
|
||||
return if (getSuspendPolicy() == EventRequest.SUSPEND_EVENT_THREAD) ObjectReference.INVOKE_SINGLE_THREADED else 0
|
||||
}
|
||||
|
||||
fun EvaluationContextImpl.findLocalVariable(name: String, asmType: Type?, checkType: Boolean, failIfNotFound: Boolean): Value? {
|
||||
val frame = getFrameProxy()?.getStackFrame()
|
||||
if (frame == null) return null
|
||||
try {
|
||||
when (name) {
|
||||
"this" -> thisObject().asValue()
|
||||
else -> getValue(visibleVariableByName(name)).asValue()
|
||||
THIS_NAME -> {
|
||||
val thisObject = frame.thisObject()
|
||||
if (thisObject != null) {
|
||||
val eval4jValue = thisObject.asValue()
|
||||
if (isValueOfCorrectType(eval4jValue, asmType, true)) return eval4jValue
|
||||
}
|
||||
|
||||
val receiver = findLocalVariable(RECEIVER_NAME, asmType, checkType = true, failIfNotFound = false)
|
||||
if (receiver != null) return receiver
|
||||
|
||||
val this0 = findLocalVariable(AsmUtil.CAPTURED_THIS_FIELD, asmType, checkType = true, failIfNotFound = false)
|
||||
if (this0 != null) return this0
|
||||
}
|
||||
else -> {
|
||||
val localVariable = frame.visibleVariableByName(name)
|
||||
if (localVariable != null) {
|
||||
val eval4jValue = frame.getValue(localVariable).asValue()
|
||||
if (isValueOfCorrectType(eval4jValue, asmType, checkType)) return eval4jValue
|
||||
}
|
||||
|
||||
val eval4j = JDIEval(frame.virtualMachine()!!,
|
||||
getClassLoader()!!,
|
||||
getSuspendContext().getThread()?.getThreadReference()!!,
|
||||
getSuspendContext().getInvokePolicy())
|
||||
|
||||
fun JDIEval.getField(owner: Value, name: String, asmType: Type?): Value? {
|
||||
val fieldDescription = FieldDescription(owner.asmType.getInternalName(), name, asmType?.getDescriptor() ?: "", isStatic = false)
|
||||
try {
|
||||
val fieldValue = getField(owner, fieldDescription)
|
||||
if (isValueOfCorrectType(fieldValue, asmType, checkType)) return fieldValue
|
||||
return null
|
||||
}
|
||||
catch (e: Exception) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
fun findCapturedVal(name: String): Value? {
|
||||
var result: Value? = null
|
||||
var thisObj: Value? = frame.thisObject().asValue()
|
||||
|
||||
while (result == null && thisObj != null) {
|
||||
result = eval4j.getField(thisObj!!, name, asmType)
|
||||
if (result == null) {
|
||||
thisObj = eval4j.getField(thisObj!!, AsmUtil.CAPTURED_THIS_FIELD, null)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
val capturedValName = getCapturedFieldName(name)
|
||||
val capturedVal = findCapturedVal(capturedValName)
|
||||
if (capturedVal != null) return capturedVal
|
||||
}
|
||||
}
|
||||
|
||||
return if (!failIfNotFound)
|
||||
null
|
||||
else
|
||||
throw EvaluateExceptionUtil.createEvaluateException("Cannot find local variable: name = $name${if (checkType) ", type = " + asmType.toString() else ""}")
|
||||
}
|
||||
catch(e: Exception) {
|
||||
if (failIfNotFound) {
|
||||
throw EvaluateExceptionUtil.createEvaluateException(
|
||||
"Cannot find local variable: name = ${name}. Note that captured variables are unsupported yet.")
|
||||
}
|
||||
else {
|
||||
return null
|
||||
}
|
||||
catch(e: InvalidStackFrameException) {
|
||||
throw EvaluateExceptionUtil.createEvaluateException("Local variable $name is unavailable in current frame")
|
||||
}
|
||||
}
|
||||
|
||||
private fun getCapturedFieldName(name: String) = when (name) {
|
||||
RECEIVER_NAME -> AsmUtil.CAPTURED_RECEIVER_FIELD
|
||||
THIS_NAME -> AsmUtil.CAPTURED_THIS_FIELD
|
||||
AsmUtil.CAPTURED_RECEIVER_FIELD -> name
|
||||
AsmUtil.CAPTURED_THIS_FIELD -> name
|
||||
else -> "$$name"
|
||||
}
|
||||
|
||||
private fun isValueOfCorrectType(value: Value, asmType: Type?, shouldCheckType: Boolean) = !shouldCheckType || asmType == null || value.asmType == asmType
|
||||
@@ -2,6 +2,7 @@ LineBreakpoint created at frameClassObject.kt:15
|
||||
!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !APP_PATH!\classes;!KOTLIN_RUNTIME!;!RT_JAR! frameClassObject.FrameClassObjectPackage
|
||||
Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||
frameClassObject.kt:14
|
||||
Compile bytecode for prop
|
||||
package frameClassObject
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
@@ -26,6 +27,9 @@ fun foo(f: () -> Unit) {
|
||||
}
|
||||
|
||||
// PRINT_FRAME
|
||||
|
||||
// EXPRESSION: prop
|
||||
// RESULT: 1: I
|
||||
frame = invoke():15, A$test$1 {frameClassObject}
|
||||
this = this = {frameClassObject.A$test$1@uniqueID}kotlin.Function0<kotlin.Unit>
|
||||
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||
|
||||
@@ -2,6 +2,11 @@ LineBreakpoint created at frameExtFunExtFun.kt:22
|
||||
!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !APP_PATH!\classes;!KOTLIN_RUNTIME!;!RT_JAR! frameExtFunExtFun.FrameExtFunExtFunPackage
|
||||
Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||
frameExtFunExtFun.kt:21
|
||||
Compile bytecode for valFoo
|
||||
Compile bytecode for valTest
|
||||
Compile bytecode for aProp
|
||||
Compile bytecode for outerProp
|
||||
Compile bytecode for bProp
|
||||
package frameExtFunExtFun
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
@@ -48,6 +53,21 @@ fun lambda(f: () -> Unit) {
|
||||
}
|
||||
|
||||
// PRINT_FRAME
|
||||
|
||||
// EXPRESSION: valFoo
|
||||
// RESULT: 1: I
|
||||
|
||||
// EXPRESSION: valTest
|
||||
// RESULT: 1: I
|
||||
|
||||
// EXPRESSION: aProp
|
||||
// RESULT: 1: I
|
||||
|
||||
// EXPRESSION: outerProp
|
||||
// RESULT: 1: I
|
||||
|
||||
// EXPRESSION: bProp
|
||||
// RESULT: 1: I
|
||||
frame = invoke():22, Outer$foo$LocalClass$test$1 {frameExtFunExtFun}
|
||||
this = this = {frameExtFunExtFun.Outer$foo$LocalClass$test$1@uniqueID}kotlin.Function0<kotlin.Unit>
|
||||
field = this$0: frameExtFunExtFun.Outer$foo$LocalClass = {frameExtFunExtFun.Outer$foo$LocalClass@uniqueID}
|
||||
|
||||
@@ -2,6 +2,7 @@ LineBreakpoint created at frameExtensionFun.kt:13
|
||||
!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !APP_PATH!\classes;!KOTLIN_RUNTIME!;!RT_JAR! frameExtensionFun.FrameExtensionFunPackage
|
||||
Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||
frameExtensionFun.kt:12
|
||||
Compile bytecode for prop
|
||||
package frameExtensionFun
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
@@ -18,6 +19,9 @@ fun A.foo() {
|
||||
}
|
||||
|
||||
// PRINT_FRAME
|
||||
|
||||
// EXPRESSION: prop
|
||||
// RESULT: 1: I
|
||||
frame = foo():13, FrameExtensionFunPackage-@packagePartHASH {frameExtensionFun}
|
||||
static = static = frameExtensionFun.FrameExtensionFunPackage-@packagePartHASH
|
||||
local = $receiver: frameExtensionFun.A = {frameExtensionFun.A@uniqueID}
|
||||
|
||||
@@ -2,6 +2,8 @@ LineBreakpoint created at frameInnerClass.kt:15
|
||||
!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !APP_PATH!\classes;!KOTLIN_RUNTIME!;!RT_JAR! frameInnerClass.FrameInnerClassPackage
|
||||
Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||
frameInnerClass.kt:14
|
||||
Compile bytecode for prop1
|
||||
Compile bytecode for prop2
|
||||
package frameInnerClass
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
@@ -22,6 +24,12 @@ class A {
|
||||
}
|
||||
|
||||
// PRINT_FRAME
|
||||
|
||||
// EXPRESSION: prop1
|
||||
// RESULT: 1: I
|
||||
|
||||
// EXPRESSION: prop2
|
||||
// RESULT: 1: I
|
||||
frame = test():15, A$Inner {frameInnerClass}
|
||||
this = this = {frameInnerClass.A$Inner@uniqueID}
|
||||
field = prop2: int = 1
|
||||
|
||||
@@ -2,6 +2,9 @@ LineBreakpoint created at frameInnerLambda.kt:9
|
||||
!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !APP_PATH!\classes;!KOTLIN_RUNTIME!;!RT_JAR! frameInnerLambda.FrameInnerLambdaPackage
|
||||
Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||
frameInnerLambda.kt:8
|
||||
Compile bytecode for val1
|
||||
Compile bytecode for val2
|
||||
Compile bytecode for val1 + val2
|
||||
package frameInnerLambda
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
@@ -20,6 +23,15 @@ fun foo(f: () -> Unit) {
|
||||
}
|
||||
|
||||
// PRINT_FRAME
|
||||
|
||||
// EXPRESSION: val1
|
||||
// RESULT: 1: I
|
||||
|
||||
// EXPRESSION: val2
|
||||
// RESULT: 1: I
|
||||
|
||||
// EXPRESSION: val1 + val2
|
||||
// RESULT: 2: I
|
||||
frame = invoke():9, FrameInnerLambdaPackage$main$1$1 {frameInnerLambda}
|
||||
this = this = {frameInnerLambda.FrameInnerLambdaPackage$main$1$1@uniqueID}kotlin.Function0<kotlin.Unit>
|
||||
field = this$0: frameInnerLambda.FrameInnerLambdaPackage$main$1 = {frameInnerLambda.FrameInnerLambdaPackage$main$1@uniqueID}kotlin.Function0<kotlin.Unit>
|
||||
|
||||
@@ -2,6 +2,7 @@ LineBreakpoint created at frameLambda.kt:7
|
||||
!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !APP_PATH!\classes;!KOTLIN_RUNTIME!;!RT_JAR! frameLambda.FrameLambdaPackage
|
||||
Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||
frameLambda.kt:6
|
||||
Compile bytecode for val1
|
||||
package frameLambda
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
@@ -17,6 +18,9 @@ fun foo(f: () -> Unit) {
|
||||
}
|
||||
|
||||
// PRINT_FRAME
|
||||
|
||||
// EXPRESSION: val1
|
||||
// RESULT: 1: I
|
||||
frame = invoke():7, FrameLambdaPackage$main$1 {frameLambda}
|
||||
this = this = {frameLambda.FrameLambdaPackage$main$1@uniqueID}kotlin.Function0<kotlin.Unit>
|
||||
field = $val1: int = 1
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
LineBreakpoint created at frameLambdaNotUsed.kt:7
|
||||
!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !APP_PATH!\classes;!KOTLIN_RUNTIME!;!RT_JAR! frameLambdaNotUsed.FrameLambdaNotUsedPackage
|
||||
Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||
frameLambdaNotUsed.kt:6
|
||||
Compile bytecode for val1
|
||||
package frameLambdaNotUsed
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val val1 = 1
|
||||
foo {
|
||||
//Breakpoint!
|
||||
val a = 1
|
||||
}
|
||||
}
|
||||
|
||||
fun foo(f: () -> Unit) {
|
||||
f()
|
||||
}
|
||||
|
||||
// PRINT_FRAME
|
||||
|
||||
// EXPRESSION: val1
|
||||
// RESULT: Cannot find local variable: name = val1
|
||||
frame = invoke():7, FrameLambdaNotUsedPackage$main$1 {frameLambdaNotUsed}
|
||||
this = this = {frameLambdaNotUsed.FrameLambdaNotUsedPackage$main$1@uniqueID}kotlin.Function0<kotlin.Unit>
|
||||
local = a: int = 0
|
||||
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||
|
||||
Process finished with exit code 0
|
||||
@@ -2,6 +2,7 @@ LineBreakpoint created at frameObject.kt:6
|
||||
!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !APP_PATH!\classes;!KOTLIN_RUNTIME!;!RT_JAR! frameObject.FrameObjectPackage
|
||||
Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||
frameObject.kt:5
|
||||
Compile bytecode for O.obProp
|
||||
package frameObject
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
@@ -20,6 +21,9 @@ fun foo(f: () -> Unit) {
|
||||
}
|
||||
|
||||
// PRINT_FRAME
|
||||
|
||||
// EXPRESSION: O.obProp
|
||||
// RESULT: 1: I
|
||||
frame = invoke():6, FrameObjectPackage$main$1 {frameObject}
|
||||
this = this = {frameObject.FrameObjectPackage$main$1@uniqueID}kotlin.Function0<kotlin.Unit>
|
||||
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||
|
||||
@@ -1,23 +1,48 @@
|
||||
LineBreakpoint created at frameSimple.kt:8
|
||||
LineBreakpoint created at frameSimple.kt:9
|
||||
!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !APP_PATH!\classes;!KOTLIN_RUNTIME!;!RT_JAR! frameSimple.FrameSimplePackage
|
||||
Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||
frameSimple.kt:7
|
||||
frameSimple.kt:8
|
||||
Compile bytecode for val1
|
||||
Compile bytecode for val2
|
||||
Compile bytecode for topVal1
|
||||
Compile bytecode for val1 + topVal1
|
||||
package frameSimple
|
||||
|
||||
val topVal1 = 1
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val val1 = 1
|
||||
val val2 = "str"
|
||||
//Breakpoint!
|
||||
val1 + topVal1
|
||||
}
|
||||
|
||||
// PRINT_FRAME
|
||||
frame = main():8, FrameSimplePackage-@packagePartHASH {frameSimple}
|
||||
|
||||
// EXPRESSION: val1
|
||||
// RESULT: 1: I
|
||||
|
||||
// EXPRESSION: val2
|
||||
// RESULT: "str": Ljava/lang/String;
|
||||
|
||||
// EXPRESSION: topVal1
|
||||
// RESULT: 1: I
|
||||
|
||||
// EXPRESSION: val1 + topVal1
|
||||
// RESULT: 2: I
|
||||
frame = main():9, FrameSimplePackage-@packagePartHASH {frameSimple}
|
||||
static = static = frameSimple.FrameSimplePackage-@packagePartHASH
|
||||
field = topVal1: int = 1
|
||||
local = args: java.lang.String[] = {java.lang.String[0]@uniqueID}
|
||||
local = val1: int = 1
|
||||
local = val2: java.lang.String = {@uniqueID}str
|
||||
field = value: char[] = {char[3]@uniqueID}
|
||||
unknown = [0] = 's' 115
|
||||
unknown = [1] = 't' 116
|
||||
unknown = [2] = 'r' 114
|
||||
field = offset: int = 0
|
||||
field = count: int = 3
|
||||
field = hash: int = 0
|
||||
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||
|
||||
Process finished with exit code 0
|
||||
|
||||
@@ -2,6 +2,10 @@ LineBreakpoint created at frameThis0.kt:15
|
||||
!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !APP_PATH!\classes;!KOTLIN_RUNTIME!;!RT_JAR! frameThis0.FrameThis0Package
|
||||
Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||
frameThis0.kt:14
|
||||
Compile bytecode for val1
|
||||
Compile bytecode for val2
|
||||
Compile bytecode for prop1
|
||||
Compile bytecode for prop1 + val1 + val2
|
||||
package frameThis0
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
@@ -26,6 +30,18 @@ fun foo(f: () -> Unit) {
|
||||
}
|
||||
|
||||
// PRINT_FRAME
|
||||
|
||||
// EXPRESSION: val1
|
||||
// RESULT: 1: I
|
||||
|
||||
// EXPRESSION: val2
|
||||
// RESULT: 1: I
|
||||
|
||||
// EXPRESSION: prop1
|
||||
// RESULT: 1: I
|
||||
|
||||
// EXPRESSION: prop1 + val1 + val2
|
||||
// RESULT: 3: I
|
||||
frame = invoke():15, A$test$1 {frameThis0}
|
||||
this = this = {frameThis0.A$test$1@uniqueID}kotlin.Function0<kotlin.Unit>
|
||||
field = this$0: frameThis0.A = {frameThis0.A@uniqueID}
|
||||
|
||||
@@ -2,6 +2,11 @@ LineBreakpoint created at frameThis0Ext.kt:14
|
||||
!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !APP_PATH!\classes;!KOTLIN_RUNTIME!;!RT_JAR! frameThis0Ext.FrameThis0ExtPackage
|
||||
Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||
frameThis0Ext.kt:13
|
||||
Compile bytecode for val1
|
||||
Compile bytecode for prop1
|
||||
Compile bytecode for prop2
|
||||
Compile bytecode for prop1 + val1
|
||||
Compile bytecode for prop2 + val1
|
||||
package frameThis0Ext
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
@@ -33,6 +38,21 @@ fun foo(f: () -> Unit) {
|
||||
}
|
||||
|
||||
// PRINT_FRAME
|
||||
|
||||
// EXPRESSION: val1
|
||||
// RESULT: 1: I
|
||||
|
||||
// EXPRESSION: prop1
|
||||
// RESULT: 1: I
|
||||
|
||||
// EXPRESSION: prop2
|
||||
// RESULT: 1: I
|
||||
|
||||
// EXPRESSION: prop1 + val1
|
||||
// RESULT: 2: I
|
||||
|
||||
// EXPRESSION: prop2 + val1
|
||||
// RESULT: 2: I
|
||||
frame = invoke():14, A$testExt$1 {frameThis0Ext}
|
||||
this = this = {frameThis0Ext.A$testExt$1@uniqueID}kotlin.Function0<kotlin.Unit>
|
||||
field = this$0: frameThis0Ext.A = {frameThis0Ext.A@uniqueID}
|
||||
|
||||
@@ -2,6 +2,10 @@ LineBreakpoint created at frameThis0This0.kt:16
|
||||
!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !APP_PATH!\classes;!KOTLIN_RUNTIME!;!RT_JAR! frameThis0This0.FrameThis0This0Package
|
||||
Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||
frameThis0This0.kt:15
|
||||
Compile bytecode for val1
|
||||
Compile bytecode for val2
|
||||
Compile bytecode for prop1
|
||||
Compile bytecode for prop1 + val1 + val2
|
||||
package frameThis0This0
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
@@ -28,6 +32,18 @@ fun foo(f: () -> Unit) {
|
||||
}
|
||||
|
||||
// PRINT_FRAME
|
||||
|
||||
// EXPRESSION: val1
|
||||
// RESULT: 1: I
|
||||
|
||||
// EXPRESSION: val2
|
||||
// RESULT: 1: I
|
||||
|
||||
// EXPRESSION: prop1
|
||||
// RESULT: 1: I
|
||||
|
||||
// EXPRESSION: prop1 + val1 + val2
|
||||
// RESULT: 3: I
|
||||
frame = invoke():16, A$test$1$1 {frameThis0This0}
|
||||
this = this = {frameThis0This0.A$test$1$1@uniqueID}kotlin.Function0<kotlin.Unit>
|
||||
field = this$0: frameThis0This0.A$test$1 = {frameThis0This0.A$test$1@uniqueID}kotlin.Function0<kotlin.Unit>
|
||||
|
||||
@@ -21,4 +21,7 @@ fun foo(f: () -> Unit) {
|
||||
f()
|
||||
}
|
||||
|
||||
// PRINT_FRAME
|
||||
// PRINT_FRAME
|
||||
|
||||
// EXPRESSION: prop
|
||||
// RESULT: 1: I
|
||||
@@ -43,4 +43,19 @@ fun lambda(f: () -> Unit) {
|
||||
f()
|
||||
}
|
||||
|
||||
// PRINT_FRAME
|
||||
// PRINT_FRAME
|
||||
|
||||
// EXPRESSION: valFoo
|
||||
// RESULT: 1: I
|
||||
|
||||
// EXPRESSION: valTest
|
||||
// RESULT: 1: I
|
||||
|
||||
// EXPRESSION: aProp
|
||||
// RESULT: 1: I
|
||||
|
||||
// EXPRESSION: outerProp
|
||||
// RESULT: 1: I
|
||||
|
||||
// EXPRESSION: bProp
|
||||
// RESULT: 1: I
|
||||
@@ -13,4 +13,7 @@ fun A.foo() {
|
||||
prop
|
||||
}
|
||||
|
||||
// PRINT_FRAME
|
||||
// PRINT_FRAME
|
||||
|
||||
// EXPRESSION: prop
|
||||
// RESULT: 1: I
|
||||
@@ -17,4 +17,10 @@ class A {
|
||||
}
|
||||
}
|
||||
|
||||
// PRINT_FRAME
|
||||
// PRINT_FRAME
|
||||
|
||||
// EXPRESSION: prop1
|
||||
// RESULT: 1: I
|
||||
|
||||
// EXPRESSION: prop2
|
||||
// RESULT: 1: I
|
||||
@@ -15,4 +15,13 @@ fun foo(f: () -> Unit) {
|
||||
f()
|
||||
}
|
||||
|
||||
// PRINT_FRAME
|
||||
// PRINT_FRAME
|
||||
|
||||
// EXPRESSION: val1
|
||||
// RESULT: 1: I
|
||||
|
||||
// EXPRESSION: val2
|
||||
// RESULT: 1: I
|
||||
|
||||
// EXPRESSION: val1 + val2
|
||||
// RESULT: 2: I
|
||||
@@ -12,4 +12,7 @@ fun foo(f: () -> Unit) {
|
||||
f()
|
||||
}
|
||||
|
||||
// PRINT_FRAME
|
||||
// PRINT_FRAME
|
||||
|
||||
// EXPRESSION: val1
|
||||
// RESULT: 1: I
|
||||
@@ -0,0 +1,18 @@
|
||||
package frameLambdaNotUsed
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val val1 = 1
|
||||
foo {
|
||||
//Breakpoint!
|
||||
val a = 1
|
||||
}
|
||||
}
|
||||
|
||||
fun foo(f: () -> Unit) {
|
||||
f()
|
||||
}
|
||||
|
||||
// PRINT_FRAME
|
||||
|
||||
// EXPRESSION: val1
|
||||
// RESULT: Cannot find local variable: name = val1
|
||||
@@ -15,4 +15,7 @@ fun foo(f: () -> Unit) {
|
||||
f()
|
||||
}
|
||||
|
||||
// PRINT_FRAME
|
||||
// PRINT_FRAME
|
||||
|
||||
// EXPRESSION: O.obProp
|
||||
// RESULT: 1: I
|
||||
@@ -4,8 +4,21 @@ val topVal1 = 1
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val val1 = 1
|
||||
val val2 = "str"
|
||||
//Breakpoint!
|
||||
val1 + topVal1
|
||||
}
|
||||
|
||||
// PRINT_FRAME
|
||||
// PRINT_FRAME
|
||||
|
||||
// EXPRESSION: val1
|
||||
// RESULT: 1: I
|
||||
|
||||
// EXPRESSION: val2
|
||||
// RESULT: "str": Ljava/lang/String;
|
||||
|
||||
// EXPRESSION: topVal1
|
||||
// RESULT: 1: I
|
||||
|
||||
// EXPRESSION: val1 + topVal1
|
||||
// RESULT: 2: I
|
||||
@@ -21,4 +21,16 @@ fun foo(f: () -> Unit) {
|
||||
f()
|
||||
}
|
||||
|
||||
// PRINT_FRAME
|
||||
// PRINT_FRAME
|
||||
|
||||
// EXPRESSION: val1
|
||||
// RESULT: 1: I
|
||||
|
||||
// EXPRESSION: val2
|
||||
// RESULT: 1: I
|
||||
|
||||
// EXPRESSION: prop1
|
||||
// RESULT: 1: I
|
||||
|
||||
// EXPRESSION: prop1 + val1 + val2
|
||||
// RESULT: 3: I
|
||||
@@ -28,4 +28,19 @@ fun foo(f: () -> Unit) {
|
||||
f()
|
||||
}
|
||||
|
||||
// PRINT_FRAME
|
||||
// PRINT_FRAME
|
||||
|
||||
// EXPRESSION: val1
|
||||
// RESULT: 1: I
|
||||
|
||||
// EXPRESSION: prop1
|
||||
// RESULT: 1: I
|
||||
|
||||
// EXPRESSION: prop2
|
||||
// RESULT: 1: I
|
||||
|
||||
// EXPRESSION: prop1 + val1
|
||||
// RESULT: 2: I
|
||||
|
||||
// EXPRESSION: prop2 + val1
|
||||
// RESULT: 2: I
|
||||
@@ -23,4 +23,16 @@ fun foo(f: () -> Unit) {
|
||||
f()
|
||||
}
|
||||
|
||||
// PRINT_FRAME
|
||||
// PRINT_FRAME
|
||||
|
||||
// EXPRESSION: val1
|
||||
// RESULT: 1: I
|
||||
|
||||
// EXPRESSION: val2
|
||||
// RESULT: 1: I
|
||||
|
||||
// EXPRESSION: prop1
|
||||
// RESULT: 1: I
|
||||
|
||||
// EXPRESSION: prop1 + val1 + val2
|
||||
// RESULT: 3: I
|
||||
+5
@@ -199,6 +199,11 @@ public class KotlinEvaluateExpressionTestGenerated extends AbstractKotlinEvaluat
|
||||
doSingleBreakpointTest("idea/testData/debugger/tinyApp/src/evaluate/frame/frameLambda.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("frameLambdaNotUsed.kt")
|
||||
public void testFrameLambdaNotUsed() throws Exception {
|
||||
doSingleBreakpointTest("idea/testData/debugger/tinyApp/src/evaluate/frame/frameLambdaNotUsed.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("frameObject.kt")
|
||||
public void testFrameObject() throws Exception {
|
||||
doSingleBreakpointTest("idea/testData/debugger/tinyApp/src/evaluate/frame/frameObject.kt");
|
||||
|
||||
Reference in New Issue
Block a user