Skip to content

Commit

Permalink
gopls/internal/regtest/marker: port the selectionrange markers
Browse files Browse the repository at this point in the history
For golang/go#54845

Change-Id: I289688a677fa6497035912eb2330bb3f0e963392
Reviewed-on: https://go-review.googlesource.com/c/tools/+/541129
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Alan Donovan <adonovan@google.com>
Auto-Submit: Robert Findley <rfindley@google.com>
  • Loading branch information
findleyr authored and gopherbot committed Nov 10, 2023
1 parent e3f6798 commit 92a8009
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 131 deletions.
64 changes: 0 additions & 64 deletions gopls/internal/lsp/lsp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@ package lsp

import (
"context"
"fmt"
"os"
"path/filepath"
"strings"
"testing"

"golang.org/x/tools/gopls/internal/bug"
Expand All @@ -18,7 +16,6 @@ import (
"golang.org/x/tools/gopls/internal/lsp/protocol"
"golang.org/x/tools/gopls/internal/lsp/source"
"golang.org/x/tools/gopls/internal/lsp/tests"
"golang.org/x/tools/gopls/internal/lsp/tests/compare"
"golang.org/x/tools/gopls/internal/span"
"golang.org/x/tools/internal/testenv"
)
Expand Down Expand Up @@ -236,64 +233,3 @@ func applyTextDocumentEdits(r *runner, edits []protocol.DocumentChanges) (map[sp
}
return res, nil
}

func (r *runner) SelectionRanges(t *testing.T, spn span.Span) {
uri := spn.URI()
sm, err := r.data.Mapper(uri)
if err != nil {
t.Fatal(err)
}
loc, err := sm.SpanLocation(spn)
if err != nil {
t.Error(err)
}

ranges, err := r.server.selectionRange(r.ctx, &protocol.SelectionRangeParams{
TextDocument: protocol.TextDocumentIdentifier{
URI: protocol.URIFromSpanURI(uri),
},
Positions: []protocol.Position{loc.Range.Start},
})
if err != nil {
t.Fatal(err)
}

sb := &strings.Builder{}
for i, path := range ranges {
fmt.Fprintf(sb, "Ranges %d: ", i)
rng := path
for {
s, e, err := sm.RangeOffsets(rng.Range)
if err != nil {
t.Error(err)
}

var snippet string
if e-s < 30 {
snippet = string(sm.Content[s:e])
} else {
snippet = string(sm.Content[s:s+15]) + "..." + string(sm.Content[e-15:e])
}

fmt.Fprintf(sb, "\n\t%v %q", rng.Range, strings.ReplaceAll(snippet, "\n", "\\n"))

if rng.Parent == nil {
break
}
rng = *rng.Parent
}
sb.WriteRune('\n')
}
got := sb.String()

testName := "selectionrange_" + tests.SpanName(spn)
want := r.data.Golden(t, testName, uri.Filename(), func() ([]byte, error) {
return []byte(got), nil
})
if want == nil {
t.Fatalf("golden file %q not found", uri.Filename())
}
if diff := compare.Text(got, string(want)); diff != "" {
t.Errorf("%s mismatch\n%s", testName, diff)
}
}
43 changes: 42 additions & 1 deletion gopls/internal/lsp/regtest/marker.go
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,6 @@ var update = flag.Bool("update", false, "if set, update test data during marker
// Existing marker tests (in ../testdata) to port:
// - CallHierarchy
// - InlayHints
// - SelectionRanges
func RunMarkerTests(t *testing.T, dir string) {
// The marker tests must be able to run go/packages.Load.
testenv.NeedsGoPackages(t)
Expand Down Expand Up @@ -738,6 +737,7 @@ var actionMarkerFuncs = map[string]func(marker){
"refs": actionMarkerFunc(refsMarker),
"rename": actionMarkerFunc(renameMarker),
"renameerr": actionMarkerFunc(renameErrMarker),
"selectionrange": actionMarkerFunc(selectionRangeMarker),
"signature": actionMarkerFunc(signatureMarker),
"snippet": actionMarkerFunc(snippetMarker),
"suggestedfix": actionMarkerFunc(suggestedfixMarker),
Expand Down Expand Up @@ -1867,6 +1867,47 @@ func renameErrMarker(mark marker, loc protocol.Location, newName string, wantErr
wantErr.check(mark, err)
}

func selectionRangeMarker(mark marker, loc protocol.Location, g *Golden) {
ctx := mark.run.env.Ctx
ranges, err := mark.run.env.Editor.Server.SelectionRange(ctx, &protocol.SelectionRangeParams{
TextDocument: mark.document(),
Positions: []protocol.Position{loc.Range.Start},
})
if err != nil {
mark.errorf("SelectionRange failed: %v", err)
return
}
var buf bytes.Buffer
m := mark.mapper()
for i, path := range ranges {
fmt.Fprintf(&buf, "Ranges %d:", i)
rng := path
for {
s, e, err := m.RangeOffsets(rng.Range)
if err != nil {
mark.errorf("RangeOffsets failed: %v", err)
return
}

var snippet string
if e-s < 30 {
snippet = string(m.Content[s:e])
} else {
snippet = string(m.Content[s:s+15]) + "..." + string(m.Content[e-15:e])
}

fmt.Fprintf(&buf, "\n\t%v %q", rng.Range, strings.ReplaceAll(snippet, "\n", "\\n"))

if rng.Parent == nil {
break
}
rng = *rng.Parent
}
buf.WriteRune('\n')
}
compareGolden(mark, "selection range", buf.Bytes(), g)
}

func tokenMarker(mark marker, loc protocol.Location, tokenType, mod string) {
tokens := mark.run.env.SemanticTokensRange(loc)
if len(tokens) != 1 {
Expand Down
13 changes: 0 additions & 13 deletions gopls/internal/lsp/testdata/selectionrange/foo.go

This file was deleted.

29 changes: 0 additions & 29 deletions gopls/internal/lsp/testdata/selectionrange/foo.go.golden

This file was deleted.

1 change: 0 additions & 1 deletion gopls/internal/lsp/testdata/summary.txt.golden
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
-- summary --
CallHierarchyCount = 2
SelectionRangesCount = 3

28 changes: 5 additions & 23 deletions gopls/internal/lsp/tests/tests.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,11 @@ var UpdateGolden = flag.Bool("golden", false, "Update golden files")
// These type names apparently avoid the need to repeat the
// type in the field name and the make() expression.
type CallHierarchy = map[span.Span]*CallHierarchyResult
type SelectionRanges = []span.Span

type Data struct {
Config packages.Config
Exported *packagestest.Exported
CallHierarchy CallHierarchy
SelectionRanges SelectionRanges
Config packages.Config
Exported *packagestest.Exported
CallHierarchy CallHierarchy

fragments map[string]string
dir string
Expand All @@ -76,7 +74,6 @@ type Data struct {
// we can abolish the interface now.
type Tests interface {
CallHierarchy(*testing.T, span.Span, *CallHierarchyResult)
SelectionRanges(*testing.T, span.Span)
}

type Completion struct {
Expand Down Expand Up @@ -295,9 +292,8 @@ func load(t testing.TB, mode string, dir string) *Data {

// Collect any data that needs to be used by subsequent tests.
if err := datum.Exported.Expect(map[string]interface{}{
"incomingcalls": datum.collectIncomingCalls,
"outgoingcalls": datum.collectOutgoingCalls,
"selectionrange": datum.collectSelectionRanges,
"incomingcalls": datum.collectIncomingCalls,
"outgoingcalls": datum.collectOutgoingCalls,
}); err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -362,15 +358,6 @@ func Run(t *testing.T, tests Tests, data *Data) {
}
})

t.Run("SelectionRanges", func(t *testing.T) {
t.Helper()
for _, span := range data.SelectionRanges {
t.Run(SpanName(span), func(t *testing.T) {
tests.SelectionRanges(t, span)
})
}
})

if *UpdateGolden {
for _, golden := range data.golden {
if !golden.Modified {
Expand All @@ -390,7 +377,6 @@ func checkData(t *testing.T, data *Data) {
buf := &bytes.Buffer{}

fmt.Fprintf(buf, "CallHierarchyCount = %v\n", len(data.CallHierarchy))
fmt.Fprintf(buf, "SelectionRangesCount = %v\n", len(data.SelectionRanges))

want := string(data.Golden(t, "summary", summaryFile, func() ([]byte, error) {
return buf.Bytes(), nil
Expand Down Expand Up @@ -471,10 +457,6 @@ func (data *Data) Golden(t *testing.T, tag, target string, update func() ([]byte
return file.Data[:len(file.Data)-1] // drop the trailing \n
}

func (data *Data) collectSelectionRanges(spn span.Span) {
data.SelectionRanges = append(data.SelectionRanges, spn)
}

func (data *Data) collectIncomingCalls(src span.Span, calls []span.Span) {
for _, call := range calls {
rng := data.mustRange(call)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
This test checks selection range functionality.

-- foo.go --
package foo

import "time"

func Bar(x, y int, t time.Time) int {
zs := []int{1, 2, 3} //@selectionrange("1", a)

for _, z := range zs {
x = x + z + y + zs[1] //@selectionrange("1", b)
}

return x + y //@selectionrange("+", c)
}
-- @a --
Ranges 0:
5:13-5:14 "1"
5:7-5:21 "[]int{1, 2, 3}"
5:1-5:21 "zs := []int{1, 2, 3}"
4:36-12:1 "{\\n\tzs := []int{...range(\"+\", c)\\n}"
4:0-12:1 "func Bar(x, y i...range(\"+\", c)\\n}"
0:0-12:1 "package foo\\n\\nim...range(\"+\", c)\\n}"
-- @b --
Ranges 0:
8:21-8:22 "1"
8:18-8:23 "zs[1]"
8:6-8:23 "x + z + y + zs[1]"
8:2-8:23 "x = x + z + y + zs[1]"
7:22-9:2 "{\\n\t\tx = x + z +...ange(\"1\", b)\\n\t}"
7:1-9:2 "for _, z := ran...ange(\"1\", b)\\n\t}"
4:36-12:1 "{\\n\tzs := []int{...range(\"+\", c)\\n}"
4:0-12:1 "func Bar(x, y i...range(\"+\", c)\\n}"
0:0-12:1 "package foo\\n\\nim...range(\"+\", c)\\n}"
-- @c --
Ranges 0:
11:8-11:13 "x + y"
11:1-11:13 "return x + y"
4:36-12:1 "{\\n\tzs := []int{...range(\"+\", c)\\n}"
4:0-12:1 "func Bar(x, y i...range(\"+\", c)\\n}"
0:0-12:1 "package foo\\n\\nim...range(\"+\", c)\\n}"

0 comments on commit 92a8009

Please sign in to comment.