service/dap: Add error handlers for unsupported and not-yet-supported requests (#1918)

* Add no-op handlers for unsupported requests

* Fix whitespace

* Add couple of missing unsupported requests

* More comments

* Separate errors for unsupported and not-yet-implemented requests.

* Fix go.mod/sum dependencies

Co-authored-by: Polina Sokolova <polinasok@users.noreply.github.com>
This commit is contained in:
polinasok
2020-05-01 12:24:44 -07:00
committed by GitHub
parent 8f5df19948
commit 2f295f310d
4 changed files with 661 additions and 30 deletions

View File

@ -59,16 +59,35 @@ func (c *Client) expectReadProtocolMessage(t *testing.T) dap.Message {
return m
}
func (c *Client) ExpectDisconnectResponse(t *testing.T) *dap.DisconnectResponse {
t.Helper()
return c.expectReadProtocolMessage(t).(*dap.DisconnectResponse)
}
func (c *Client) ExpectErrorResponse(t *testing.T) *dap.ErrorResponse {
t.Helper()
return c.expectReadProtocolMessage(t).(*dap.ErrorResponse)
}
func (c *Client) expectErrorResponse(t *testing.T, id int, message string) *dap.ErrorResponse {
t.Helper()
er := c.expectReadProtocolMessage(t).(*dap.ErrorResponse)
if er.Body.Error.Id != id || er.Message != message {
t.Errorf("\ngot %#v\nwant Id=%d Message=%q", er, id, message)
}
return er
}
func (c *Client) ExpectNotYetImplementedErrorResponse(t *testing.T) *dap.ErrorResponse {
t.Helper()
return c.expectErrorResponse(t, 7777, "Not yet implemented")
}
func (c *Client) ExpectUnsupportedCommandErrorResponse(t *testing.T) *dap.ErrorResponse {
t.Helper()
return c.expectErrorResponse(t, 9999, "Unsupported command")
}
func (c *Client) ExpectDisconnectResponse(t *testing.T) *dap.DisconnectResponse {
t.Helper()
return c.expectReadProtocolMessage(t).(*dap.DisconnectResponse)
}
func (c *Client) ExpectContinueResponse(t *testing.T) *dap.ContinueResponse {
t.Helper()
return c.expectReadProtocolMessage(t).(*dap.ContinueResponse)
@ -128,6 +147,106 @@ func (c *Client) ExpectStackTraceResponse(t *testing.T) *dap.StackTraceResponse
return c.expectReadProtocolMessage(t).(*dap.StackTraceResponse)
}
func (c *Client) ExpectTerminateResponse(t *testing.T) *dap.TerminateResponse {
t.Helper()
return c.expectReadProtocolMessage(t).(*dap.TerminateResponse)
}
func (c *Client) ExpectRestartResponse(t *testing.T) *dap.RestartResponse {
t.Helper()
return c.expectReadProtocolMessage(t).(*dap.RestartResponse)
}
func (c *Client) ExpectSetFunctionBreakpointsResponse(t *testing.T) *dap.SetFunctionBreakpointsResponse {
t.Helper()
return c.expectReadProtocolMessage(t).(*dap.SetFunctionBreakpointsResponse)
}
func (c *Client) ExpectStepBackResponse(t *testing.T) *dap.StepBackResponse {
t.Helper()
return c.expectReadProtocolMessage(t).(*dap.StepBackResponse)
}
func (c *Client) ExpectReverseContinueResponse(t *testing.T) *dap.ReverseContinueResponse {
t.Helper()
return c.expectReadProtocolMessage(t).(*dap.ReverseContinueResponse)
}
func (c *Client) ExpectRestartFrameResponse(t *testing.T) *dap.RestartFrameResponse {
t.Helper()
return c.expectReadProtocolMessage(t).(*dap.RestartFrameResponse)
}
func (c *Client) ExpectSetExpressionResponse(t *testing.T) *dap.SetExpressionResponse {
t.Helper()
return c.expectReadProtocolMessage(t).(*dap.SetExpressionResponse)
}
func (c *Client) ExpectTerminateThreadsResponse(t *testing.T) *dap.TerminateThreadsResponse {
t.Helper()
return c.expectReadProtocolMessage(t).(*dap.TerminateThreadsResponse)
}
func (c *Client) ExpectStepInTargetsResponse(t *testing.T) *dap.StepInTargetsResponse {
t.Helper()
return c.expectReadProtocolMessage(t).(*dap.StepInTargetsResponse)
}
func (c *Client) ExpectGotoTargetsResponse(t *testing.T) *dap.GotoTargetsResponse {
t.Helper()
return c.expectReadProtocolMessage(t).(*dap.GotoTargetsResponse)
}
func (c *Client) ExpectCompletionsResponse(t *testing.T) *dap.CompletionsResponse {
t.Helper()
return c.expectReadProtocolMessage(t).(*dap.CompletionsResponse)
}
func (c *Client) ExpectExceptionInfoResponse(t *testing.T) *dap.ExceptionInfoResponse {
t.Helper()
return c.expectReadProtocolMessage(t).(*dap.ExceptionInfoResponse)
}
func (c *Client) ExpectLoadedSourcesResponse(t *testing.T) *dap.LoadedSourcesResponse {
t.Helper()
return c.expectReadProtocolMessage(t).(*dap.LoadedSourcesResponse)
}
func (c *Client) ExpectDataBreakpointInfoResponse(t *testing.T) *dap.DataBreakpointInfoResponse {
t.Helper()
return c.expectReadProtocolMessage(t).(*dap.DataBreakpointInfoResponse)
}
func (c *Client) ExpectSetDataBreakpointsResponse(t *testing.T) *dap.SetDataBreakpointsResponse {
t.Helper()
return c.expectReadProtocolMessage(t).(*dap.SetDataBreakpointsResponse)
}
func (c *Client) ExpectReadMemoryResponse(t *testing.T) *dap.ReadMemoryResponse {
t.Helper()
return c.expectReadProtocolMessage(t).(*dap.ReadMemoryResponse)
}
func (c *Client) ExpectDisassembleResponse(t *testing.T) *dap.DisassembleResponse {
t.Helper()
return c.expectReadProtocolMessage(t).(*dap.DisassembleResponse)
}
func (c *Client) ExpectCancelResponse(t *testing.T) *dap.CancelResponse {
t.Helper()
return c.expectReadProtocolMessage(t).(*dap.CancelResponse)
}
func (c *Client) ExpectBreakpointLocationsResponse(t *testing.T) *dap.BreakpointLocationsResponse {
t.Helper()
return c.expectReadProtocolMessage(t).(*dap.BreakpointLocationsResponse)
}
func (c *Client) ExpectModulesResponse(t *testing.T) *dap.ModulesResponse {
t.Helper()
return c.expectReadProtocolMessage(t).(*dap.ModulesResponse)
}
// InitializeRequest sends an 'initialize' request.
func (c *Client) InitializeRequest() {
request := &dap.InitializeRequest{Request: *c.newRequest("initialize")}
@ -165,6 +284,13 @@ func (c *Client) LaunchRequestWithArgs(arguments map[string]interface{}) {
c.send(request)
}
// AttachRequest sends an 'attach' request.
func (c *Client) AttachRequest() {
request := &dap.AttachRequest{Request: *c.newRequest("attach")}
// TODO(polina): populate meaningful arguments
c.send(request)
}
// DisconnectRequest sends a 'disconnect' request.
func (c *Client) DisconnectRequest() {
request := &dap.DisconnectRequest{Request: *c.newRequest("disconnect")}
@ -207,6 +333,34 @@ func (c *Client) ContinueRequest(thread int) {
c.send(request)
}
// NextRequest sends a 'next' request.
func (c *Client) NextRequest() {
request := &dap.NextRequest{Request: *c.newRequest("next")}
// TODO(polina): arguments
c.send(request)
}
// StepInRequest sends a 'stepIn' request.
func (c *Client) StepInRequest() {
request := &dap.NextRequest{Request: *c.newRequest("stepIn")}
// TODO(polina): arguments
c.send(request)
}
// StepOutRequest sends a 'stepOut' request.
func (c *Client) StepOutRequest() {
request := &dap.NextRequest{Request: *c.newRequest("stepOut")}
// TODO(polina): arguments
c.send(request)
}
// PauseRequest sends a 'pause' request.
func (c *Client) PauseRequest() {
request := &dap.NextRequest{Request: *c.newRequest("pause")}
// TODO(polina): arguments
c.send(request)
}
// ThreadsRequest sends a 'threads' request.
func (c *Client) ThreadsRequest() {
request := &dap.ThreadsRequest{Request: *c.newRequest("threads")}
@ -219,6 +373,138 @@ func (c *Client) StackTraceRequest() {
c.send(request)
}
// ScopesRequest sends a 'scopes' request.
func (c *Client) ScopesRequest() {
request := &dap.ScopesRequest{Request: *c.newRequest("scopes")}
c.send(request)
}
// VariablesRequest sends a 'scopes' request.
func (c *Client) VariablesRequest() {
request := &dap.ScopesRequest{Request: *c.newRequest("variables")}
c.send(request)
}
// TeriminateRequest sends a 'terminate' request.
func (c *Client) TerminateRequest() {
c.send(&dap.TerminateRequest{Request: *c.newRequest("terminate")})
}
// RestartRequest sends a 'restart' request.
func (c *Client) RestartRequest() {
c.send(&dap.RestartRequest{Request: *c.newRequest("restart")})
}
// SetFunctionBreakpointsRequest sends a 'setFunctionBreakpoints' request.
func (c *Client) SetFunctionBreakpointsRequest() {
c.send(&dap.SetFunctionBreakpointsRequest{Request: *c.newRequest("setFunctionBreakpoints")})
}
// StepBackRequest sends a 'stepBack' request.
func (c *Client) StepBackRequest() {
c.send(&dap.StepBackRequest{Request: *c.newRequest("stepBack")})
}
// ReverseContinueRequest sends a 'reverseContinue' request.
func (c *Client) ReverseContinueRequest() {
c.send(&dap.ReverseContinueRequest{Request: *c.newRequest("reverseContinue")})
}
// SetVariableRequest sends a 'setVariable' request.
func (c *Client) SetVariableRequest() {
c.send(&dap.ReverseContinueRequest{Request: *c.newRequest("setVariable")})
}
// RestartFrameRequest sends a 'restartFrame' request.
func (c *Client) RestartFrameRequest() {
c.send(&dap.RestartFrameRequest{Request: *c.newRequest("restartFrame")})
}
// GotoRequest sends a 'goto' request.
func (c *Client) GotoRequest() {
c.send(&dap.GotoRequest{Request: *c.newRequest("goto")})
}
// SetExpressionRequest sends a 'setExpression' request.
func (c *Client) SetExpressionRequest() {
c.send(&dap.SetExpressionRequest{Request: *c.newRequest("setExpression")})
}
// SourceRequest sends a 'source' request.
func (c *Client) SourceRequest() {
c.send(&dap.SourceRequest{Request: *c.newRequest("source")})
}
// TerminateThreadsRequest sends a 'terminateThreads' request.
func (c *Client) TerminateThreadsRequest() {
c.send(&dap.TerminateThreadsRequest{Request: *c.newRequest("terminateThreads")})
}
// EvaluateRequest sends a 'evaluate' request.
func (c *Client) EvaluateRequest() {
c.send(&dap.EvaluateRequest{Request: *c.newRequest("evaluate")})
}
// StepInTargetsRequest sends a 'stepInTargets' request.
func (c *Client) StepInTargetsRequest() {
c.send(&dap.StepInTargetsRequest{Request: *c.newRequest("stepInTargets")})
}
// GotoTargetsRequest sends a 'gotoTargets' request.
func (c *Client) GotoTargetsRequest() {
c.send(&dap.GotoTargetsRequest{Request: *c.newRequest("gotoTargets")})
}
// CompletionsRequest sends a 'completions' request.
func (c *Client) CompletionsRequest() {
c.send(&dap.CompletionsRequest{Request: *c.newRequest("completions")})
}
// ExceptionInfoRequest sends a 'exceptionInfo' request.
func (c *Client) ExceptionInfoRequest() {
c.send(&dap.ExceptionInfoRequest{Request: *c.newRequest("exceptionInfo")})
}
// LoadedSourcesRequest sends a 'loadedSources' request.
func (c *Client) LoadedSourcesRequest() {
c.send(&dap.LoadedSourcesRequest{Request: *c.newRequest("loadedSources")})
}
// DataBreakpointInfoRequest sends a 'dataBreakpointInfo' request.
func (c *Client) DataBreakpointInfoRequest() {
c.send(&dap.DataBreakpointInfoRequest{Request: *c.newRequest("dataBreakpointInfo")})
}
// SetDataBreakpointsRequest sends a 'setDataBreakpoints' request.
func (c *Client) SetDataBreakpointsRequest() {
c.send(&dap.SetDataBreakpointsRequest{Request: *c.newRequest("setDataBreakpoints")})
}
// ReadMemoryRequest sends a 'readMemory' request.
func (c *Client) ReadMemoryRequest() {
c.send(&dap.ReadMemoryRequest{Request: *c.newRequest("readMemory")})
}
// DisassembleRequest sends a 'disassemble' request.
func (c *Client) DisassembleRequest() {
c.send(&dap.DisassembleRequest{Request: *c.newRequest("disassemble")})
}
// CancelRequest sends a 'cancel' request.
func (c *Client) CancelRequest() {
c.send(&dap.CancelRequest{Request: *c.newRequest("cancel")})
}
// BreakpointLocationsRequest sends a 'breakpointLocations' request.
func (c *Client) BreakpointLocationsRequest() {
c.send(&dap.BreakpointLocationsRequest{Request: *c.newRequest("breakpointLocations")})
}
// ModulesRequest sends a 'modules' request.
func (c *Client) ModulesRequest() {
c.send(&dap.ModulesRequest{Request: *c.newRequest("modules")})
}
// UnknownRequest triggers dap.DecodeProtocolMessageFieldError.
func (c *Client) UnknownRequest() {
request := c.newRequest("unknown")

View File

@ -4,6 +4,7 @@ package dap
const (
UnsupportedCommand int = 9999
InternalError int = 8888
NotYetImplemented int = 7777
// The values below come from the vscode-go debug adaptor.
// Although the spec says they should be unique, the adaptor

View File

@ -194,82 +194,150 @@ func (s *Server) handleRequest(request dap.Message) {
switch request := request.(type) {
case *dap.InitializeRequest:
// Required
s.onInitializeRequest(request)
case *dap.LaunchRequest:
// Required
s.onLaunchRequest(request)
case *dap.AttachRequest:
s.sendUnsupportedErrorResponse(request.Request)
// Required
// TODO: implement this request in V0
s.onAttachRequest(request)
case *dap.DisconnectRequest:
// Required
s.onDisconnectRequest(request)
case *dap.TerminateRequest:
s.sendUnsupportedErrorResponse(request.Request)
// Optional (capability supportsTerminateRequest)
// TODO: implement this request in V1
s.onTerminateRequest(request)
case *dap.RestartRequest:
s.sendUnsupportedErrorResponse(request.Request)
// Optional (capability supportsRestartRequest)
// TODO: implement this request in V1
s.onRestartRequest(request)
case *dap.SetBreakpointsRequest:
// Required
s.onSetBreakpointsRequest(request)
case *dap.SetFunctionBreakpointsRequest:
s.sendUnsupportedErrorResponse(request.Request)
// Optional (capability supportsFunctionBreakpoints)
// TODO: implement this request in V1
s.onSetFunctionBreakpointsRequest(request)
case *dap.SetExceptionBreakpointsRequest:
// Optional (capability exceptionBreakpointFilters)
s.onSetExceptionBreakpointsRequest(request)
case *dap.ConfigurationDoneRequest:
// Optional (capability supportsConfigurationDoneRequest)
// Supported by vscode-go
s.onConfigurationDoneRequest(request)
case *dap.ContinueRequest:
// Required
s.onContinueRequest(request)
case *dap.NextRequest:
s.sendUnsupportedErrorResponse(request.Request)
// Required
// TODO: implement this request in V0
s.onNextRequest(request)
case *dap.StepInRequest:
s.sendUnsupportedErrorResponse(request.Request)
// Required
// TODO: implement this request in V0
s.onStepInRequest(request)
case *dap.StepOutRequest:
s.sendUnsupportedErrorResponse(request.Request)
// Required
// TODO: implement this request in V0
s.onStepOutRequest(request)
case *dap.StepBackRequest:
s.sendUnsupportedErrorResponse(request.Request)
// Optional (capability supportsStepBack)
// TODO: implement this request in V1
s.onStepBackRequest(request)
case *dap.ReverseContinueRequest:
s.sendUnsupportedErrorResponse(request.Request)
// Optional (capability supportsStepBack)
// TODO: implement this request in V1
s.onReverseContinueRequest(request)
case *dap.RestartFrameRequest:
// Optional (capability supportsRestartFrame)
s.sendUnsupportedErrorResponse(request.Request)
case *dap.GotoRequest:
// Optional (capability supportsGotoTargetsRequest)
s.sendUnsupportedErrorResponse(request.Request)
case *dap.PauseRequest:
s.sendUnsupportedErrorResponse(request.Request)
// Required
// TODO: implement this request in V0
s.onPauseRequest(request)
case *dap.StackTraceRequest:
s.sendUnsupportedErrorResponse(request.Request)
// Required
// TODO: implement this request in V0
s.onStackTraceRequest(request)
case *dap.ScopesRequest:
s.sendUnsupportedErrorResponse(request.Request)
// Required
// TODO: implement this request in V0
s.onScopesRequest(request)
case *dap.VariablesRequest:
s.sendUnsupportedErrorResponse(request.Request)
// Required
// TODO: implement this request in V0
s.onVariablesRequest(request)
case *dap.SetVariableRequest:
s.sendUnsupportedErrorResponse(request.Request)
// Optional (capability supportsSetVariable)
// Supported by vscode-go
// TODO: implement this request in V0
s.onSetVariableRequest(request)
case *dap.SetExpressionRequest:
s.sendUnsupportedErrorResponse(request.Request)
// Optional (capability supportsSetExpression)
// TODO: implement this request in V1
s.onSetExpressionRequest(request)
case *dap.SourceRequest:
// Required
// This does not make sense in the context of Go as
// the source cannot be a string eval'ed at runtime.
s.sendUnsupportedErrorResponse(request.Request)
case *dap.ThreadsRequest:
// Required
s.onThreadsRequest(request)
case *dap.TerminateThreadsRequest:
// Optional (capability supportsTerminateThreadsRequest)
s.sendUnsupportedErrorResponse(request.Request)
case *dap.EvaluateRequest:
s.sendUnsupportedErrorResponse(request.Request)
// Required - TODO
// TODO: implement this request in V0
s.onEvaluateRequest(request)
case *dap.StepInTargetsRequest:
// Optional (capability supportsStepInTargetsRequest)
s.sendUnsupportedErrorResponse(request.Request)
case *dap.GotoTargetsRequest:
// Optional (capability supportsGotoTargetsRequest)
s.sendUnsupportedErrorResponse(request.Request)
case *dap.CompletionsRequest:
// Optional (capability supportsCompletionsRequest)
s.sendUnsupportedErrorResponse(request.Request)
case *dap.ExceptionInfoRequest:
// Optional (capability supportsExceptionInfoRequest)
// TODO: does this request make sense for delve?
s.sendUnsupportedErrorResponse(request.Request)
case *dap.LoadedSourcesRequest:
s.sendUnsupportedErrorResponse(request.Request)
// Optional (capability supportsLoadedSourcesRequest)
// TODO: implement this request in V1
s.onLoadedSourcesRequest(request)
case *dap.DataBreakpointInfoRequest:
// Optional (capability supportsDataBreakpoints)
s.sendUnsupportedErrorResponse(request.Request)
case *dap.SetDataBreakpointsRequest:
// Optional (capability supportsDataBreakpoints)
s.sendUnsupportedErrorResponse(request.Request)
case *dap.ReadMemoryRequest:
s.sendUnsupportedErrorResponse(request.Request)
// Optional (capability supportsReadMemoryRequest)
// TODO: implement this request in V1
s.onReadMemoryRequest(request)
case *dap.DisassembleRequest:
s.sendUnsupportedErrorResponse(request.Request)
// Optional (capability supportsDisassembleRequest)
// TODO: implement this request in V1
s.onDisassembleRequest(request)
case *dap.CancelRequest:
s.sendUnsupportedErrorResponse(request.Request)
// Optional (capability supportsCancelRequest)
// TODO: does this request make sense for delve?
s.onCancelRequest(request)
case *dap.BreakpointLocationsRequest:
// Optional (capability supportsBreakpointLocationsRequest)
s.sendUnsupportedErrorResponse(request.Request)
case *dap.ModulesRequest:
// Optional (capability supportsModulesRequest)
// TODO: does this request make sense for delve?
s.sendUnsupportedErrorResponse(request.Request)
default:
// This is a DAP message that go-dap has a struct for, so
@ -291,6 +359,16 @@ func (s *Server) onInitializeRequest(request *dap.InitializeRequest) {
response.Body.SupportsConfigurationDoneRequest = true
// TODO(polina): support this to match vscode-go functionality
response.Body.SupportsSetVariable = false
// TODO(polina): support these requests in addition to vscode-go feature parity
response.Body.SupportsTerminateRequest = false
response.Body.SupportsRestartRequest = false
response.Body.SupportsFunctionBreakpoints = false
response.Body.SupportsStepBack = false
response.Body.SupportsSetExpression = false
response.Body.SupportsLoadedSourcesRequest = false
response.Body.SupportsReadMemoryRequest = false
response.Body.SupportsDisassembleRequest = false
response.Body.SupportsCancelRequest = false
s.send(response)
}
@ -422,7 +500,7 @@ func (s *Server) onSetBreakpointsRequest(request *dap.SetBreakpointsRequest) {
func (s *Server) onSetExceptionBreakpointsRequest(request *dap.SetExceptionBreakpointsRequest) {
// Unlike what DAP documentation claims, this request is always sent
// even though we specified no filters at initializatin. Handle as no-op.
// even though we specified no filters at initialization. Handle as no-op.
s.send(&dap.SetExceptionBreakpointsResponse{Response: *newResponse(request.Request)})
}
@ -488,6 +566,126 @@ func (s *Server) onThreadsRequest(request *dap.ThreadsRequest) {
s.send(response)
}
// onAttachRequest sends a not-yet-implemented error response.
// This is a mandatory request to support.
func (s *Server) onAttachRequest(request *dap.AttachRequest) { // TODO V0
s.sendNotYetImplementedErrorResponse(request.Request)
}
// onNextRequest sends a not-yet-implemented error response.
// This is a mandatory request to support.
func (s *Server) onNextRequest(request *dap.NextRequest) { // TODO V0
s.sendNotYetImplementedErrorResponse(request.Request)
}
// onStepInRequest sends a not-yet-implemented error response.
// This is a mandatory request to support.
func (s *Server) onStepInRequest(request *dap.StepInRequest) { // TODO V0
s.sendNotYetImplementedErrorResponse(request.Request)
}
// onStepOutRequest sends a not-yet-implemented error response.
// This is a mandatory request to support.
func (s *Server) onStepOutRequest(request *dap.StepOutRequest) { // TODO V0
s.sendNotYetImplementedErrorResponse(request.Request)
}
// onPauseRequest sends a not-yet-implemented error response.
// This is a mandatory request to support.
func (s *Server) onPauseRequest(request *dap.PauseRequest) { // TODO V0
s.sendNotYetImplementedErrorResponse(request.Request)
}
// onStackTraceRequest sends a not-yet-implemented error response.
// This is a mandatory request to support.
func (s *Server) onStackTraceRequest(request *dap.StackTraceRequest) { // TODO V0
s.sendNotYetImplementedErrorResponse(request.Request)
}
// onScopesRequest sends a not-yet-implemented error response.
// This is a mandatory request to support.
func (s *Server) onScopesRequest(request *dap.ScopesRequest) { // TODO V0
s.sendNotYetImplementedErrorResponse(request.Request)
}
// onVariablesRequest sends a not-yet-implemented error response.
// This is a mandatory request to support.
func (s *Server) onVariablesRequest(request *dap.VariablesRequest) { // TODO V0
s.sendNotYetImplementedErrorResponse(request.Request)
}
// onEvaluateRequest sends a not-yet-implemented error response.
// This is a mandatory request to support.
func (s *Server) onEvaluateRequest(request *dap.EvaluateRequest) { // TODO V0
s.sendNotYetImplementedErrorResponse(request.Request)
}
// onTerminateRequest sends a not-yet-implemented error response.
// Capability 'supportsTerminateRequest' is not set in 'initialize' response.
func (s *Server) onTerminateRequest(request *dap.TerminateRequest) {
s.sendNotYetImplementedErrorResponse(request.Request)
}
// onRestartRequest sends a not-yet-implemented error response
// Capability 'supportsRestartRequest' is not set in 'initialize' response.
func (s *Server) onRestartRequest(request *dap.RestartRequest) {
s.sendNotYetImplementedErrorResponse(request.Request)
}
// onSetFunctionBreakpointsRequest sends a not-yet-implemented error response.
// Capability 'supportsFunctionBreakpoints' is not set 'initialize' response.
func (s *Server) onSetFunctionBreakpointsRequest(request *dap.SetFunctionBreakpointsRequest) {
s.sendNotYetImplementedErrorResponse(request.Request)
}
// onStepBackRequest sends a not-yet-implemented error response.
// Capability 'supportsStepBack' is not set 'initialize' response.
func (s *Server) onStepBackRequest(request *dap.StepBackRequest) {
s.sendNotYetImplementedErrorResponse(request.Request)
}
// onReverseContinueRequest sends a not-yet-implemented error response.
// Capability 'supportsStepBack' is not set 'initialize' response.
func (s *Server) onReverseContinueRequest(request *dap.ReverseContinueRequest) {
s.sendNotYetImplementedErrorResponse(request.Request)
}
// onSetVariableRequest sends a not-yet-implemented error response.
// Capability 'supportsSetVariable' is not set 'initialize' response.
func (s *Server) onSetVariableRequest(request *dap.SetVariableRequest) { // TODO V0
s.sendNotYetImplementedErrorResponse(request.Request)
}
// onSetExpression sends a not-yet-implemented error response.
// Capability 'supportsSetExpression' is not set 'initialize' response.
func (s *Server) onSetExpressionRequest(request *dap.SetExpressionRequest) {
s.sendNotYetImplementedErrorResponse(request.Request)
}
// onLoadedSourcesRequest sends a not-yet-implemented error response.
// Capability 'supportsLoadedSourcesRequest' is not set 'initialize' response.
func (s *Server) onLoadedSourcesRequest(request *dap.LoadedSourcesRequest) {
s.sendNotYetImplementedErrorResponse(request.Request)
}
// onReadMemoryRequest sends a not-yet-implemented error response.
// Capability 'supportsReadMemoryRequest' is not set 'initialize' response.
func (s *Server) onReadMemoryRequest(request *dap.ReadMemoryRequest) {
s.sendNotYetImplementedErrorResponse(request.Request)
}
// onDisassembleRequest sends a not-yet-implemented error response.
// Capability 'supportsDisassembleRequest' is not set 'initialize' response.
func (s *Server) onDisassembleRequest(request *dap.DisassembleRequest) {
s.sendNotYetImplementedErrorResponse(request.Request)
}
// onCancelRequest sends a not-yet-implemented error response.
// Capability 'supportsCancelRequest' is not set 'initialize' response.
func (s *Server) onCancelRequest(request *dap.CancelRequest) {
s.sendNotYetImplementedErrorResponse(request.Request)
}
func (s *Server) sendErrorResponse(request dap.Request, id int, summary string, details string) {
er := &dap.ErrorResponse{}
er.Type = "response"
@ -521,6 +719,11 @@ func (s *Server) sendUnsupportedErrorResponse(request dap.Request) {
fmt.Sprintf("cannot process '%s' request", request.Command))
}
func (s *Server) sendNotYetImplementedErrorResponse(request dap.Request) {
s.sendErrorResponse(request, NotYetImplemented, "Not yet implemented",
fmt.Sprintf("cannot process '%s' request", request.Command))
}
func newResponse(request dap.Request) *dap.Response {
return &dap.Response{
ProtocolMessage: dap.ProtocolMessage{

View File

@ -168,15 +168,15 @@ func TestStopOnEntry(t *testing.T) {
// 8 >> stackTrace, << stackTrace
client.StackTraceRequest()
stResp := client.ExpectErrorResponse(t)
if stResp.Seq != 0 || stResp.RequestSeq != 8 || stResp.Message != "Unsupported command" {
t.Errorf("\ngot %#v\nwant Seq=0, RequestSeq=8 Message=\"Unsupported command\"", stResp)
if stResp.Seq != 0 || stResp.RequestSeq != 8 || stResp.Message != "Not yet implemented" {
t.Errorf("\ngot %#v\nwant Seq=0, RequestSeq=8 Message=\"Not yet implemented\"", stResp)
}
// 9 >> stackTrace, << stackTrace
client.StackTraceRequest()
stResp = client.ExpectErrorResponse(t)
if stResp.Seq != 0 || stResp.RequestSeq != 9 || stResp.Message != "Unsupported command" {
t.Errorf("\ngot %#v\nwant Seq=0, RequestSeq=9 Message=\"Unsupported command\"", stResp)
if stResp.Seq != 0 || stResp.RequestSeq != 9 || stResp.Message != "Not yet implemented" {
t.Errorf("\ngot %#v\nwant Seq=0, RequestSeq=9 Message=\"Not yet implemented\"", stResp)
}
// 10 >> continue, << continue, << terminated
@ -366,6 +366,147 @@ func TestLaunchTestRequest(t *testing.T) {
})
}
func TestUnupportedCommandResponses(t *testing.T) {
var got *dap.ErrorResponse
runTest(t, "increment", func(client *daptest.Client, fixture protest.Fixture) {
seqCnt := 1
expectUnsupportedCommand := func(cmd string) {
t.Helper()
got = client.ExpectUnsupportedCommandErrorResponse(t)
if got.RequestSeq != seqCnt || got.Command != cmd {
t.Errorf("\ngot %#v\nwant RequestSeq=%d Command=%s", got, seqCnt, cmd)
}
seqCnt++
}
client.RestartFrameRequest()
expectUnsupportedCommand("restartFrame")
client.GotoRequest()
expectUnsupportedCommand("goto")
client.SourceRequest()
expectUnsupportedCommand("source")
client.TerminateThreadsRequest()
expectUnsupportedCommand("terminateThreads")
client.StepInTargetsRequest()
expectUnsupportedCommand("stepInTargets")
client.GotoTargetsRequest()
expectUnsupportedCommand("gotoTargets")
client.CompletionsRequest()
expectUnsupportedCommand("completions")
client.ExceptionInfoRequest()
expectUnsupportedCommand("exceptionInfo")
client.DataBreakpointInfoRequest()
expectUnsupportedCommand("dataBreakpointInfo")
client.SetDataBreakpointsRequest()
expectUnsupportedCommand("setDataBreakpoints")
client.BreakpointLocationsRequest()
expectUnsupportedCommand("breakpointLocations")
client.ModulesRequest()
expectUnsupportedCommand("modules")
})
}
func TestRequiredNotYetImplementedResponses(t *testing.T) {
var got *dap.ErrorResponse
runTest(t, "increment", func(client *daptest.Client, fixture protest.Fixture) {
seqCnt := 1
expectNotYetImplemented := func(cmd string) {
t.Helper()
got = client.ExpectNotYetImplementedErrorResponse(t)
if got.RequestSeq != seqCnt || got.Command != cmd {
t.Errorf("\ngot %#v\nwant RequestSeq=%d Command=%s", got, seqCnt, cmd)
}
seqCnt++
}
client.AttachRequest()
expectNotYetImplemented("attach")
client.NextRequest()
expectNotYetImplemented("next")
client.StepInRequest()
expectNotYetImplemented("stepIn")
client.StepOutRequest()
expectNotYetImplemented("stepOut")
client.PauseRequest()
expectNotYetImplemented("pause")
client.StackTraceRequest()
expectNotYetImplemented("stackTrace")
client.ScopesRequest()
expectNotYetImplemented("scopes")
client.VariablesRequest()
expectNotYetImplemented("variables")
client.EvaluateRequest()
expectNotYetImplemented("evaluate")
})
}
func TestOptionalNotYetImplementedResponses(t *testing.T) {
var got *dap.ErrorResponse
runTest(t, "increment", func(client *daptest.Client, fixture protest.Fixture) {
seqCnt := 1
expectNotYetImplemented := func(cmd string) {
t.Helper()
got = client.ExpectNotYetImplementedErrorResponse(t)
if got.RequestSeq != seqCnt || got.Command != cmd {
t.Errorf("\ngot %#v\nwant RequestSeq=%d Command=%s", got, seqCnt, cmd)
}
seqCnt++
}
client.TerminateRequest()
expectNotYetImplemented("terminate")
client.RestartRequest()
expectNotYetImplemented("restart")
client.SetFunctionBreakpointsRequest()
expectNotYetImplemented("setFunctionBreakpoints")
client.StepBackRequest()
expectNotYetImplemented("stepBack")
client.ReverseContinueRequest()
expectNotYetImplemented("reverseContinue")
client.SetVariableRequest()
expectNotYetImplemented("setVariable")
client.SetExpressionRequest()
expectNotYetImplemented("setExpression")
client.LoadedSourcesRequest()
expectNotYetImplemented("loadedSources")
client.ReadMemoryRequest()
expectNotYetImplemented("readMemory")
client.DisassembleRequest()
expectNotYetImplemented("disassemble")
client.CancelRequest()
expectNotYetImplemented("cancel")
})
}
func TestBadLaunchRequests(t *testing.T) {
runTest(t, "increment", func(client *daptest.Client, fixture protest.Fixture) {
seqCnt := 1