@@ -11,6 +11,7 @@ import org.javacs.ktda.core.breakpoint.Breakpoint
1111import org.javacs.ktda.core.breakpoint.ExceptionBreakpoint
1212import org.javacs.kt.LOG
1313import org.javacs.ktda.util.ObservableList
14+ import org.javacs.ktda.util.SubscriptionBag
1415import org.javacs.ktda.classpath.findValidKtFilePath
1516import org.javacs.ktda.classpath.toJVMClassNames
1617import org.javacs.ktda.jdi.event.VMEventBus
@@ -38,6 +39,8 @@ class JDIDebuggee(
3839 override val stdin: OutputStream ?
3940 override val stdout: InputStream ?
4041 override val stderr: InputStream ?
42+
43+ private var breakpointSubscriptions = SubscriptionBag ()
4144
4245 init {
4346 eventBus = VMEventBus (vm)
@@ -66,6 +69,7 @@ class JDIDebuggee(
6669 }
6770
6871 private fun setAllBreakpoints (breakpoints : List <Breakpoint >) {
72+ breakpointSubscriptions.unsubscribe()
6973 vm.eventRequestManager().deleteAllBreakpoints()
7074 breakpoints.forEach { bp ->
7175 bp.position.let { setBreakpoint(
@@ -94,25 +98,27 @@ class JDIDebuggee(
9498 private fun setBreakpoint (filePath : String , lineNumber : Long ) {
9599 val eventRequestManager = vm.eventRequestManager()
96100 toJVMClassNames(filePath)
101+ .flatMap { listOf (it, " $it $*" ) } // For local types
97102 .forEach { className ->
98103 // 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
105106 .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+ })
108115
109- eventBus.subscribe(ClassPrepareEvent ::class ) {
110- setBreakpointAtType(it.jdiEvent.referenceType(), lineNumber)
111- }
116+ request.enable()
112117
113118 // Try setting breakpoint using loaded VM classes
114119
115120 vm.classesByName(className).forEach {
121+ LOG .info(" Setting breakpoint at known type {}" , it.name())
116122 setBreakpointAtType(it, lineNumber)
117123 }
118124 }
@@ -122,13 +128,11 @@ class JDIDebuggee(
122128 private fun setBreakpointAtType (refType : ReferenceType , lineNumber : Long ): Boolean {
123129 try {
124130 val location = refType
125- .locationsOfLine(lineNumber.toInt())
126- ?.firstOrNull() ? : return false
131+ .locationsOfLine(lineNumber.toInt())
132+ ?.firstOrNull() ? : return false
127133 val request = vm.eventRequestManager()
128- .createBreakpointRequest(location)
129- request?.let {
130- it.enable()
131- }
134+ .createBreakpointRequest(location)
135+ request?.enable()
132136 return request != null
133137 } catch (e: AbsentInformationException ) {
134138 return false
0 commit comments