@@ -11,6 +11,7 @@ import org.javacs.ktda.core.breakpoint.Breakpoint
11
11
import org.javacs.ktda.core.breakpoint.ExceptionBreakpoint
12
12
import org.javacs.kt.LOG
13
13
import org.javacs.ktda.util.ObservableList
14
+ import org.javacs.ktda.util.SubscriptionBag
14
15
import org.javacs.ktda.classpath.findValidKtFilePath
15
16
import org.javacs.ktda.classpath.toJVMClassNames
16
17
import org.javacs.ktda.jdi.event.VMEventBus
@@ -38,6 +39,8 @@ class JDIDebuggee(
38
39
override val stdin: OutputStream ?
39
40
override val stdout: InputStream ?
40
41
override val stderr: InputStream ?
42
+
43
+ private var breakpointSubscriptions = SubscriptionBag ()
41
44
42
45
init {
43
46
eventBus = VMEventBus (vm)
@@ -66,6 +69,7 @@ class JDIDebuggee(
66
69
}
67
70
68
71
private fun setAllBreakpoints (breakpoints : List <Breakpoint >) {
72
+ breakpointSubscriptions.unsubscribe()
69
73
vm.eventRequestManager().deleteAllBreakpoints()
70
74
breakpoints.forEach { bp ->
71
75
bp.position.let { setBreakpoint(
@@ -94,25 +98,27 @@ class JDIDebuggee(
94
98
private fun setBreakpoint (filePath : String , lineNumber : Long ) {
95
99
val eventRequestManager = vm.eventRequestManager()
96
100
toJVMClassNames(filePath)
101
+ .flatMap { listOf (it, " $it $*" ) } // For local types
97
102
.forEach { className ->
98
103
// Try setting breakpoint using a ClassPrepareRequest
99
-
100
- eventRequestManager
101
- .createClassPrepareRequest()
102
- .apply { addClassFilter(className) } // For global types
103
- .enable()
104
- eventRequestManager
104
+
105
+ val request = eventRequestManager
105
106
.createClassPrepareRequest()
106
- .apply { addClassFilter(className + " $*" ) } // For local types
107
- .enable()
107
+ .apply { addClassFilter(className) }
108
+
109
+ breakpointSubscriptions.add(eventBus.subscribe(ClassPrepareEvent ::class ) {
110
+ if (it.jdiEvent.request() == request) {
111
+ LOG .info(" Setting breakpoint at prepared type {}" , it.jdiEvent.referenceType().name())
112
+ setBreakpointAtType(it.jdiEvent.referenceType(), lineNumber)
113
+ }
114
+ })
108
115
109
- eventBus.subscribe(ClassPrepareEvent ::class ) {
110
- setBreakpointAtType(it.jdiEvent.referenceType(), lineNumber)
111
- }
116
+ request.enable()
112
117
113
118
// Try setting breakpoint using loaded VM classes
114
119
115
120
vm.classesByName(className).forEach {
121
+ LOG .info(" Setting breakpoint at known type {}" , it.name())
116
122
setBreakpointAtType(it, lineNumber)
117
123
}
118
124
}
@@ -122,13 +128,11 @@ class JDIDebuggee(
122
128
private fun setBreakpointAtType (refType : ReferenceType , lineNumber : Long ): Boolean {
123
129
try {
124
130
val location = refType
125
- .locationsOfLine(lineNumber.toInt())
126
- ?.firstOrNull() ? : return false
131
+ .locationsOfLine(lineNumber.toInt())
132
+ ?.firstOrNull() ? : return false
127
133
val request = vm.eventRequestManager()
128
- .createBreakpointRequest(location)
129
- request?.let {
130
- it.enable()
131
- }
134
+ .createBreakpointRequest(location)
135
+ request?.enable()
132
136
return request != null
133
137
} catch (e: AbsentInformationException ) {
134
138
return false
0 commit comments