@@ -3,17 +3,21 @@ package dev.robotcode.robotcode4ij.debugging
33import com.intellij.execution.ExecutionResult
44import com.intellij.execution.process.ProcessHandler
55import com.intellij.execution.ui.ExecutionConsole
6- import com.intellij.openapi.ui.MessageType
76import com.intellij.openapi.vfs.VirtualFile
87import com.intellij.xdebugger.XDebugProcess
98import com.intellij.xdebugger.XDebugSession
109import com.intellij.xdebugger.XSourcePosition
10+ import com.intellij.xdebugger.breakpoints.XBreakpoint
1111import com.intellij.xdebugger.breakpoints.XBreakpointHandler
1212import com.intellij.xdebugger.breakpoints.XLineBreakpoint
1313import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider
1414import com.intellij.xdebugger.frame.XSuspendContext
1515import com.jetbrains.rd.util.lifetime.Lifetime
1616import com.jetbrains.rd.util.threading.coroutines.adviseSuspend
17+ import dev.robotcode.robotcode4ij.debugging.breakpoints.RobotCodeExceptionBreakpointHandler
18+ import dev.robotcode.robotcode4ij.debugging.breakpoints.RobotCodeExceptionBreakpointProperties
19+ import dev.robotcode.robotcode4ij.debugging.breakpoints.RobotCodeLineBreakpointHandler
20+ import dev.robotcode.robotcode4ij.debugging.breakpoints.RobotCodeLineBreakpointProperties
1721import dev.robotcode.robotcode4ij.execution.RobotCodeRunProfileState
1822import kotlinx.coroutines.Dispatchers
1923import kotlinx.coroutines.future.await
@@ -22,7 +26,7 @@ import kotlinx.coroutines.sync.Mutex
2226import kotlinx.coroutines.sync.withLock
2327import org.eclipse.lsp4j.debug.ContinueArguments
2428import org.eclipse.lsp4j.debug.NextArguments
25- import org.eclipse.lsp4j.debug.OutputEventArgumentsCategory
29+ import org.eclipse.lsp4j.debug.PauseArguments
2630import org.eclipse.lsp4j.debug.SetBreakpointsArguments
2731import org.eclipse.lsp4j.debug.Source
2832import org.eclipse.lsp4j.debug.SourceBreakpoint
@@ -50,26 +54,11 @@ class RobotCodeDebugProcess(
5054 }
5155
5256 init {
57+ session.setPauseActionSupported(true )
5358 state.afterInitialize.adviseSuspend(Lifetime .Eternal , Dispatchers .IO ) {
5459 runBlocking { sendBreakpointRequest() }
5560 }
56- debugClient.onStopped.adviseSuspend(Lifetime .Eternal , Dispatchers .IO ) { args ->
57- handleOnStopped(args)
58- }
59- // debugClient.onOutput.adviseSuspend(Lifetime.Eternal, Dispatchers.IO) { args ->
60- //
61- // session.reportMessage(
62- // args.output, when (args.category) {
63- // OutputEventArgumentsCategory.STDOUT, OutputEventArgumentsCategory.CONSOLE -> MessageType.INFO
64- // OutputEventArgumentsCategory.STDERR -> MessageType.ERROR
65- // else -> MessageType.WARNING
66- // }
67- // )
68- // }
69-
70- // debugClient.onTerminated.adviseSuspend(Lifetime.Eternal, Dispatchers.IO) {
71- // session.stop()
72- // }
61+ debugClient.onStopped.adviseSuspend(Lifetime .Eternal , Dispatchers .IO , this ::handleOnStopped)
7362 }
7463
7564 private suspend fun createRobotCodeSuspendContext (threadId : Int ): RobotCodeSuspendContext {
@@ -89,8 +78,7 @@ class RobotCodeDebugProcess(
8978 if (bp is LineBreakpointInfo ) {
9079 if (! session.breakpointReached(
9180 bp.breakpoint, null , createRobotCodeSuspendContext(
92- args
93- .threadId
81+ args.threadId
9482 )
9583 )
9684 ) {
@@ -103,9 +91,17 @@ class RobotCodeDebugProcess(
10391 }
10492 }
10593
106- " exception" -> {
107- // TODO session.exceptionCaught()
108- session.positionReached(createRobotCodeSuspendContext(args.threadId))
94+ " exception" -> { // TODO session.exceptionCaught()
95+ if (! session.breakpointReached(
96+ exceptionBreakpoints.first().breakpoint,
97+ null ,
98+ createRobotCodeSuspendContext(args.threadId)
99+ )
100+ ) {
101+ debugServer.continue_(ContinueArguments ().apply {
102+ threadId = args.threadId
103+ }).await()
104+ }
109105 }
110106
111107 else -> {
@@ -116,18 +112,26 @@ class RobotCodeDebugProcess(
116112 }
117113
118114 private open class BreakPointInfo (val line : Int , var file : VirtualFile , var id : Int? = null )
119- private class LineBreakpointInfo (val breakpoint : XLineBreakpoint <RobotCodeBreakpointProperties >, id : Int? = null ) :
120- BreakPointInfo (breakpoint.line, breakpoint.sourcePosition!! .file, id)
115+ private class LineBreakpointInfo (
116+ val breakpoint : XLineBreakpoint <RobotCodeLineBreakpointProperties >, id : Int? = null
117+ ) : BreakPointInfo(breakpoint.line, breakpoint.sourcePosition!!.file, id)
118+
119+ private class ExceptionBreakpointInfo (
120+ val breakpoint : XBreakpoint <RobotCodeExceptionBreakpointProperties >, id : Int? = null
121+ )
121122
122123 private class OneTimeBreakpointInfo (val position : XSourcePosition , id : Int? = null ) :
123124 BreakPointInfo (position.line, position.file, id)
124125
126+ private val exceptionBreakpoints = mutableListOf<ExceptionBreakpointInfo >()
127+
125128 private val breakpoints = mutableListOf<BreakPointInfo >()
126129 private val breakpointMap = mutableMapOf<VirtualFile , MutableMap <Int , BreakPointInfo >>()
127130 private val breakpointsMapMutex = Mutex ()
128131
129132 private val editorsProvider = RobotCodeXDebuggerEditorsProvider ()
130- private val breakpointHandler = RobotCodeBreakpointHandler (this )
133+ private val breakpointHandler = RobotCodeLineBreakpointHandler (this )
134+ private val exceptionBreakpointHandler = RobotCodeExceptionBreakpointHandler (this )
131135
132136 override fun getEditorsProvider (): XDebuggerEditorsProvider {
133137 return editorsProvider
@@ -146,10 +150,26 @@ class RobotCodeDebugProcess(
146150 }
147151
148152 override fun getBreakpointHandlers (): Array <out XBreakpointHandler <* >? > {
149- return arrayOf(breakpointHandler)
153+ return arrayOf(breakpointHandler, exceptionBreakpointHandler)
154+ }
155+
156+ fun registerExceptionBreakpoint (breakpoint : XBreakpoint <RobotCodeExceptionBreakpointProperties >) {
157+ runBlocking {
158+ breakpointsMapMutex.withLock {
159+ exceptionBreakpoints.add(ExceptionBreakpointInfo (breakpoint))
160+ }
161+ }
150162 }
151163
152- fun registerBreakpoint (breakpoint : XLineBreakpoint <RobotCodeBreakpointProperties >) {
164+ fun unregisterExceptionBreakpoint (breakpoint : XBreakpoint <RobotCodeExceptionBreakpointProperties >) {
165+ runBlocking {
166+ breakpointsMapMutex.withLock {
167+ exceptionBreakpoints.removeIf { it.breakpoint == breakpoint }
168+ }
169+ }
170+ }
171+
172+ fun registerBreakpoint (breakpoint : XLineBreakpoint <RobotCodeLineBreakpointProperties >) {
153173 runBlocking {
154174 breakpointsMapMutex.withLock {
155175 breakpoint.sourcePosition?.let {
@@ -165,7 +185,7 @@ class RobotCodeDebugProcess(
165185 }
166186 }
167187
168- fun unregisterBreakpoint (breakpoint : XLineBreakpoint <RobotCodeBreakpointProperties >) {
188+ fun unregisterBreakpoint (breakpoint : XLineBreakpoint <RobotCodeLineBreakpointProperties >) {
169189 runBlocking {
170190 breakpointsMapMutex.withLock {
171191 breakpoint.sourcePosition?.let {
@@ -314,4 +334,10 @@ class RobotCodeDebugProcess(
314334 resume(context)
315335 }
316336 }
337+
338+ override fun startPausing () {
339+ runBlocking {
340+ debugServer.pause(PauseArguments ().apply { threadId = 0 }).await()
341+ }
342+ }
317343}
0 commit comments