diff --git a/internal/lsp/cmd/test/cmdtest.go b/internal/lsp/cmd/test/cmdtest.go index 312f7b8b43..ff0461b333 100644 --- a/internal/lsp/cmd/test/cmdtest.go +++ b/internal/lsp/cmd/test/cmdtest.go @@ -113,6 +113,10 @@ func (r *runner) Hover(t *testing.T, spn span.Span, info string) { //TODO: hovering not supported on command line } +func (r *runner) InlayHints(t *testing.T, spn span.Span) { + // TODO: inlayHints not supported on command line +} + func (r *runner) runGoplsCmd(t testing.TB, args ...string) (string, string) { rStdout, wStdout, err := os.Pipe() if err != nil { diff --git a/internal/lsp/lsp_test.go b/internal/lsp/lsp_test.go index ee364b8b03..e097100c2f 100644 --- a/internal/lsp/lsp_test.go +++ b/internal/lsp/lsp_test.go @@ -932,6 +932,48 @@ func (r *runner) References(t *testing.T, src span.Span, itemList []span.Span) { } } +func (r *runner) InlayHints(t *testing.T, spn span.Span) { + uri := spn.URI() + filename := uri.Filename() + + hints, err := r.server.InlayHint(r.ctx, &protocol.InlayHintParams{ + TextDocument: protocol.TextDocumentIdentifier{ + URI: protocol.URIFromSpanURI(uri), + }, + // TODO: add ViewPort + }) + if err != nil { + t.Fatal(err) + } + + // Map inlay hints to text edits. + edits := make([]protocol.TextEdit, len(hints)) + for i, hint := range hints { + edits[i] = protocol.TextEdit{ + Range: protocol.Range{Start: *hint.Position, End: *hint.Position}, + NewText: fmt.Sprintf("<%s>", hint.Label[0].Value), + } + } + + m, err := r.data.Mapper(uri) + if err != nil { + t.Fatal(err) + } + sedits, err := source.FromProtocolEdits(m, edits) + if err != nil { + t.Error(err) + } + got := diff.ApplyEdits(string(m.Content), sedits) + + withinlayHints := string(r.data.Golden("inlayHint", filename, func() ([]byte, error) { + return []byte(got), nil + })) + + if withinlayHints != got { + t.Errorf("format failed for %s, expected:\n%v\ngot:\n%v", filename, withinlayHints, got) + } +} + func (r *runner) Rename(t *testing.T, spn span.Span, newText string) { tag := fmt.Sprintf("%s-rename", newText) diff --git a/internal/lsp/source/source_test.go b/internal/lsp/source/source_test.go index 426bffc97b..9218f9ddc1 100644 --- a/internal/lsp/source/source_test.go +++ b/internal/lsp/source/source_test.go @@ -685,6 +685,10 @@ func (r *runner) Highlight(t *testing.T, src span.Span, locations []span.Span) { } } +func (r *runner) InlayHints(t *testing.T, src span.Span) { + // TODO(golang/go#53315): add source test +} + func (r *runner) Hover(t *testing.T, src span.Span, text string) { ctx := r.ctx _, srcRng, err := spanToRange(r.data, src) diff --git a/internal/lsp/testdata/inlayHint/a.go b/internal/lsp/testdata/inlayHint/a.go new file mode 100644 index 0000000000..90ef7c41d1 --- /dev/null +++ b/internal/lsp/testdata/inlayHint/a.go @@ -0,0 +1,9 @@ +package inlayHint //@inlayHint("package") + +func hello(name string) string { + return "Hello " + name +} + +func helloWorld() string { + return hello("World") +} diff --git a/internal/lsp/testdata/inlayHint/a.go.golden b/internal/lsp/testdata/inlayHint/a.go.golden new file mode 100644 index 0000000000..e4e6cc0c0c --- /dev/null +++ b/internal/lsp/testdata/inlayHint/a.go.golden @@ -0,0 +1,11 @@ +-- inlayHint -- +package inlayHint //@inlayHint("package") + +func hello(name string) string { + return "Hello " + name +} + +func helloWorld() string { + return hello("World") +} + diff --git a/internal/lsp/tests/tests.go b/internal/lsp/tests/tests.go index 8265cf2e9b..81a5d39902 100644 --- a/internal/lsp/tests/tests.go +++ b/internal/lsp/tests/tests.go @@ -81,6 +81,7 @@ type PrepareRenames map[span.Span]*source.PrepareItem type Symbols map[span.URI][]protocol.DocumentSymbol type SymbolsChildren map[string][]protocol.DocumentSymbol type SymbolInformation map[span.Span]protocol.SymbolInformation +type InlayHints []span.Span type WorkspaceSymbols map[WorkspaceSymbolsTestType]map[span.URI][]string type Signatures map[span.Span]*protocol.SignatureHelp type Links map[span.URI][]Link @@ -113,6 +114,7 @@ type Data struct { Highlights Highlights References References Renames Renames + InlayHints InlayHints PrepareRenames PrepareRenames Symbols Symbols symbolsChildren SymbolsChildren @@ -156,6 +158,7 @@ type Tests interface { Definition(*testing.T, span.Span, Definition) Implementation(*testing.T, span.Span, []span.Span) Highlight(*testing.T, span.Span, []span.Span) + InlayHints(*testing.T, span.Span) References(*testing.T, span.Span, []span.Span) Rename(*testing.T, span.Span, string) PrepareRename(*testing.T, span.Span, *source.PrepareItem) @@ -466,6 +469,7 @@ func load(t testing.TB, mode string, dir string) *Data { "hoverdef": datum.collectHoverDefinitions, "hover": datum.collectHovers, "highlight": datum.collectHighlights, + "inlayHint": datum.collectInlayHints, "refs": datum.collectReferences, "rename": datum.collectRenames, "prepare": datum.collectPrepareRenames, @@ -782,6 +786,17 @@ func Run(t *testing.T, tests Tests, data *Data) { } }) + t.Run("InlayHints", func(t *testing.T) { + t.Skip("Inlay Hints not yet implemented") + t.Helper() + for _, src := range data.InlayHints { + t.Run(SpanName(src), func(t *testing.T) { + t.Helper() + tests.InlayHints(t, src) + }) + } + }) + t.Run("References", func(t *testing.T) { t.Helper() for src, itemList := range data.References { @@ -1292,6 +1307,10 @@ func (data *Data) collectHighlights(src span.Span, expected []span.Span) { data.Highlights[src] = append(data.Highlights[src], expected...) } +func (data *Data) collectInlayHints(src span.Span) { + data.InlayHints = append(data.InlayHints, src) +} + func (data *Data) collectReferences(src span.Span, expected []span.Span) { data.References[src] = expected }