@@ -3,17 +3,21 @@ package dev.robotcode.robotcode4ij.debugging
3
3
import com.intellij.execution.ExecutionResult
4
4
import com.intellij.execution.process.ProcessHandler
5
5
import com.intellij.execution.ui.ExecutionConsole
6
- import com.intellij.openapi.ui.MessageType
7
6
import com.intellij.openapi.vfs.VirtualFile
8
7
import com.intellij.xdebugger.XDebugProcess
9
8
import com.intellij.xdebugger.XDebugSession
10
9
import com.intellij.xdebugger.XSourcePosition
10
+ import com.intellij.xdebugger.breakpoints.XBreakpoint
11
11
import com.intellij.xdebugger.breakpoints.XBreakpointHandler
12
12
import com.intellij.xdebugger.breakpoints.XLineBreakpoint
13
13
import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider
14
14
import com.intellij.xdebugger.frame.XSuspendContext
15
15
import com.jetbrains.rd.util.lifetime.Lifetime
16
16
import 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
17
21
import dev.robotcode.robotcode4ij.execution.RobotCodeRunProfileState
18
22
import kotlinx.coroutines.Dispatchers
19
23
import kotlinx.coroutines.future.await
@@ -22,7 +26,7 @@ import kotlinx.coroutines.sync.Mutex
22
26
import kotlinx.coroutines.sync.withLock
23
27
import org.eclipse.lsp4j.debug.ContinueArguments
24
28
import org.eclipse.lsp4j.debug.NextArguments
25
- import org.eclipse.lsp4j.debug.OutputEventArgumentsCategory
29
+ import org.eclipse.lsp4j.debug.PauseArguments
26
30
import org.eclipse.lsp4j.debug.SetBreakpointsArguments
27
31
import org.eclipse.lsp4j.debug.Source
28
32
import org.eclipse.lsp4j.debug.SourceBreakpoint
@@ -50,26 +54,11 @@ class RobotCodeDebugProcess(
50
54
}
51
55
52
56
init {
57
+ session.setPauseActionSupported(true )
53
58
state.afterInitialize.adviseSuspend(Lifetime .Eternal , Dispatchers .IO ) {
54
59
runBlocking { sendBreakpointRequest() }
55
60
}
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)
73
62
}
74
63
75
64
private suspend fun createRobotCodeSuspendContext (threadId : Int ): RobotCodeSuspendContext {
@@ -89,8 +78,7 @@ class RobotCodeDebugProcess(
89
78
if (bp is LineBreakpointInfo ) {
90
79
if (! session.breakpointReached(
91
80
bp.breakpoint, null , createRobotCodeSuspendContext(
92
- args
93
- .threadId
81
+ args.threadId
94
82
)
95
83
)
96
84
) {
@@ -103,9 +91,17 @@ class RobotCodeDebugProcess(
103
91
}
104
92
}
105
93
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
+ }
109
105
}
110
106
111
107
else -> {
@@ -116,18 +112,26 @@ class RobotCodeDebugProcess(
116
112
}
117
113
118
114
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
+ )
121
122
122
123
private class OneTimeBreakpointInfo (val position : XSourcePosition , id : Int? = null ) :
123
124
BreakPointInfo (position.line, position.file, id)
124
125
126
+ private val exceptionBreakpoints = mutableListOf<ExceptionBreakpointInfo >()
127
+
125
128
private val breakpoints = mutableListOf<BreakPointInfo >()
126
129
private val breakpointMap = mutableMapOf<VirtualFile , MutableMap <Int , BreakPointInfo >>()
127
130
private val breakpointsMapMutex = Mutex ()
128
131
129
132
private val editorsProvider = RobotCodeXDebuggerEditorsProvider ()
130
- private val breakpointHandler = RobotCodeBreakpointHandler (this )
133
+ private val breakpointHandler = RobotCodeLineBreakpointHandler (this )
134
+ private val exceptionBreakpointHandler = RobotCodeExceptionBreakpointHandler (this )
131
135
132
136
override fun getEditorsProvider (): XDebuggerEditorsProvider {
133
137
return editorsProvider
@@ -146,10 +150,26 @@ class RobotCodeDebugProcess(
146
150
}
147
151
148
152
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
+ }
150
162
}
151
163
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 >) {
153
173
runBlocking {
154
174
breakpointsMapMutex.withLock {
155
175
breakpoint.sourcePosition?.let {
@@ -165,7 +185,7 @@ class RobotCodeDebugProcess(
165
185
}
166
186
}
167
187
168
- fun unregisterBreakpoint (breakpoint : XLineBreakpoint <RobotCodeBreakpointProperties >) {
188
+ fun unregisterBreakpoint (breakpoint : XLineBreakpoint <RobotCodeLineBreakpointProperties >) {
169
189
runBlocking {
170
190
breakpointsMapMutex.withLock {
171
191
breakpoint.sourcePosition?.let {
@@ -314,4 +334,10 @@ class RobotCodeDebugProcess(
314
334
resume(context)
315
335
}
316
336
}
337
+
338
+ override fun startPausing () {
339
+ runBlocking {
340
+ debugServer.pause(PauseArguments ().apply { threadId = 0 }).await()
341
+ }
342
+ }
317
343
}
0 commit comments