Merge pull request #3704 from jsternberg/dap-case-insensitive-breakpoints
dap: detect breakpoints for files when the case differs
This commit is contained in:
+27
-5
@@ -9,6 +9,7 @@ import (
|
||||
"path"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
|
||||
@@ -573,7 +574,9 @@ func (b *breakpointMap) Set(fname string, sbps []dap.SourceBreakpoint) (breakpoi
|
||||
// null back in the JSON if there are no breakpoints
|
||||
breakpoints = []dap.Breakpoint{}
|
||||
|
||||
prev := b.byPath[fname]
|
||||
// Use lowercase paths to normalize the case. We can only know the correct casing after
|
||||
// we intersect the breakpoint map. When we report the pending breakpoint to the editor,
|
||||
prev := b.getByPath(fname)
|
||||
for _, sbp := range sbps {
|
||||
index := slices.IndexFunc(prev, func(e dap.Breakpoint) bool {
|
||||
return sbp.Line >= e.Line && sbp.Line <= e.EndLine && sbp.Column >= e.Column && sbp.Column <= e.EndColumn
|
||||
@@ -589,12 +592,16 @@ func (b *breakpointMap) Set(fname string, sbps []dap.SourceBreakpoint) (breakpoi
|
||||
EndLine: sbp.Line,
|
||||
Column: sbp.Column,
|
||||
EndColumn: sbp.Column,
|
||||
Reason: "pending",
|
||||
Source: &dap.Source{
|
||||
Name: path.Base(fname),
|
||||
Path: fname,
|
||||
},
|
||||
Reason: "pending",
|
||||
}
|
||||
}
|
||||
breakpoints = append(breakpoints, bp)
|
||||
}
|
||||
b.byPath[fname] = breakpoints
|
||||
b.setByPath(fname, breakpoints)
|
||||
return breakpoints
|
||||
}
|
||||
|
||||
@@ -615,7 +622,7 @@ func (b *breakpointMap) Intersect(ctx Context, src *pb.Source, ws string) map[di
|
||||
for _, info := range src.Infos {
|
||||
fname := filepath.Join(ws, info.Filename)
|
||||
|
||||
bps := b.byPath[fname]
|
||||
bps := b.getByPath(fname)
|
||||
for _, bp := range bps {
|
||||
if !bp.Verified && bp.Reason != "failed" {
|
||||
bp.Reason = "failed"
|
||||
@@ -656,7 +663,7 @@ func (b *breakpointMap) intersect(ctx Context, src *pb.Source, locs *pb.Location
|
||||
info := src.Infos[loc.SourceIndex]
|
||||
fname := filepath.Join(ws, info.Filename)
|
||||
|
||||
bps := b.byPath[fname]
|
||||
bps := b.getByPath(fname)
|
||||
if len(bps) == 0 {
|
||||
// No breakpoints for this file.
|
||||
continue
|
||||
@@ -675,6 +682,13 @@ func (b *breakpointMap) intersect(ctx Context, src *pb.Source, locs *pb.Location
|
||||
bp.Verified = true
|
||||
bp.Reason = ""
|
||||
|
||||
// The path from the source might be different than the path
|
||||
// the editor sent to us just because of different casing.
|
||||
// Prefer the version given to us from buildkit and tell
|
||||
// the editor what the proper casing for this should be.
|
||||
bp.Source.Name = path.Base(fname)
|
||||
bp.Source.Path = fname
|
||||
|
||||
ctx.C() <- &dap.BreakpointEvent{
|
||||
Event: dap.Event{Event: "breakpoint"},
|
||||
Body: dap.BreakpointEventBody{
|
||||
@@ -689,3 +703,11 @@ func (b *breakpointMap) intersect(ctx Context, src *pb.Source, locs *pb.Location
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (b *breakpointMap) setByPath(fname string, bps []dap.Breakpoint) {
|
||||
b.byPath[strings.ToLower(fname)] = bps
|
||||
}
|
||||
|
||||
func (b *breakpointMap) getByPath(fname string) []dap.Breakpoint {
|
||||
return b.byPath[strings.ToLower(fname)]
|
||||
}
|
||||
|
||||
+2
-2
@@ -202,7 +202,7 @@ func TestBreakpointMapIntersectVerified(t *testing.T) {
|
||||
assert.Len(t, digests, wantMatches)
|
||||
|
||||
expectedEvents := make(map[int]struct{})
|
||||
for i, bp := range bm.byPath[fpath] {
|
||||
for i, bp := range bm.getByPath(fpath) {
|
||||
if breakpointCases[i].expectVerified {
|
||||
expectedEvents[bp.Id] = struct{}{}
|
||||
}
|
||||
@@ -226,7 +226,7 @@ func TestBreakpointMapIntersectVerified(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
stored := bm.byPath[fpath]
|
||||
stored := bm.getByPath(fpath)
|
||||
if assert.Len(t, stored, len(breakpointCases)) {
|
||||
for i, bc := range breakpointCases {
|
||||
assert.Equal(t, bc.expectVerified, stored[i].Verified, "breakpoint %d (%s) mismatch", i, bc.desc)
|
||||
|
||||
+14
-6
@@ -228,18 +228,26 @@ func testDapBuildVerifiedBreakpoints(t *testing.T, sb integration.Sandbox) {
|
||||
{
|
||||
Reason: "changed",
|
||||
Breakpoint: dap.Breakpoint{
|
||||
Id: 1,
|
||||
Line: 2,
|
||||
EndLine: 2,
|
||||
Id: 1,
|
||||
Line: 2,
|
||||
EndLine: 2,
|
||||
Source: &dap.Source{
|
||||
Name: "Dockerfile",
|
||||
Path: path.Join(dir, "Dockerfile"),
|
||||
},
|
||||
Verified: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
Reason: "changed",
|
||||
Breakpoint: dap.Breakpoint{
|
||||
Id: 2,
|
||||
Line: 10,
|
||||
EndLine: 10,
|
||||
Id: 2,
|
||||
Line: 10,
|
||||
EndLine: 10,
|
||||
Source: &dap.Source{
|
||||
Name: "Dockerfile",
|
||||
Path: path.Join(dir, "Dockerfile"),
|
||||
},
|
||||
Verified: false,
|
||||
Reason: "failed",
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user