Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions service/dap/daptest/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,8 @@ func (c *Client) InitializeRequest() {
SupportsVariablePaging: true,
SupportsRunInTerminalRequest: true,
SupportsMemoryReferences: true,
SupportsMemoryEvent: true,
SupportsInvalidatedEvent: true,
Locale: "en-us",
}
c.send(request)
Expand Down
25 changes: 25 additions & 0 deletions service/dap/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,8 @@ type dapClientCapabilities struct {
supportsRunInTerminalRequest bool
supportsMemoryReferences bool
supportsProgressReporting bool
supportsMemoryEvent bool
supportsInvalidatedEvent bool
}

// DefaultLoadConfig controls how variables are loaded from the target's memory.
Expand Down Expand Up @@ -994,6 +996,8 @@ func (s *Session) setClientCapabilities(args dap.InitializeRequestArguments) {
s.clientCapabilities.supportsRunInTerminalRequest = args.SupportsRunInTerminalRequest
s.clientCapabilities.supportsVariablePaging = args.SupportsVariablePaging
s.clientCapabilities.supportsVariableType = args.SupportsVariableType
s.clientCapabilities.supportsMemoryEvent = args.SupportsMemoryEvent
s.clientCapabilities.supportsInvalidatedEvent = args.SupportsInvalidatedEvent
}

func cleanExeName(name string) string {
Expand Down Expand Up @@ -3652,6 +3656,17 @@ func (s *Session) onSetVariableRequest(request *dap.SetVariableRequest) {
// TODO(hyangah): instead of arg.Value, reload the variable and return
// the presentation of the new value.
s.send(response)

if s.clientCapabilities.supportsInvalidatedEvent {
// Enforce editors to reload full state after successfull variable update
// to fix problem described above
s.send(&dap.InvalidatedEvent{
Event: *s.newEvent("invalidated"),
Body: dap.InvalidatedEventBody{
Areas: []dap.InvalidatedAreas{"all"},
},
})
}
}

// onSetExpressionRequest sends a not-yet-implemented error response.
Expand Down Expand Up @@ -3788,6 +3803,16 @@ func (s *Session) onWriteMemoryRequest(request *dap.WriteMemoryRequest) {
BytesWritten: n,
},
})

if s.clientCapabilities.supportsInvalidatedEvent {
// Inform editor to refetch variables after changes
s.send(&dap.InvalidatedEvent{
Event: *s.newEvent("invalidated"),
Body: dap.InvalidatedEventBody{
Areas: []dap.InvalidatedAreas{"variables"},
},
})
}
}

func (s *Session) writeTargetMemory(addr uint64, data []byte) (int, error) {
Expand Down
12 changes: 12 additions & 0 deletions service/dap/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6636,6 +6636,10 @@ func (h *helperForSetVariable) expectSetVariable0(ref int, name, value string, w
if got, want := h.c.ExpectSetVariableResponse(h.t), value; got.Success != true || got.Body.Value != want {
h.t.Errorf("SetVariableRequest(%v, %v)=%#v, want {Success=true, Body.Value=%q", name, value, got, want)
}
ie := h.c.ExpectInvalidatedEvent(h.t)
if len(ie.Body.Areas) != 1 && ie.Body.Areas[0] != "all" {
h.t.Errorf("expected 'all' invalidated areas, got %v", ie.Body.Areas)
}
}

func (h *helperForSetVariable) failSetVariable0(ref int, name, value, wantErrInfo string, wantStop bool) {
Expand Down Expand Up @@ -8596,6 +8600,10 @@ func TestWriteMemory(t *testing.T) {
if wr.Body.BytesWritten != len(newData) {
t.Fatalf("expected %d bytes written, got %d", len(newData), wr.Body.BytesWritten)
}
ie := client.ExpectInvalidatedEvent(t)
if len(ie.Body.Areas) != 1 && ie.Body.Areas[0] != "variables" {
t.Fatalf("expected 'varianles' invalidated areas, got %v", ie.Body.Areas)
}

client.ReadMemoryRequest(bytesVar.MemoryReference, 0, len(newData))
rm = client.ExpectReadMemoryResponse(t)
Expand All @@ -8612,6 +8620,10 @@ func TestWriteMemory(t *testing.T) {
if wr.Body.BytesWritten != len(origData) {
t.Fatalf("expected %d bytes written, got %d", len(newData), wr.Body.BytesWritten)
}
ie = client.ExpectInvalidatedEvent(t)
if len(ie.Body.Areas) != 1 && ie.Body.Areas[0] != "variables" {
t.Fatalf("expected 'variables' invalidated areas, got %v", ie.Body.Areas)
}
},
disconnect: true,
},
Expand Down
Loading