internal/lsp: add support for hovering runes

Enable to hover runes found in basic literals in various forms.
When a rune is found, the hover message provides a summary composed of a
printable version (if it exists) of the rune, its codepoint and its name.

Behaviour varies slightly depending on the basic literal: rune literals
always display the summary when hovered, string literals only display it
when an escaped rune sequence is found to avoid providing unnecessary
information, and finally number literals only when expressed as a
hexadecimal number whose size ranges from one to eight bytes.

Fixes golang/go#38239

Change-Id: I024fdd5c511a45c7c285e200ce1eda0669a45491
Reviewed-on: https://go-review.googlesource.com/c/tools/+/321810
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
Trust: Rebecca Stambler <rstambler@golang.org>
Trust: Robert Findley <rfindley@google.com>
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
This commit is contained in:
Jean-Hadrien Chabran 2021-04-30 21:34:57 +02:00 коммит произвёл Rebecca Stambler
Родитель 258ee27c37
Коммит cd7c003cd3
32 изменённых файлов: 491 добавлений и 198 удалений

1
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
)

3
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=

Просмотреть файл

@ -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 {

Просмотреть файл

@ -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 {

Просмотреть файл

@ -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()

Просмотреть файл

@ -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)

43
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", "")
}

Просмотреть файл

@ -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()
```

Просмотреть файл

@ -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()
```

30
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
)

40
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
```

Просмотреть файл

@ -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)
```

Просмотреть файл

@ -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)
```

2
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"

32
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\.

4
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)
}
}

6
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{}
```

2
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)

2
internal/lsp/testdata/godef/a/g.go.golden поставляемый
Просмотреть файл

@ -1,4 +1,4 @@
-- dur-hover --
-- dur-hoverdef --
```go
const dur time.Duration = 910350000000 // 15m10.35s
```

46
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)
}

46
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
```

Просмотреть файл

@ -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
```

14
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")

78
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")
```

12
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
```

6
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)
}
}

30
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
```

4
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)
}

4
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
```

Просмотреть файл

@ -22,7 +22,7 @@ var myUnclosedIf string
"description": "```go\nvar myUnclosedIf string\n```\n\n\\@myUnclosedIf"
}
-- myUnclosedIf-hover --
-- myUnclosedIf-hoverdef --
```go
var myUnclosedIf string
```

Просмотреть файл

@ -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₁
```

Просмотреть файл

@ -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,