Debugger: Support synchronized blocks and functions in evaluator (KT-11888)
This commit is contained in:
+7
@@ -20,6 +20,7 @@ import com.sun.jdi.ArrayReference
|
|||||||
import com.sun.jdi.ArrayType
|
import com.sun.jdi.ArrayType
|
||||||
import com.sun.jdi.ClassLoaderReference
|
import com.sun.jdi.ClassLoaderReference
|
||||||
import com.sun.jdi.Value
|
import com.sun.jdi.Value
|
||||||
|
import jdk.internal.org.objectweb.asm.Opcodes
|
||||||
import org.jetbrains.kotlin.idea.debugger.evaluate.ExecutionContext
|
import org.jetbrains.kotlin.idea.debugger.evaluate.ExecutionContext
|
||||||
import org.jetbrains.org.objectweb.asm.ClassReader
|
import org.jetbrains.org.objectweb.asm.ClassReader
|
||||||
import org.jetbrains.org.objectweb.asm.Label
|
import org.jetbrains.org.objectweb.asm.Label
|
||||||
@@ -63,6 +64,7 @@ interface ClassLoadingAdapter {
|
|||||||
|
|
||||||
private fun analyzeClass(classToLoad: ClassToLoad, info: ClassInfoForEvaluator): ClassInfoForEvaluator {
|
private fun analyzeClass(classToLoad: ClassToLoad, info: ClassInfoForEvaluator): ClassInfoForEvaluator {
|
||||||
val classNode = ClassNode().apply { ClassReader(classToLoad.bytes).accept(this, 0) }
|
val classNode = ClassNode().apply { ClassReader(classToLoad.bytes).accept(this, 0) }
|
||||||
|
|
||||||
val methodToRun = classNode.methods.single { it.name == GENERATED_FUNCTION_NAME }
|
val methodToRun = classNode.methods.single { it.name == GENERATED_FUNCTION_NAME }
|
||||||
|
|
||||||
val visitedLabels = hashSetOf<Label>()
|
val visitedLabels = hashSetOf<Label>()
|
||||||
@@ -78,6 +80,11 @@ interface ClassLoadingAdapter {
|
|||||||
is TableSwitchInsnNode, is LookupSwitchInsnNode -> {
|
is TableSwitchInsnNode, is LookupSwitchInsnNode -> {
|
||||||
return info.copy(containsCodeUnsupportedInEval4J = true)
|
return info.copy(containsCodeUnsupportedInEval4J = true)
|
||||||
}
|
}
|
||||||
|
is InsnNode -> {
|
||||||
|
if (insn.opcode == Opcodes.MONITORENTER || insn.opcode == Opcodes.MONITOREXIT) {
|
||||||
|
return info.copy(containsCodeUnsupportedInEval4J = true)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val nextInsn = insn.next ?: return info
|
val nextInsn = insn.next ?: return info
|
||||||
|
|||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
package synchronizedBlock
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
//Breakpoint!
|
||||||
|
val a = 5
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXPRESSION: synchronized(Any()) { "foo" }
|
||||||
|
// RESULT: "foo": Ljava/lang/String;
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
class Foo {
|
||||||
|
@Synchronized
|
||||||
|
fun foo(): Int {
|
||||||
|
return 5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Foo().foo()
|
||||||
|
|
||||||
|
// RESULT: 5: I
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
LineBreakpoint created at synchronizedBlock.kt:5
|
||||||
|
Run Java
|
||||||
|
Connected to the target VM
|
||||||
|
synchronizedBlock.kt:5
|
||||||
|
Compile bytecode for synchronized(Any()) { "foo" }
|
||||||
|
Compile bytecode for class Foo {
|
||||||
|
@Synchronized
|
||||||
|
fun foo(): Int {
|
||||||
|
return 5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Foo().foo()
|
||||||
|
|
||||||
|
// RESULT: 5: I
|
||||||
|
Disconnected from the target VM
|
||||||
|
|
||||||
|
Process finished with exit code 0
|
||||||
Generated
+5
@@ -391,6 +391,11 @@ public class KotlinEvaluateExpressionTestGenerated extends AbstractKotlinEvaluat
|
|||||||
runTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/stdlib.kt");
|
runTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/stdlib.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("synchronizedBlock.kt")
|
||||||
|
public void testSynchronizedBlock() throws Exception {
|
||||||
|
runTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/synchronizedBlock.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("typeParameterRef.kt")
|
@TestMetadata("typeParameterRef.kt")
|
||||||
public void testTypeParameterRef() throws Exception {
|
public void testTypeParameterRef() throws Exception {
|
||||||
runTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/typeParameterRef.kt");
|
runTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/typeParameterRef.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user