diff --git a/go.mod b/go.mod index 1c1dad4101..ff8184facb 100644 --- a/go.mod +++ b/go.mod @@ -8,5 +8,6 @@ require ( golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d golang.org/x/sync v0.0.0-20210220032951-036812b2e83c golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e + golang.org/x/text v0.3.6 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 ) diff --git a/go.sum b/go.sum index a56a1307ae..b4edbe6be0 100644 --- a/go.sum +++ b/go.sum @@ -18,7 +18,10 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e h1:WUoyKPm6nCo1BnNUvPGnFG3T5DUVem42yDJZZ4CNxMA= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= diff --git a/internal/lsp/cmd/test/cmdtest.go b/internal/lsp/cmd/test/cmdtest.go index 2e9272611d..832d794c7d 100644 --- a/internal/lsp/cmd/test/cmdtest.go +++ b/internal/lsp/cmd/test/cmdtest.go @@ -108,6 +108,10 @@ func (r *runner) AddImport(t *testing.T, uri span.URI, expectedImport string) { //TODO: import addition not supported on command line } +func (r *runner) Hover(t *testing.T, spn span.Span, info string) { + //TODO: hovering 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 f095489c79..d21d71d666 100644 --- a/internal/lsp/lsp_test.go +++ b/internal/lsp/lsp_test.go @@ -718,7 +718,7 @@ func (r *runner) Definition(t *testing.T, spn span.Span, d tests.Definition) { didSomething := false if hover != nil { didSomething = true - tag := fmt.Sprintf("%s-hover", d.Name) + tag := fmt.Sprintf("%s-hoverdef", d.Name) expectHover := string(r.data.Golden(tag, d.Src.URI().Filename(), func() ([]byte, error) { return []byte(hover.Contents.Value), nil })) @@ -840,6 +840,43 @@ func (r *runner) Highlight(t *testing.T, src span.Span, locations []span.Span) { } } +func (r *runner) Hover(t *testing.T, src span.Span, text string) { + m, err := r.data.Mapper(src.URI()) + if err != nil { + t.Fatal(err) + } + loc, err := m.Location(src) + if err != nil { + t.Fatalf("failed for %v", err) + } + tdpp := protocol.TextDocumentPositionParams{ + TextDocument: protocol.TextDocumentIdentifier{URI: loc.URI}, + Position: loc.Range.Start, + } + params := &protocol.HoverParams{ + TextDocumentPositionParams: tdpp, + } + hover, err := r.server.Hover(r.ctx, params) + if err != nil { + t.Fatal(err) + } + if text == "" { + if hover != nil { + t.Errorf("want nil, got %v\n", hover) + } + } else { + if hover == nil { + t.Fatalf("want hover result to include %s, but got nil", text) + } + if got := hover.Contents.Value; got != text { + t.Errorf("want %v, got %v\n", text, got) + } + if want, got := loc.Range, hover.Range; want != got { + t.Errorf("want range %v, got %v instead", want, got) + } + } +} + func (r *runner) References(t *testing.T, src span.Span, itemList []span.Span) { sm, err := r.data.Mapper(src.URI()) if err != nil { diff --git a/internal/lsp/source/hover.go b/internal/lsp/source/hover.go index 0bc92d1fb4..56666d352e 100644 --- a/internal/lsp/source/hover.go +++ b/internal/lsp/source/hover.go @@ -14,9 +14,12 @@ import ( "go/format" "go/token" "go/types" + "strconv" "strings" "time" + "unicode/utf8" + "golang.org/x/text/unicode/runenames" "golang.org/x/tools/internal/event" "golang.org/x/tools/internal/lsp/protocol" "golang.org/x/tools/internal/typeparams" @@ -66,6 +69,9 @@ type HoverInformation struct { func Hover(ctx context.Context, snapshot Snapshot, fh FileHandle, position protocol.Position) (*protocol.Hover, error) { ident, err := Identifier(ctx, snapshot, fh, position) if err != nil { + if hover, innerErr := hoverRune(ctx, snapshot, fh, position); innerErr == nil { + return hover, nil + } return nil, nil } h, err := HoverIdentifier(ctx, ident) @@ -93,6 +99,155 @@ func Hover(ctx context.Context, snapshot Snapshot, fh FileHandle, position proto }, nil } +func hoverRune(ctx context.Context, snapshot Snapshot, fh FileHandle, position protocol.Position) (*protocol.Hover, error) { + ctx, done := event.Start(ctx, "source.hoverRune") + defer done() + + r, mrng, err := findRune(ctx, snapshot, fh, position) + if err != nil { + return nil, err + } + rng, err := mrng.Range() + if err != nil { + return nil, err + } + + var desc string + runeName := runenames.Name(r) + if len(runeName) > 0 && runeName[0] == '<' { + // Check if the rune looks like an HTML tag. If so, trim the surrounding <> + // characters to work around https://github.com/microsoft/vscode/issues/124042. + runeName = strings.TrimRight(runeName[1:], ">") + } + if strconv.IsPrint(r) { + desc = fmt.Sprintf("'%s', U+%04X, %s", string(r), uint32(r), runeName) + } else { + desc = fmt.Sprintf("U+%04X, %s", uint32(r), runeName) + } + return &protocol.Hover{ + Contents: protocol.MarkupContent{ + Kind: snapshot.View().Options().PreferredContentFormat, + Value: desc, + }, + Range: rng, + }, nil +} + +// ErrNoRuneFound is the error returned when no rune is found at a particular position. +var ErrNoRuneFound = errors.New("no rune found") + +// findRune returns rune information for a position in a file. +func findRune(ctx context.Context, snapshot Snapshot, fh FileHandle, pos protocol.Position) (rune, MappedRange, error) { + pkg, pgf, err := GetParsedFile(ctx, snapshot, fh, NarrowestPackage) + if err != nil { + return 0, MappedRange{}, err + } + spn, err := pgf.Mapper.PointSpan(pos) + if err != nil { + return 0, MappedRange{}, err + } + rng, err := spn.Range(pgf.Mapper.Converter) + if err != nil { + return 0, MappedRange{}, err + } + + // Find the basic literal enclosing the given position, if there is one. + var lit *ast.BasicLit + var found bool + ast.Inspect(pgf.File, func(n ast.Node) bool { + if found { + return false + } + if n, ok := n.(*ast.BasicLit); ok && rng.Start >= n.Pos() && rng.Start <= n.End() { + lit = n + found = true + } + return !found + }) + if !found { + return 0, MappedRange{}, ErrNoRuneFound + } + + var r rune + var start, end token.Pos + switch lit.Kind { + case token.CHAR: + s, err := strconv.Unquote(lit.Value) + if err != nil { + // If the conversion fails, it's because of an invalid syntax, therefore + // there is no rune to be found. + return 0, MappedRange{}, ErrNoRuneFound + } + r, _ = utf8.DecodeRuneInString(s) + if r == utf8.RuneError { + return 0, MappedRange{}, fmt.Errorf("rune error") + } + start, end = lit.Pos(), lit.End() + case token.INT: + // It's an integer, scan only if it is a hex litteral whose bitsize in + // ranging from 8 to 32. + if !(strings.HasPrefix(lit.Value, "0x") && len(lit.Value[2:]) >= 2 && len(lit.Value[2:]) <= 8) { + return 0, MappedRange{}, ErrNoRuneFound + } + v, err := strconv.ParseUint(lit.Value[2:], 16, 32) + if err != nil { + return 0, MappedRange{}, err + } + r = rune(v) + if r == utf8.RuneError { + return 0, MappedRange{}, fmt.Errorf("rune error") + } + start, end = lit.Pos(), lit.End() + case token.STRING: + // It's a string, scan only if it contains a unicode escape sequence under or before the + // current cursor position. + var found bool + strMappedRng, err := posToMappedRange(snapshot, pkg, lit.Pos(), lit.End()) + if err != nil { + return 0, MappedRange{}, err + } + strRng, err := strMappedRng.Range() + if err != nil { + return 0, MappedRange{}, err + } + offset := strRng.Start.Character + for i := pos.Character - offset; i > 0; i-- { + // Start at the cursor position and search backward for the beginning of a rune escape sequence. + rr, _ := utf8.DecodeRuneInString(lit.Value[i:]) + if rr == utf8.RuneError { + return 0, MappedRange{}, fmt.Errorf("rune error") + } + if rr == '\\' { + // Got the beginning, decode it. + var tail string + r, _, tail, err = strconv.UnquoteChar(lit.Value[i:], '"') + if err != nil { + // If the conversion fails, it's because of an invalid syntax, therefore is no rune to be found. + return 0, MappedRange{}, ErrNoRuneFound + } + // Only the rune escape sequence part of the string has to be highlighted, recompute the range. + runeLen := len(lit.Value) - (int(i) + len(tail)) + start = token.Pos(int(lit.Pos()) + int(i)) + end = token.Pos(int(start) + runeLen) + found = true + break + } + } + if !found { + // No escape sequence found + return 0, MappedRange{}, ErrNoRuneFound + } + default: + return 0, MappedRange{}, ErrNoRuneFound + } + + mappedRange, err := posToMappedRange(snapshot, pkg, start, end) + if err != nil { + return 0, MappedRange{}, err + } + return r, mappedRange, nil +} + func HoverIdentifier(ctx context.Context, i *IdentifierInfo) (*HoverInformation, error) { ctx, done := event.Start(ctx, "source.Hover") defer done() diff --git a/internal/lsp/source/source_test.go b/internal/lsp/source/source_test.go index f1ab3ff4c2..83ce712c83 100644 --- a/internal/lsp/source/source_test.go +++ b/internal/lsp/source/source_test.go @@ -576,12 +576,12 @@ func (r *runner) Definition(t *testing.T, spn span.Span, d tests.Definition) { didSomething := false if hover != "" { didSomething = true - tag := fmt.Sprintf("%s-hover", d.Name) + tag := fmt.Sprintf("%s-hoverdef", d.Name) expectHover := string(r.data.Golden(tag, d.Src.URI().Filename(), func() ([]byte, error) { return []byte(hover), nil })) if hover != expectHover { - t.Errorf("hover for %s failed:\n%s", d.Src, tests.Diff(t, expectHover, hover)) + t.Errorf("hoverdef for %s failed:\n%s", d.Src, tests.Diff(t, expectHover, hover)) } } if !d.OnlyHover { @@ -682,6 +682,37 @@ func (r *runner) Highlight(t *testing.T, src span.Span, locations []span.Span) { } } +func (r *runner) Hover(t *testing.T, src span.Span, text string) { + ctx := r.ctx + _, srcRng, err := spanToRange(r.data, src) + if err != nil { + t.Fatal(err) + } + fh, err := r.snapshot.GetFile(r.ctx, src.URI()) + if err != nil { + t.Fatal(err) + } + hover, err := source.Hover(ctx, r.snapshot, fh, srcRng.Start) + if err != nil { + t.Errorf("hover failed for %s: %v", src.URI(), err) + } + if text == "" { + if hover != nil { + t.Errorf("want nil, got %v\n", hover) + } + } else { + if hover == nil { + t.Fatalf("want hover result to not be nil") + } + if got := hover.Contents.Value; got != text { + t.Errorf("want %v, got %v\n", got, text) + } + if want, got := srcRng, hover.Range; want != got { + t.Errorf("want range %v, got %v instead", want, got) + } + } +} + func (r *runner) References(t *testing.T, src span.Span, itemList []span.Span) { ctx := r.ctx _, srcRng, err := spanToRange(r.data, src) diff --git a/internal/lsp/testdata/basiclit/basiclit.go b/internal/lsp/testdata/basiclit/basiclit.go index ab895dc011..9829003d35 100644 --- a/internal/lsp/testdata/basiclit/basiclit.go +++ b/internal/lsp/testdata/basiclit/basiclit.go @@ -10,4 +10,47 @@ func _() { _ = 1. //@complete(".") _ = 'a' //@complete("' ") + + _ = 'a' //@hover("'a'", "'a', U+0061, LATIN SMALL LETTER A") + _ = 0x61 //@hover("0x61", "'a', U+0061, LATIN SMALL LETTER A") + + _ = '\u2211' //@hover("'\\u2211'", "'āˆ‘', U+2211, N-ARY SUMMATION") + _ = 0x2211 //@hover("0x2211", "'āˆ‘', U+2211, N-ARY SUMMATION") + _ = "foo \u2211 bar" //@hover("\\u2211", "'āˆ‘', U+2211, N-ARY SUMMATION") + + _ = '\a' //@hover("'\\a'", "U+0007, control") + _ = "foo \a bar" //@hover("\\a", "U+0007, control") + + _ = '\U0001F30A' //@hover("'\\U0001F30A'", "'🌊', U+1F30A, WATER WAVE") + _ = 0x0001F30A //@hover("0x0001F30A", "'🌊', U+1F30A, WATER WAVE") + _ = "foo \U0001F30A bar" //@hover("\\U0001F30A", "'🌊', U+1F30A, WATER WAVE") + + _ = '\x7E' //@hover("'\\x7E'", "'~', U+007E, TILDE") + _ = "foo \x7E bar" //@hover("\\x7E", "'~', U+007E, TILDE") + _ = "foo \a bar" //@hover("\\a", "U+0007, control") + + _ = '\173' //@hover("'\\173'", "'{', U+007B, LEFT CURLY BRACKET") + _ = "foo \173 bar" //@hover("\\173", "'{', U+007B, LEFT CURLY BRACKET") + _ = "foo \173 bar \u2211 baz" //@hover("\\173", "'{', U+007B, LEFT CURLY BRACKET") + _ = "foo \173 bar \u2211 baz" //@hover("\\u2211", "'āˆ‘', U+2211, N-ARY SUMMATION") + _ = "foo\173bar\u2211baz" //@hover("\\173", "'{', U+007B, LEFT CURLY BRACKET") + _ = "foo\173bar\u2211baz" //@hover("\\u2211", "'āˆ‘', U+2211, N-ARY SUMMATION") + + // search for runes in string only if there is an escaped sequence + _ = "hello" //@hover("\"hello\"", "") + + // incorrect escaped rune sequences + _ = '\0' //@hover("'\\0'", "") + _ = '\u22111' //@hover("'\\u22111'", "") + _ = '\U00110000' //@hover("'\\U00110000'", "") + _ = '\u12e45'//@hover("'\\u12e45'", "") + _ = '\xa' //@hover("'\\xa'", "") + _ = 'aa' //@hover("'aa'", "") + + // other basic lits + _ = 1 //@hover("1", "") + _ = 1.2 //@hover("1.2", "") + _ = 1.2i //@hover("1.2i", "") + _ = 0123 //@hover("0123", "") + _ = 0x1234567890 //@hover("0x1234567890", "") } diff --git a/internal/lsp/testdata/cgo/declarecgo.go.golden b/internal/lsp/testdata/cgo/declarecgo.go.golden index 773f3b7d3e..b6d94d0c6c 100644 --- a/internal/lsp/testdata/cgo/declarecgo.go.golden +++ b/internal/lsp/testdata/cgo/declarecgo.go.golden @@ -22,7 +22,7 @@ func Example() "description": "```go\nfunc Example()\n```\n\n[`cgo.Example` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/cgo?utm_source=gopls#Example)" } --- funccgoexample-hover -- +-- funccgoexample-hoverdef -- ```go func Example() ``` diff --git a/internal/lsp/testdata/cgoimport/usecgo.go.golden b/internal/lsp/testdata/cgoimport/usecgo.go.golden index 8f7518a154..f33f94f84a 100644 --- a/internal/lsp/testdata/cgoimport/usecgo.go.golden +++ b/internal/lsp/testdata/cgoimport/usecgo.go.golden @@ -22,7 +22,7 @@ func cgo.Example() "description": "```go\nfunc cgo.Example()\n```\n\n[`cgo.Example` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/cgo?utm_source=gopls#Example)" } --- funccgoexample-hover -- +-- funccgoexample-hoverdef -- ```go func cgo.Example() ``` diff --git a/internal/lsp/testdata/godef/a/a.go b/internal/lsp/testdata/godef/a/a.go index 993fd86b43..5cc85527ae 100644 --- a/internal/lsp/testdata/godef/a/a.go +++ b/internal/lsp/testdata/godef/a/a.go @@ -1,5 +1,5 @@ // Package a is a package for testing go to definition. -package a //@mark(aPackage, "a "),hover("a ", aPackage) +package a //@mark(aPackage, "a "),hoverdef("a ", aPackage) import ( "fmt" @@ -9,19 +9,19 @@ import ( var ( // x is a variable. - x string //@x,hover("x", x) + x string //@x,hoverdef("x", x) ) // Constant block. When I hover on h, I should see this comment. const ( // When I hover on g, I should see this comment. - g = 1 //@g,hover("g", g) + g = 1 //@g,hoverdef("g", g) - h = 2 //@h,hover("h", h) + h = 2 //@h,hoverdef("h", h) ) // z is a variable too. -var z string //@z,hover("z", z) +var z string //@z,hoverdef("z", z) type A string //@mark(AString, "A") @@ -33,14 +33,14 @@ func AStuff() { //@AStuff var err error //@err fmt.Printf("%v", err) //@godef("err", err) - var y string //@string,hover("string", string) - _ = make([]int, 0) //@make,hover("make", make) + var y string //@string,hoverdef("string", string) + _ = make([]int, 0) //@make,hoverdef("make", make) var mu sync.Mutex - mu.Lock() //@Lock,hover("Lock", Lock) + mu.Lock() //@Lock,hoverdef("Lock", Lock) - var typ *types.Named //@mark(typesImport, "types"),hover("types", typesImport) - typ.Obj().Name() //@Name,hover("Name", Name) + var typ *types.Named //@mark(typesImport, "types"),hoverdef("types", typesImport) + typ.Obj().Name() //@Name,hoverdef("Name", Name) } type A struct { @@ -76,7 +76,7 @@ type J interface { func _() { // 1st type declaration block type ( - a struct { //@mark(declBlockA, "a"),hover("a", declBlockA) + a struct { //@mark(declBlockA, "a"),hoverdef("a", declBlockA) x string } ) @@ -84,21 +84,21 @@ func _() { // 2nd type declaration block type ( // b has a comment - b struct{} //@mark(declBlockB, "b"),hover("b", declBlockB) + b struct{} //@mark(declBlockB, "b"),hoverdef("b", declBlockB) ) // 3rd type declaration block type ( // c is a struct - c struct { //@mark(declBlockC, "c"),hover("c", declBlockC) + c struct { //@mark(declBlockC, "c"),hoverdef("c", declBlockC) f string } - d string //@mark(declBlockD, "d"),hover("d", declBlockD) + d string //@mark(declBlockD, "d"),hoverdef("d", declBlockD) ) type ( - e struct { //@mark(declBlockE, "e"),hover("e", declBlockE) + e struct { //@mark(declBlockE, "e"),hoverdef("e", declBlockE) f float64 } // e has a comment ) diff --git a/internal/lsp/testdata/godef/a/a.go.golden b/internal/lsp/testdata/godef/a/a.go.golden index c26829350b..182928eebb 100644 --- a/internal/lsp/testdata/godef/a/a.go.golden +++ b/internal/lsp/testdata/godef/a/a.go.golden @@ -1,4 +1,4 @@ --- Lock-hover -- +-- Lock-hoverdef -- ```go func (*sync.Mutex).Lock() ``` @@ -6,7 +6,7 @@ func (*sync.Mutex).Lock() [`(sync.Mutex).Lock` on pkg.go.dev](https://pkg.go.dev/sync?utm_source=gopls#Mutex.Lock) Lock locks m\. --- Name-hover -- +-- Name-hoverdef -- ```go func (*types.object).Name() string ``` @@ -38,7 +38,7 @@ func Random() int "description": "```go\nfunc Random() int\n```\n\n[`a.Random` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a?utm_source=gopls#Random)" } --- Random-hover -- +-- Random-hoverdef -- ```go func Random() int ``` @@ -68,15 +68,15 @@ func Random2(y int) int "description": "```go\nfunc Random2(y int) int\n```\n\n[`a.Random2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a?utm_source=gopls#Random2)" } --- Random2-hover -- +-- Random2-hoverdef -- ```go func Random2(y int) int ``` [`a.Random2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a?utm_source=gopls#Random2) --- aPackage-hover -- +-- aPackage-hoverdef -- Package a is a package for testing go to definition\. --- declBlockA-hover -- +-- declBlockA-hoverdef -- ```go type a struct { x string @@ -84,13 +84,13 @@ type a struct { ``` 1st type declaration block --- declBlockB-hover -- +-- declBlockB-hoverdef -- ```go type b struct{} ``` b has a comment --- declBlockC-hover -- +-- declBlockC-hoverdef -- ```go type c struct { f string @@ -98,13 +98,13 @@ type c struct { ``` c is a struct --- declBlockD-hover -- +-- declBlockD-hoverdef -- ```go type d string ``` 3rd type declaration block --- declBlockE-hover -- +-- declBlockE-hoverdef -- ```go type e struct { f float64 @@ -125,36 +125,36 @@ var err error "start": { "line": 33, "column": 6, - "offset": 597 + "offset": 612 }, "end": { "line": 33, "column": 9, - "offset": 600 + "offset": 615 } }, "description": "```go\nvar err error\n```\n\n\\@err" } --- err-hover -- +-- err-hoverdef -- ```go var err error ``` \@err --- g-hover -- +-- g-hoverdef -- ```go const g untyped int = 1 ``` When I hover on g, I should see this comment\. --- h-hover -- +-- h-hoverdef -- ```go const h untyped int = 2 ``` Constant block\. --- make-hover -- +-- make-hoverdef -- ```go func(t Type, size ...IntegerType) Type ``` @@ -162,23 +162,23 @@ func(t Type, size ...IntegerType) Type [`make` on pkg.go.dev](https://pkg.go.dev/builtin?utm_source=gopls#make) The make built\-in function allocates and initializes an object of type slice, map, or chan \(only\)\. --- string-hover -- +-- string-hoverdef -- ```go string ``` --- typesImport-hover -- +-- typesImport-hoverdef -- ```go package types ("go/types") ``` [`types` on pkg.go.dev](https://pkg.go.dev/go/types?utm_source=gopls) --- x-hover -- +-- x-hoverdef -- ```go var x string ``` x is a variable\. --- z-hover -- +-- z-hoverdef -- ```go var z string ``` diff --git a/internal/lsp/testdata/godef/a/a_test.go.golden b/internal/lsp/testdata/godef/a/a_test.go.golden index ac50b90b95..e5cb3d799c 100644 --- a/internal/lsp/testdata/godef/a/a_test.go.golden +++ b/internal/lsp/testdata/godef/a/a_test.go.golden @@ -20,7 +20,7 @@ func TestA(t *testing.T) "description": "```go\nfunc TestA(t *testing.T)\n```" } --- TestA-hover -- +-- TestA-hoverdef -- ```go func TestA(t *testing.T) ``` diff --git a/internal/lsp/testdata/godef/a/a_x_test.go.golden b/internal/lsp/testdata/godef/a/a_x_test.go.golden index dd1d740164..2e3064794f 100644 --- a/internal/lsp/testdata/godef/a/a_x_test.go.golden +++ b/internal/lsp/testdata/godef/a/a_x_test.go.golden @@ -20,7 +20,7 @@ func TestA2(t *testing.T) "description": "```go\nfunc TestA2(t *testing.T)\n```" } --- TestA2-hover -- +-- TestA2-hoverdef -- ```go func TestA2(t *testing.T) ``` diff --git a/internal/lsp/testdata/godef/a/d.go b/internal/lsp/testdata/godef/a/d.go index d20bdad988..2da8d058ed 100644 --- a/internal/lsp/testdata/godef/a/d.go +++ b/internal/lsp/testdata/godef/a/d.go @@ -1,4 +1,4 @@ -package a //@mark(a, "a "),hover("a ", a) +package a //@mark(a, "a "),hoverdef("a ", a) import "fmt" diff --git a/internal/lsp/testdata/godef/a/d.go.golden b/internal/lsp/testdata/godef/a/d.go.golden index d80c14a9df..23c7da1ec4 100644 --- a/internal/lsp/testdata/godef/a/d.go.golden +++ b/internal/lsp/testdata/godef/a/d.go.golden @@ -13,18 +13,18 @@ field Member string "start": { "line": 6, "column": 2, - "offset": 87 + "offset": 90 }, "end": { "line": 6, "column": 8, - "offset": 93 + "offset": 96 } }, "description": "```go\nfield Member string\n```\n\n[`(a.Thing).Member` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a?utm_source=gopls#Thing.Member)\n\n\\@Member" } --- Member-hover -- +-- Member-hoverdef -- ```go field Member string ``` @@ -45,18 +45,18 @@ func (Thing).Method(i int) string "start": { "line": 15, "column": 16, - "offset": 216 + "offset": 219 }, "end": { "line": 15, "column": 22, - "offset": 222 + "offset": 225 } }, "description": "```go\nfunc (Thing).Method(i int) string\n```\n\n[`(a.Thing).Method` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a?utm_source=gopls#Thing.Method)" } --- Method-hover -- +-- Method-hoverdef -- ```go func (Thing).Method(i int) string ``` @@ -77,18 +77,18 @@ var Other Thing "start": { "line": 9, "column": 5, - "offset": 118 + "offset": 121 }, "end": { "line": 9, "column": 10, - "offset": 123 + "offset": 126 } }, "description": "```go\nvar Other Thing\n```\n\n[`a.Other` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a?utm_source=gopls#Other)\n\n\\@Other" } --- Other-hover -- +-- Other-hoverdef -- ```go var Other Thing ``` @@ -111,18 +111,18 @@ type Thing struct { "start": { "line": 5, "column": 6, - "offset": 62 + "offset": 65 }, "end": { "line": 5, "column": 11, - "offset": 67 + "offset": 70 } }, "description": "```go\ntype Thing struct {\n\tMember string //@Member\n}\n```\n\n[`a.Thing` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a?utm_source=gopls#Thing)" } --- Thing-hover -- +-- Thing-hoverdef -- ```go type Thing struct { Member string //@Member @@ -143,22 +143,22 @@ func Things(val []string) []Thing "start": { "line": 11, "column": 6, - "offset": 145 + "offset": 148 }, "end": { "line": 11, "column": 12, - "offset": 151 + "offset": 154 } }, "description": "```go\nfunc Things(val []string) []Thing\n```\n\n[`a.Things` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a?utm_source=gopls#Things)" } --- Things-hover -- +-- Things-hoverdef -- ```go func Things(val []string) []Thing ``` [`a.Things` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a?utm_source=gopls#Things) --- a-hover -- +-- a-hoverdef -- Package a is a package for testing go to definition\. diff --git a/internal/lsp/testdata/godef/a/f.go b/internal/lsp/testdata/godef/a/f.go index 2d3eefcfbc..589c45fc1a 100644 --- a/internal/lsp/testdata/godef/a/f.go +++ b/internal/lsp/testdata/godef/a/f.go @@ -7,9 +7,9 @@ func TypeStuff() { //@Stuff switch y := interface{}(x).(type) { //@mark(switchY, "y"),godef("y", switchY) case int: //@mark(intY, "int") - fmt.Printf("%v", y) //@hover("y", intY) + fmt.Printf("%v", y) //@hoverdef("y", intY) case string: //@mark(stringY, "string") - fmt.Printf("%v", y) //@hover("y", stringY) + fmt.Printf("%v", y) //@hoverdef("y", stringY) } } diff --git a/internal/lsp/testdata/godef/a/f.go.golden b/internal/lsp/testdata/godef/a/f.go.golden index 6c84b4d5fa..a084356c06 100644 --- a/internal/lsp/testdata/godef/a/f.go.golden +++ b/internal/lsp/testdata/godef/a/f.go.golden @@ -1,8 +1,8 @@ --- intY-hover -- +-- intY-hoverdef -- ```go var y int ``` --- stringY-hover -- +-- stringY-hoverdef -- ```go var y string ``` @@ -28,7 +28,7 @@ var y interface{} "description": "```go\nvar y interface{}\n```" } --- switchY-hover -- +-- switchY-hoverdef -- ```go var y interface{} ``` diff --git a/internal/lsp/testdata/godef/a/g.go b/internal/lsp/testdata/godef/a/g.go index 4f31857e39..dfef2fb804 100644 --- a/internal/lsp/testdata/godef/a/g.go +++ b/internal/lsp/testdata/godef/a/g.go @@ -3,4 +3,4 @@ package a import "time" // dur is a constant of type time.Duration. -const dur = 15*time.Minute + 10*time.Second + 350*time.Millisecond //@dur,hover("dur", dur) +const dur = 15*time.Minute + 10*time.Second + 350*time.Millisecond //@dur,hoverdef("dur", dur) diff --git a/internal/lsp/testdata/godef/a/g.go.golden b/internal/lsp/testdata/godef/a/g.go.golden index d46ff048bd..b7ed739280 100644 --- a/internal/lsp/testdata/godef/a/g.go.golden +++ b/internal/lsp/testdata/godef/a/g.go.golden @@ -1,4 +1,4 @@ --- dur-hover -- +-- dur-hoverdef -- ```go const dur time.Duration = 910350000000 // 15m10.35s ``` diff --git a/internal/lsp/testdata/godef/a/h.go b/internal/lsp/testdata/godef/a/h.go index efe7d4ec12..5a5dcc6784 100644 --- a/internal/lsp/testdata/godef/a/h.go +++ b/internal/lsp/testdata/godef/a/h.go @@ -25,9 +25,9 @@ func _() { } var t s - _ = t.nested.number //@hover("number", nestedNumber) - _ = t.nested2[0].str //@hover("str", nestedString) - _ = t.x.x.x.x.x.m //@hover("m", nestedMap) + _ = t.nested.number //@hoverdef("number", nestedNumber) + _ = t.nested2[0].str //@hoverdef("str", nestedString) + _ = t.x.x.x.x.x.m //@hoverdef("m", nestedMap) } func _() { @@ -40,9 +40,9 @@ func _() { c int //@mark(structC, "c") } } - _ = s.a //@hover("a", structA) - _ = s.b //@hover("b", structB) - _ = s.b.c //@hover("c", structC) + _ = s.a //@hoverdef("a", structA) + _ = s.b //@hoverdef("b", structB) + _ = s.b.c //@hoverdef("c", structC) var arr []struct { // d field @@ -53,9 +53,9 @@ func _() { f int //@mark(arrF, "f") } } - _ = arr[0].d //@hover("d", arrD) - _ = arr[0].e //@hover("e", arrE) - _ = arr[0].e.f //@hover("f", arrF) + _ = arr[0].d //@hoverdef("d", arrD) + _ = arr[0].e //@hoverdef("e", arrE) + _ = arr[0].e.f //@hoverdef("f", arrF) var complex []struct { c <-chan map[string][]struct { @@ -68,16 +68,16 @@ func _() { } } } - _ = (<-complex[0].c)["0"][0].h //@hover("h", complexH) - _ = (<-complex[0].c)["0"][0].i //@hover("i", complexI) - _ = (<-complex[0].c)["0"][0].i.j //@hover("j", complexJ) + _ = (<-complex[0].c)["0"][0].h //@hoverdef("h", complexH) + _ = (<-complex[0].c)["0"][0].i //@hoverdef("i", complexI) + _ = (<-complex[0].c)["0"][0].i.j //@hoverdef("j", complexJ) var mapWithStructKey map[struct { // X key field x []string //@mark(mapStructKeyX, "x") }]int for k := range mapWithStructKey { - _ = k.x //@hover("x", mapStructKeyX) + _ = k.x //@hoverdef("x", mapStructKeyX) } var mapWithStructKeyAndValue map[struct { @@ -90,15 +90,15 @@ func _() { for k, v := range mapWithStructKeyAndValue { // TODO: we don't show docs for y field because both map key and value // are structs. And in this case, we parse only map value - _ = k.y //@hover("y", mapStructKeyY) - _ = v.x //@hover("x", mapStructValueX) + _ = k.y //@hoverdef("y", mapStructKeyY) + _ = v.x //@hoverdef("x", mapStructValueX) } var i []map[string]interface { // open method comment open() error //@mark(openMethod, "open") } - i[0]["1"].open() //@hover("open", openMethod) + i[0]["1"].open() //@hoverdef("open", openMethod) } func _() { @@ -106,7 +106,7 @@ func _() { // test description desc string //@mark(testDescription, "desc") }{} - _ = test.desc //@hover("desc", testDescription) + _ = test.desc //@hoverdef("desc", testDescription) for _, tt := range []struct { // test input @@ -123,11 +123,11 @@ func _() { } } }{} { - _ = tt.in //@hover("in", testInput) - _ = tt.in["0"][0].key //@hover("key", testInputKey) - _ = tt.in["0"][0].value //@hover("value", testInputValue) + _ = tt.in //@hoverdef("in", testInput) + _ = tt.in["0"][0].key //@hoverdef("key", testInputKey) + _ = tt.in["0"][0].value //@hoverdef("value", testInputValue) - _ = (<-tt.result.v).value //@hover("value", testResultValue) + _ = (<-tt.result.v).value //@hoverdef("value", testResultValue) } } @@ -142,6 +142,6 @@ func _() { } r := getPoints() - r[0].x //@hover("x", returnX) - r[0].y //@hover("y", returnY) + r[0].x //@hoverdef("x", returnX) + r[0].y //@hoverdef("y", returnY) } diff --git a/internal/lsp/testdata/godef/a/h.go.golden b/internal/lsp/testdata/godef/a/h.go.golden index 3525d4cfde..4b27211e9a 100644 --- a/internal/lsp/testdata/godef/a/h.go.golden +++ b/internal/lsp/testdata/godef/a/h.go.golden @@ -1,134 +1,134 @@ --- arrD-hover -- +-- arrD-hoverdef -- ```go field d int ``` d field --- arrE-hover -- +-- arrE-hoverdef -- ```go field e struct{f int} ``` e nested struct --- arrF-hover -- +-- arrF-hoverdef -- ```go field f int ``` f field of nested struct --- complexH-hover -- +-- complexH-hoverdef -- ```go field h int ``` h field --- complexI-hover -- +-- complexI-hoverdef -- ```go field i struct{j int} ``` i nested struct --- complexJ-hover -- +-- complexJ-hoverdef -- ```go field j int ``` j field of nested struct --- mapStructKeyX-hover -- +-- mapStructKeyX-hoverdef -- ```go field x []string ``` X key field --- mapStructKeyY-hover -- +-- mapStructKeyY-hoverdef -- ```go field y string ``` --- mapStructValueX-hover -- +-- mapStructValueX-hoverdef -- ```go field x string ``` X value field --- nestedMap-hover -- +-- nestedMap-hoverdef -- ```go field m map[string]float64 ``` nested map --- nestedNumber-hover -- +-- nestedNumber-hoverdef -- ```go field number int64 ``` nested number --- nestedString-hover -- +-- nestedString-hoverdef -- ```go field str string ``` nested string --- openMethod-hover -- +-- openMethod-hoverdef -- ```go func (interface).open() error ``` open method comment --- returnX-hover -- +-- returnX-hoverdef -- ```go field x int ``` X coord --- returnY-hover -- +-- returnY-hoverdef -- ```go field y int ``` Y coord --- structA-hover -- +-- structA-hoverdef -- ```go field a int ``` a field --- structB-hover -- +-- structB-hoverdef -- ```go field b struct{c int} ``` b nested struct --- structC-hover -- +-- structC-hoverdef -- ```go field c int ``` c field of nested struct --- testDescription-hover -- +-- testDescription-hoverdef -- ```go field desc string ``` test description --- testInput-hover -- +-- testInput-hoverdef -- ```go field in map[string][]struct{key string; value interface{}} ``` test input --- testInputKey-hover -- +-- testInputKey-hoverdef -- ```go field key string ``` test key --- testInputValue-hover -- +-- testInputValue-hoverdef -- ```go field value interface{} ``` test value --- testResultValue-hover -- +-- testResultValue-hoverdef -- ```go field value int ``` diff --git a/internal/lsp/testdata/godef/a/random.go.golden b/internal/lsp/testdata/godef/a/random.go.golden index 0f99a52f34..381a11acee 100644 --- a/internal/lsp/testdata/godef/a/random.go.golden +++ b/internal/lsp/testdata/godef/a/random.go.golden @@ -22,7 +22,7 @@ func (*Pos).Sum() int "description": "```go\nfunc (*Pos).Sum() int\n```\n\n[`(a.Pos).Sum` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a?utm_source=gopls#Pos.Sum)" } --- PosSum-hover -- +-- PosSum-hoverdef -- ```go func (*Pos).Sum() int ``` @@ -52,7 +52,7 @@ field x int "description": "```go\nfield x int\n```\n\n\\@mark\\(PosX, \\\"x\\\"\\),mark\\(PosY, \\\"y\\\"\\)" } --- PosX-hover -- +-- PosX-hoverdef -- ```go field x int ``` @@ -80,7 +80,7 @@ var y int "description": "```go\nvar y int\n```" } --- RandomParamY-hover -- +-- RandomParamY-hoverdef -- ```go var y int ``` @@ -106,7 +106,7 @@ field field string "description": "```go\nfield field string\n```" } --- TypField-hover -- +-- TypField-hoverdef -- ```go field field string ``` diff --git a/internal/lsp/testdata/godef/b/b.go b/internal/lsp/testdata/godef/b/b.go index 23d908f1f8..f9c1d64024 100644 --- a/internal/lsp/testdata/godef/b/b.go +++ b/internal/lsp/testdata/godef/b/b.go @@ -13,13 +13,13 @@ type Embed struct { func _() { e := Embed{} - e.Hi() //@hover("Hi", AHi) - e.B() //@hover("B", AB) - e.Field //@hover("Field", AField) - e.Field2 //@hover("Field2", AField2) - e.Hello() //@hover("Hello", AHello) - e.Hey() //@hover("Hey", AHey) - e.Goodbye() //@hover("Goodbye", AGoodbye) + e.Hi() //@hoverdef("Hi", AHi) + e.B() //@hoverdef("B", AB) + e.Field //@hoverdef("Field", AField) + e.Field2 //@hoverdef("Field2", AField2) + e.Hello() //@hoverdef("Hello", AHello) + e.Hey() //@hoverdef("Hey", AHey) + e.Goodbye() //@hoverdef("Goodbye", AGoodbye) } type aAlias = a.A //@mark(aAlias, "aAlias") diff --git a/internal/lsp/testdata/godef/b/b.go.golden b/internal/lsp/testdata/godef/b/b.go.golden index 553718075f..7f05a70ce1 100644 --- a/internal/lsp/testdata/godef/b/b.go.golden +++ b/internal/lsp/testdata/godef/b/b.go.golden @@ -1,4 +1,4 @@ --- AB-hover -- +-- AB-hoverdef -- ```go func (a.I).B() ``` @@ -6,7 +6,7 @@ func (a.I).B() [`(a.I).B` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a?utm_source=gopls#I.B) \@mark\(AB, \"B\"\) --- AField-hover -- +-- AField-hoverdef -- ```go field Field int ``` @@ -14,7 +14,7 @@ field Field int [`(a.S).Field` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a?utm_source=gopls#S.Field) \@mark\(AField, \"Field\"\) --- AField2-hover -- +-- AField2-hoverdef -- ```go field Field2 int ``` @@ -22,7 +22,7 @@ field Field2 int [`(a.R).Field2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a?utm_source=gopls#R.Field2) \@mark\(AField2, \"Field2\"\) --- AGoodbye-hover -- +-- AGoodbye-hoverdef -- ```go func (a.H).Goodbye() ``` @@ -30,7 +30,7 @@ func (a.H).Goodbye() [`(a.H).Goodbye` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a?utm_source=gopls#H.Goodbye) \@mark\(AGoodbye, \"Goodbye\"\) --- AHello-hover -- +-- AHello-hoverdef -- ```go func (a.J).Hello() ``` @@ -38,13 +38,13 @@ func (a.J).Hello() [`(a.J).Hello` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a?utm_source=gopls#J.Hello) \@mark\(AHello, \"Hello\"\) --- AHey-hover -- +-- AHey-hoverdef -- ```go func (a.R).Hey() ``` [`(a.R).Hey` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a?utm_source=gopls#R.Hey) --- AHi-hover -- +-- AHi-hoverdef -- ```go func (a.A).Hi() ``` @@ -74,7 +74,7 @@ package a ("golang.org/x/tools/internal/lsp/godef/a") "description": "```go\npackage a (\"golang.org/x/tools/internal/lsp/godef/a\")\n```\n\n[`a` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a?utm_source=gopls)" } --- AImport-hover -- +-- AImport-hoverdef -- ```go package a ("golang.org/x/tools/internal/lsp/godef/a") ``` @@ -95,18 +95,18 @@ type A string "start": { "line": 26, "column": 6, - "offset": 452 + "offset": 467 }, "end": { "line": 26, "column": 7, - "offset": 453 + "offset": 468 } }, "description": "```go\ntype A string\n```\n\n[`a.A` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a?utm_source=gopls#A)\n\n\\@mark\\(AString, \\\"A\\\"\\)" } --- AString-hover -- +-- AString-hoverdef -- ```go type A string ``` @@ -127,18 +127,18 @@ func a.AStuff() "start": { "line": 28, "column": 6, - "offset": 489 + "offset": 504 }, "end": { "line": 28, "column": 12, - "offset": 495 + "offset": 510 } }, "description": "```go\nfunc a.AStuff()\n```\n\n[`a.AStuff` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a?utm_source=gopls#AStuff)" } --- AStuff-hover -- +-- AStuff-hoverdef -- ```go func a.AStuff() ``` @@ -162,18 +162,18 @@ type S1 struct { "start": { "line": 27, "column": 6, - "offset": 566 + "offset": 587 }, "end": { "line": 27, "column": 8, - "offset": 568 + "offset": 589 } }, "description": "```go\ntype S1 struct {\n\tF1 int //@mark(S1F1, \"F1\")\n\tS2 //@godef(\"S2\", S2),mark(S1S2, \"S2\")\n\ta.A //@godef(\"A\", AString)\n\taAlias //@godef(\"a\", aAlias)\n}\n```\n\n[`b.S1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b?utm_source=gopls#S1)" } --- S1-hover -- +-- S1-hoverdef -- ```go type S1 struct { F1 int //@mark(S1F1, "F1") @@ -199,18 +199,18 @@ field F1 int "start": { "line": 28, "column": 2, - "offset": 585 + "offset": 606 }, "end": { "line": 28, "column": 4, - "offset": 587 + "offset": 608 } }, "description": "```go\nfield F1 int\n```\n\n[`(b.S1).F1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b?utm_source=gopls#S1.F1)\n\n\\@mark\\(S1F1, \\\"F1\\\"\\)" } --- S1F1-hover -- +-- S1F1-hoverdef -- ```go field F1 int ``` @@ -233,18 +233,18 @@ field S2 S2 "start": { "line": 29, "column": 2, - "offset": 617 + "offset": 638 }, "end": { "line": 29, "column": 4, - "offset": 619 + "offset": 640 } }, "description": "```go\nfield S2 S2\n```\n\n[`(b.S1).S2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b?utm_source=gopls#S1.S2)\n\n\\@godef\\(\\\"S2\\\", S2\\),mark\\(S1S2, \\\"S2\\\"\\)" } --- S1S2-hover -- +-- S1S2-hoverdef -- ```go field S2 S2 ``` @@ -269,18 +269,18 @@ type S2 struct { "start": { "line": 34, "column": 6, - "offset": 741 + "offset": 762 }, "end": { "line": 34, "column": 8, - "offset": 743 + "offset": 764 } }, "description": "```go\ntype S2 struct {\n\tF1 string //@mark(S2F1, \"F1\")\n\tF2 int //@mark(S2F2, \"F2\")\n\t*a.A //@godef(\"A\", AString),godef(\"a\",AImport)\n}\n```\n\n[`b.S2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b?utm_source=gopls#S2)" } --- S2-hover -- +-- S2-hoverdef -- ```go type S2 struct { F1 string //@mark(S2F1, "F1") @@ -305,18 +305,18 @@ field F1 string "start": { "line": 35, "column": 2, - "offset": 760 + "offset": 781 }, "end": { "line": 35, "column": 4, - "offset": 762 + "offset": 783 } }, "description": "```go\nfield F1 string\n```\n\n[`(b.S2).F1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b?utm_source=gopls#S2.F1)\n\n\\@mark\\(S2F1, \\\"F1\\\"\\)" } --- S2F1-hover -- +-- S2F1-hoverdef -- ```go field F1 string ``` @@ -339,18 +339,18 @@ field F2 int "start": { "line": 36, "column": 2, - "offset": 793 + "offset": 814 }, "end": { "line": 36, "column": 4, - "offset": 795 + "offset": 816 } }, "description": "```go\nfield F2 int\n```\n\n[`(b.S2).F2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b?utm_source=gopls#S2.F2)\n\n\\@mark\\(S2F2, \\\"F2\\\"\\)" } --- S2F2-hover -- +-- S2F2-hoverdef -- ```go field F2 int ``` @@ -371,18 +371,18 @@ type aAlias = a.A "start": { "line": 25, "column": 6, - "offset": 521 + "offset": 542 }, "end": { "line": 25, "column": 12, - "offset": 527 + "offset": 548 } }, "description": "```go\ntype aAlias = a.A\n```\n\n\\@mark\\(aAlias, \\\"aAlias\\\"\\)" } --- aAlias-hover -- +-- aAlias-hoverdef -- ```go type aAlias = a.A ``` @@ -403,18 +403,18 @@ const X untyped int = 0 "start": { "line": 57, "column": 7, - "offset": 1228 + "offset": 1249 }, "end": { "line": 57, "column": 8, - "offset": 1229 + "offset": 1250 } }, "description": "```go\nconst X untyped int = 0\n```\n\n[`b.X` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b?utm_source=gopls#X)\n\n\\@mark\\(bX, \\\"X\\\"\\),godef\\(\\\"X\\\", bX\\)" } --- bX-hover -- +-- bX-hoverdef -- ```go const X untyped int = 0 ``` @@ -446,7 +446,7 @@ package myFoo ("golang.org/x/tools/internal/lsp/foo") "description": "```go\npackage myFoo (\"golang.org/x/tools/internal/lsp/foo\")\n```\n\n[`myFoo` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/foo?utm_source=gopls)" } --- myFoo-hover -- +-- myFoo-hoverdef -- ```go package myFoo ("golang.org/x/tools/internal/lsp/foo") ``` diff --git a/internal/lsp/testdata/godef/b/c.go.golden b/internal/lsp/testdata/godef/b/c.go.golden index 9554c0d435..3ae3e2d0ac 100644 --- a/internal/lsp/testdata/godef/b/c.go.golden +++ b/internal/lsp/testdata/godef/b/c.go.golden @@ -16,18 +16,18 @@ type S1 struct { "start": { "line": 27, "column": 6, - "offset": 566 + "offset": 587 }, "end": { "line": 27, "column": 8, - "offset": 568 + "offset": 589 } }, "description": "```go\ntype S1 struct {\n\tF1 int //@mark(S1F1, \"F1\")\n\tS2 //@godef(\"S2\", S2),mark(S1S2, \"S2\")\n\ta.A //@godef(\"A\", AString)\n\taAlias //@godef(\"a\", aAlias)\n}\n```\n\n[`b.S1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b?utm_source=gopls#S1)" } --- S1-hover -- +-- S1-hoverdef -- ```go type S1 struct { F1 int //@mark(S1F1, "F1") @@ -53,18 +53,18 @@ field F1 int "start": { "line": 28, "column": 2, - "offset": 585 + "offset": 606 }, "end": { "line": 28, "column": 4, - "offset": 587 + "offset": 608 } }, "description": "```go\nfield F1 int\n```\n\n[`(b.S1).F1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b?utm_source=gopls#S1.F1)\n\n\\@mark\\(S1F1, \\\"F1\\\"\\)" } --- S1F1-hover -- +-- S1F1-hoverdef -- ```go field F1 int ``` diff --git a/internal/lsp/testdata/godef/b/e.go b/internal/lsp/testdata/godef/b/e.go index 92037ed339..7b96cd7e8a 100644 --- a/internal/lsp/testdata/godef/b/e.go +++ b/internal/lsp/testdata/godef/b/e.go @@ -22,10 +22,10 @@ godef(bFunc, Things) func _() { var x interface{} //@mark(eInterface, "interface{}") - switch x := x.(type) { //@hover("x", eInterface) + switch x := x.(type) { //@hoverdef("x", eInterface) case string: //@mark(eString, "string") - fmt.Println(x) //@hover("x", eString) + fmt.Println(x) //@hoverdef("x", eString) case int: //@mark(eInt, "int") - fmt.Println(x) //@hover("x", eInt) + fmt.Println(x) //@hoverdef("x", eInt) } } diff --git a/internal/lsp/testdata/godef/b/e.go.golden b/internal/lsp/testdata/godef/b/e.go.golden index 13c2e0eb5d..079ed7923c 100644 --- a/internal/lsp/testdata/godef/b/e.go.golden +++ b/internal/lsp/testdata/godef/b/e.go.golden @@ -13,18 +13,18 @@ field Member string "start": { "line": 6, "column": 2, - "offset": 87 + "offset": 90 }, "end": { "line": 6, "column": 8, - "offset": 93 + "offset": 96 } }, "description": "```go\nfield Member string\n```\n\n[`(a.Thing).Member` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a?utm_source=gopls#Thing.Member)\n\n\\@Member" } --- Member-hover -- +-- Member-hoverdef -- ```go field Member string ``` @@ -47,18 +47,18 @@ var a.Other a.Thing "start": { "line": 9, "column": 5, - "offset": 118 + "offset": 121 }, "end": { "line": 9, "column": 10, - "offset": 123 + "offset": 126 } }, "description": "```go\nvar a.Other a.Thing\n```\n\n[`a.Other` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a?utm_source=gopls#Other)\n\n\\@Other" } --- Other-hover -- +-- Other-hoverdef -- ```go var a.Other a.Thing ``` @@ -81,18 +81,18 @@ type Thing struct { "start": { "line": 5, "column": 6, - "offset": 62 + "offset": 65 }, "end": { "line": 5, "column": 11, - "offset": 67 + "offset": 70 } }, "description": "```go\ntype Thing struct {\n\tMember string //@Member\n}\n```\n\n[`a.Thing` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a?utm_source=gopls#Thing)" } --- Thing-hover -- +-- Thing-hoverdef -- ```go type Thing struct { Member string //@Member @@ -113,32 +113,32 @@ func a.Things(val []string) []a.Thing "start": { "line": 11, "column": 6, - "offset": 145 + "offset": 148 }, "end": { "line": 11, "column": 12, - "offset": 151 + "offset": 154 } }, "description": "```go\nfunc a.Things(val []string) []a.Thing\n```\n\n[`a.Things` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a?utm_source=gopls#Things)" } --- Things-hover -- +-- Things-hoverdef -- ```go func a.Things(val []string) []a.Thing ``` [`a.Things` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a?utm_source=gopls#Things) --- eInt-hover -- +-- eInt-hoverdef -- ```go var x int ``` --- eInterface-hover -- +-- eInterface-hoverdef -- ```go var x interface{} ``` --- eString-hover -- +-- eString-hoverdef -- ```go var x string ``` diff --git a/internal/lsp/testdata/godef/b/h.go b/internal/lsp/testdata/godef/b/h.go index c2776a03a5..c8cbe850f9 100644 --- a/internal/lsp/testdata/godef/b/h.go +++ b/internal/lsp/testdata/godef/b/h.go @@ -4,7 +4,7 @@ import . "golang.org/x/tools/internal/lsp/godef/a" func _() { // variable of type a.A - var _ A //@mark(AVariable, "_"),hover("_", AVariable) + var _ A //@mark(AVariable, "_"),hoverdef("_", AVariable) - AStuff() //@hover("AStuff", AStuff) + AStuff() //@hoverdef("AStuff", AStuff) } diff --git a/internal/lsp/testdata/godef/b/h.go.golden b/internal/lsp/testdata/godef/b/h.go.golden index b854dd4ab3..f32f0264f8 100644 --- a/internal/lsp/testdata/godef/b/h.go.golden +++ b/internal/lsp/testdata/godef/b/h.go.golden @@ -1,10 +1,10 @@ --- AStuff-hover -- +-- AStuff-hoverdef -- ```go func AStuff() ``` [`a.AStuff` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a?utm_source=gopls#AStuff) --- AVariable-hover -- +-- AVariable-hoverdef -- ```go var _ A ``` diff --git a/internal/lsp/testdata/godef/broken/unclosedIf.go.golden b/internal/lsp/testdata/godef/broken/unclosedIf.go.golden index eac0339236..5c3329d8b6 100644 --- a/internal/lsp/testdata/godef/broken/unclosedIf.go.golden +++ b/internal/lsp/testdata/godef/broken/unclosedIf.go.golden @@ -22,7 +22,7 @@ var myUnclosedIf string "description": "```go\nvar myUnclosedIf string\n```\n\n\\@myUnclosedIf" } --- myUnclosedIf-hover -- +-- myUnclosedIf-hoverdef -- ```go var myUnclosedIf string ``` diff --git a/internal/lsp/testdata/godef/infer_generics/inferred.go.golden b/internal/lsp/testdata/godef/infer_generics/inferred.go.golden index 2dd97d9b6a..081ea53dc0 100644 --- a/internal/lsp/testdata/godef/infer_generics/inferred.go.golden +++ b/internal/lsp/testdata/godef/infer_generics/inferred.go.golden @@ -1,20 +1,20 @@ --- argInfer-hover -- +-- argInfer-hoverdef -- ```go func app(s []int, e int) []int // func[S₁ interface{~[]Eā‚‚}, Eā‚‚ interface{}](s S₁, e Eā‚‚) S₁ ``` --- constrInf-hover -- +-- constrInf-hoverdef -- ```go func app(s []int, e int) []int // func[S₁ interface{~[]Eā‚‚}, Eā‚‚ interface{}](s S₁, e Eā‚‚) S₁ ``` --- constrInfer-hover -- +-- constrInfer-hoverdef -- ```go func app(s []int, e int) []int // func[S₁ interface{~[]Eā‚‚}, Eā‚‚ interface{}](s S₁, e Eā‚‚) S₁ ``` --- instance-hover -- +-- instance-hoverdef -- ```go func app(s []int, e int) []int // func[S₁ interface{~[]Eā‚‚}, Eā‚‚ interface{}](s S₁, e Eā‚‚) S₁ ``` --- partialInfer-hover -- +-- partialInfer-hoverdef -- ```go func app(s []int, e int) []int // func[S₁ interface{~[]Eā‚‚}, Eā‚‚ interface{}](s S₁, e Eā‚‚) S₁ ``` diff --git a/internal/lsp/tests/tests.go b/internal/lsp/tests/tests.go index d5db454b73..5d6af9ed1b 100644 --- a/internal/lsp/tests/tests.go +++ b/internal/lsp/tests/tests.go @@ -84,6 +84,7 @@ type WorkspaceSymbols map[WorkspaceSymbolsTestType]map[span.URI][]string type Signatures map[span.Span]*protocol.SignatureHelp type Links map[span.URI][]Link type AddImport map[span.URI]string +type Hovers map[span.Span]string type Data struct { Config packages.Config @@ -119,6 +120,7 @@ type Data struct { Signatures Signatures Links Links AddImport AddImport + Hovers Hovers t testing.TB fragments map[string]string @@ -161,6 +163,7 @@ type Tests interface { SignatureHelp(*testing.T, span.Span, *protocol.SignatureHelp) Link(*testing.T, span.URI, []Link) AddImport(*testing.T, span.URI, string) + Hover(*testing.T, span.Span, string) } type Definition struct { @@ -309,6 +312,7 @@ func load(t testing.TB, mode string, dir string) *Data { Signatures: make(Signatures), Links: make(Links), AddImport: make(AddImport), + Hovers: make(Hovers), t: t, dir: dir, @@ -459,7 +463,8 @@ func load(t testing.TB, mode string, dir string) *Data { "godef": datum.collectDefinitions, "implementations": datum.collectImplementations, "typdef": datum.collectTypeDefinitions, - "hover": datum.collectHoverDefinitions, + "hoverdef": datum.collectHoverDefinitions, + "hover": datum.collectHovers, "highlight": datum.collectHighlights, "refs": datum.collectReferences, "rename": datum.collectRenames, @@ -485,7 +490,7 @@ func load(t testing.TB, mode string, dir string) *Data { // Collect names for the entries that require golden files. if err := datum.Exported.Expect(map[string]interface{}{ "godef": datum.collectDefinitionNames, - "hover": datum.collectDefinitionNames, + "hoverdef": datum.collectDefinitionNames, "workspacesymbol": datum.collectWorkspaceSymbols(WorkspaceSymbolsDefault), "workspacesymbolfuzzy": datum.collectWorkspaceSymbols(WorkspaceSymbolsFuzzy), "workspacesymbolcasesensitive": datum.collectWorkspaceSymbols(WorkspaceSymbolsCaseSensitive), @@ -730,6 +735,16 @@ func Run(t *testing.T, tests Tests, data *Data) { } }) + t.Run("Hover", func(t *testing.T) { + t.Helper() + for pos, info := range data.Hovers { + t.Run(SpanName(pos), func(t *testing.T) { + t.Helper() + tests.Hover(t, pos, info) + }) + } + }) + t.Run("References", func(t *testing.T) { t.Helper() for src, itemList := range data.References { @@ -1222,6 +1237,10 @@ func (data *Data) collectHoverDefinitions(src, target span.Span) { } } +func (data *Data) collectHovers(src span.Span, expected string) { + data.Hovers[src] = expected +} + func (data *Data) collectTypeDefinitions(src, target span.Span) { data.Definitions[src] = Definition{ Src: src,