internal/lsp: improve link in documentation on hover

This change refactors some of the logic that builds a link anchor for
a given symbol, pushing the actual Link into the HoverInformation struct.
This is necessary because type information is needed to build up that
link in certain cases, like methods.

The last step will be to correctly display struct fields.

Updates golang/go#34240
Fixes golang/go#36031

Change-Id: I7f989faddbaa07f91838a870b4477bf78ce8ddf7
Reviewed-on: https://go-review.googlesource.com/c/tools/+/210201
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Heschi Kreinick <heschi@google.com>
This commit is contained in:
Rebecca Stambler 2019-12-06 02:44:16 -05:00
parent 8facea2ecf
commit cfcbc7796e
20 changed files with 568 additions and 233 deletions

View File

@ -168,7 +168,7 @@ func (app *Application) connect(ctx context.Context) (*connection, error) {
case "":
connection := newConnection(app)
ctx, connection.Server = lsp.NewClientServer(ctx, cache.New(app.options), connection.Client)
return connection, connection.initialize(ctx)
return connection, connection.initialize(ctx, app.options)
case "internal":
internalMu.Lock()
defer internalMu.Unlock()
@ -186,7 +186,7 @@ func (app *Application) connect(ctx context.Context) (*connection, error) {
ctx, srv := lsp.NewServer(ctx, cache.New(app.options), jsonrpc2.NewHeaderStream(sr, sw))
srv.Run(ctx)
}()
if err := connection.initialize(ctx); err != nil {
if err := connection.initialize(ctx, app.options); err != nil {
return nil, err
}
internalConnections[app.wd] = connection
@ -201,17 +201,24 @@ func (app *Application) connect(ctx context.Context) (*connection, error) {
var jc *jsonrpc2.Conn
ctx, jc, connection.Server = protocol.NewClient(ctx, stream, connection.Client)
go jc.Run(ctx)
return connection, connection.initialize(ctx)
return connection, connection.initialize(ctx, app.options)
}
}
func (c *connection) initialize(ctx context.Context) error {
func (c *connection) initialize(ctx context.Context, options func(*source.Options)) error {
params := &protocol.ParamInitialize{}
params.RootURI = string(span.FileURI(c.Client.app.wd))
params.Capabilities.Workspace.Configuration = true
params.Capabilities.TextDocument.Hover = protocol.HoverClientCapabilities{
ContentFormat: []protocol.MarkupKind{protocol.PlainText},
// Make sure to respect configured options when sending initialize request.
opts := source.DefaultOptions
if options != nil {
options(&opts)
}
params.Capabilities.TextDocument.Hover = protocol.HoverClientCapabilities{
ContentFormat: []protocol.MarkupKind{opts.PreferredContentFormat},
}
if _, err := c.Server.Initialize(ctx, params); err != nil {
return err
}

View File

@ -14,6 +14,7 @@ import (
guru "golang.org/x/tools/cmd/guru/serial"
"golang.org/x/tools/internal/lsp/protocol"
"golang.org/x/tools/internal/lsp/source"
"golang.org/x/tools/internal/span"
"golang.org/x/tools/internal/tool"
errors "golang.org/x/xerrors"
@ -60,6 +61,15 @@ func (d *definition) Run(ctx context.Context, args ...string) error {
if len(args) != 1 {
return tool.CommandLineErrorf("definition expects 1 argument")
}
// Plaintext makes more sense for the command line.
opts := d.query.app.options
d.query.app.options = func(o *source.Options) {
opts(o)
o.PreferredContentFormat = protocol.PlainText
if d.query.MarkdownSupported {
o.PreferredContentFormat = protocol.Markdown
}
}
conn, err := d.query.app.connect(ctx)
if err != nil {
return err

View File

@ -23,8 +23,9 @@ const (
// query implements the query command.
type query struct {
JSON bool `flag:"json" help:"emit output in JSON format"`
Emulate string `flag:"emulate" help:"compatibility mode, causes gopls to emulate another tool.\nvalues depend on the operation being performed"`
JSON bool `flag:"json" help:"emit output in JSON format"`
MarkdownSupported bool `flag:"markdown" help:"support markdown in responses"`
Emulate string `flag:"emulate" help:"compatibility mode, causes gopls to emulate another tool.\nvalues depend on the operation being performed"`
app *Application
}

View File

@ -6,13 +6,10 @@ package lsp
import (
"context"
"encoding/json"
"fmt"
"golang.org/x/tools/internal/lsp/protocol"
"golang.org/x/tools/internal/lsp/source"
"golang.org/x/tools/internal/span"
"golang.org/x/tools/internal/telemetry/log"
)
func (s *Server) hover(ctx context.Context, params *protocol.HoverParams) (*protocol.Hover, error) {
@ -33,7 +30,7 @@ func (s *Server) hover(ctx context.Context, params *protocol.HoverParams) (*prot
if err != nil {
return nil, nil
}
hover, err := ident.Hover(ctx)
h, err := ident.Hover(ctx)
if err != nil {
return nil, err
}
@ -41,59 +38,15 @@ func (s *Server) hover(ctx context.Context, params *protocol.HoverParams) (*prot
if err != nil {
return nil, err
}
contents := s.toProtocolHoverContents(ctx, hover, view.Options())
hover, err := source.FormatHover(h, view.Options())
if err != nil {
return nil, err
}
return &protocol.Hover{
Contents: contents,
Range: rng,
Contents: protocol.MarkupContent{
Kind: view.Options().PreferredContentFormat,
Value: hover,
},
Range: rng,
}, nil
}
func (s *Server) toProtocolHoverContents(ctx context.Context, h *source.HoverInformation, options source.Options) protocol.MarkupContent {
content := protocol.MarkupContent{
Kind: options.PreferredContentFormat,
}
signature := h.Signature
if content.Kind == protocol.Markdown {
signature = fmt.Sprintf("```go\n%s\n```", h.Signature)
}
switch options.HoverKind {
case source.SingleLine:
doc := h.SingleLine
if content.Kind == protocol.Markdown {
doc = source.CommentToMarkdown(doc)
}
content.Value = doc
case source.NoDocumentation:
content.Value = signature
case source.SynopsisDocumentation:
if h.Synopsis != "" {
doc := h.Synopsis
if content.Kind == protocol.Markdown {
doc = source.CommentToMarkdown(h.Synopsis)
}
content.Value = fmt.Sprintf("%s\n%s", doc, signature)
} else {
content.Value = signature
}
content.Value += "\n" + h.DocumentationLink(options)
case source.FullDocumentation:
if h.FullDocumentation != "" {
doc := h.FullDocumentation
if content.Kind == protocol.Markdown {
doc = source.CommentToMarkdown(h.FullDocumentation)
}
content.Value = fmt.Sprintf("%s\n%s", signature, doc)
} else {
content.Value = signature
}
content.Value += "\n" + h.DocumentationLink(options)
case source.Structured:
b, err := json.Marshal(h)
if err != nil {
log.Error(ctx, "failed to marshal structured hover", err)
}
content.Value = string(b)
}
return content
}

View File

@ -6,6 +6,7 @@ package source
import (
"context"
"encoding/json"
"fmt"
"go/ast"
"go/doc"
@ -13,6 +14,7 @@ import (
"go/types"
"strings"
"golang.org/x/tools/internal/lsp/protocol"
"golang.org/x/tools/internal/telemetry/trace"
errors "golang.org/x/xerrors"
)
@ -31,23 +33,17 @@ type HoverInformation struct {
// FullDocumentation is the symbol's full documentation.
FullDocumentation string `json:"fullDocumentation"`
// pkgPath holds the package path of the hovered symbol.
pkgPath string
// Link is the pkg.go.dev anchor for the given symbol.
// For example, "go/ast#Node".
Link string `json:"link"`
// symbolName holds the symbol name without any package prefix.
symbolName string
// SymbolName is the types.Object.Name for the given symbol.
SymbolName string
source interface{}
comment *ast.CommentGroup
}
func (h *HoverInformation) DocumentationLink(options Options) string {
if h.symbolName == "" || h.pkgPath == "" || options.LinkTarget == "" {
return ""
}
return fmt.Sprintf("[%s on %s](https://%s/%s#%s)", h.symbolName, options.LinkTarget, options.LinkTarget, h.pkgPath, h.symbolName)
}
func (i *IdentifierInfo) Hover(ctx context.Context) (*HoverInformation, error) {
ctx, done := trace.StartSpan(ctx, "source.Hover")
defer done()
@ -68,16 +64,9 @@ func (i *IdentifierInfo) Hover(ctx context.Context) (*HoverInformation, error) {
h.Signature = objectString(x, i.qf)
}
if obj := i.Declaration.obj; obj != nil {
// Only show the documentation links for symbols in the package scope.
// TODO(https://golang.org/issue/34240): Handle other symbols.
if obj.Exported() && obj.Parent() == obj.Pkg().Scope() {
h.pkgPath = obj.Pkg().Path()
h.symbolName = obj.Name()
}
// Set the documentation.
h.SingleLine = objectString(obj, i.qf)
}
h.Link, h.SymbolName = i.linkAndSymbolName()
if h.comment != nil {
h.FullDocumentation = h.comment.Text()
h.Synopsis = doc.Synopsis(h.FullDocumentation)
@ -85,6 +74,57 @@ func (i *IdentifierInfo) Hover(ctx context.Context) (*HoverInformation, error) {
return h, nil
}
func (i *IdentifierInfo) linkAndSymbolName() (string, string) {
obj := i.Declaration.obj
if obj == nil {
return "", ""
}
switch obj := obj.(type) {
case *types.PkgName:
return obj.Imported().Path(), obj.Name()
case *types.Builtin:
return fmt.Sprintf("builtin#%s", obj.Name()), obj.Name()
}
// Don't return links for other unexported types.
if !obj.Exported() {
return "", ""
}
var rTypeName string
switch obj := obj.(type) {
case *types.Var:
if obj.IsField() {
// If the object is a field, and we have an associated selector,
// we can determine the struct.
if selection, ok := i.pkg.GetTypesInfo().Selections[i.selector]; ok {
switch rtyp := deref(selection.Recv()).(type) {
case *types.Named:
rTypeName = rtyp.Obj().Name()
}
}
}
case *types.Func:
typ, ok := obj.Type().(*types.Signature)
if !ok {
return "", ""
}
if r := typ.Recv(); r != nil {
switch rtyp := deref(r.Type()).(type) {
case *types.Struct:
rTypeName = r.Name()
case *types.Named:
rTypeName = rtyp.Obj().Name()
}
}
}
if rTypeName != "" {
link := fmt.Sprintf("%s#%s.%s", obj.Pkg().Path(), rTypeName, obj.Name())
symbol := fmt.Sprintf("(%s.%s).%s", obj.Pkg().Name(), rTypeName, obj.Name())
return link, symbol
}
// For most cases, the link is "package/path#symbol".
return fmt.Sprintf("%s#%s", obj.Pkg().Path(), obj.Name()), fmt.Sprintf("%s.%s", obj.Pkg().Name(), obj.Name())
}
// objectString is a wrapper around the types.ObjectString function.
// It handles adding more information to the object string.
func objectString(obj types.Object, qf types.Qualifier) string {
@ -199,3 +239,91 @@ func formatVar(node ast.Spec, obj types.Object, decl *ast.GenDecl) *HoverInforma
// If we weren't able to find documentation for the object.
return &HoverInformation{source: obj}
}
func FormatHover(h *HoverInformation, options Options) (string, error) {
signature := formatSignature(h.Signature, options)
switch options.HoverKind {
case SingleLine:
return h.SingleLine, nil
case NoDocumentation:
return signature, nil
case Structured:
b, err := json.Marshal(h)
if err != nil {
return "", err
}
return string(b), nil
}
link := formatLink(h, options)
switch options.HoverKind {
case SynopsisDocumentation:
doc := formatDoc(h.Synopsis, options)
return formatHover(options, doc, link, signature), nil
case FullDocumentation:
doc := formatDoc(h.FullDocumentation, options)
return formatHover(options, signature, link, doc), nil
}
return "", errors.Errorf("no hover for %v", h.source)
}
func formatLink(h *HoverInformation, options Options) string {
if options.LinkTarget == "" || h.Link == "" {
return ""
}
plainLink := fmt.Sprintf("https://%s/%s", options.LinkTarget, h.Link)
switch options.PreferredContentFormat {
case protocol.Markdown:
return fmt.Sprintf("[`%s` on %s](%s)", h.SymbolName, options.LinkTarget, plainLink)
case protocol.PlainText:
return ""
default:
return plainLink
}
}
func formatSignature(signature string, options Options) string {
if options.PreferredContentFormat == protocol.Markdown {
signature = fmt.Sprintf("```go\n%s\n```", signature)
}
return signature
}
func formatDoc(doc string, options Options) string {
if options.PreferredContentFormat == protocol.Markdown {
return CommentToMarkdown(doc)
}
return doc
}
func formatHover(options Options, x ...string) string {
var b strings.Builder
for i, el := range x {
if el != "" {
b.WriteString(el)
// Don't write out final newline.
if i == len(x) {
continue
}
// If any elements of the remainder of the list are non-empty,
// write a newline.
if anyNonEmpty(x[i+1:]) {
if options.PreferredContentFormat == protocol.Markdown {
b.WriteString("\n\n")
} else {
b.WriteRune('\n')
}
}
}
}
return b.String()
}
func anyNonEmpty(x []string) bool {
for _, el := range x {
if el != "" {
return true
}
}
return false
}

View File

@ -33,9 +33,11 @@ type IdentifierInfo struct {
Declaration Declaration
pkg Package
ident *ast.Ident
qf types.Qualifier
ident *ast.Ident
selector *ast.SelectorExpr
pkg Package
qf types.Qualifier
}
type Declaration struct {
@ -123,7 +125,9 @@ func identifier(s Snapshot, pkg Package, file *ast.File, pos token.Pos) (*Identi
qf: qualifier(file, pkg.GetTypes(), pkg.GetTypesInfo()),
pkg: pkg,
ident: searchForIdent(path[0]),
selector: searchForSelector(path),
}
// No identifier at the given position.
if result.ident == nil {
return nil, nil
@ -228,6 +232,16 @@ func searchForIdent(n ast.Node) *ast.Ident {
return nil
}
func searchForSelector(path []ast.Node) *ast.SelectorExpr {
for _, n := range path {
switch node := n.(type) {
case *ast.SelectorExpr:
return node
}
}
return nil
}
func typeToObject(typ types.Type) types.Object {
switch typ := typ.(type) {
case *types.Named:

View File

@ -46,7 +46,7 @@ var (
TextDocumentSyncKind: protocol.Incremental,
HoverKind: SynopsisDocumentation,
InsertTextFormat: protocol.PlainTextTextFormat,
PreferredContentFormat: protocol.PlainText,
PreferredContentFormat: protocol.Markdown,
SupportedCodeActions: map[FileKind]map[protocol.CodeActionKind]bool{
Go: {
protocol.SourceOrganizeImports: true,

View File

@ -519,12 +519,10 @@ func (r *runner) Definition(t *testing.T, spn span.Span, d tests.Definition) {
if err != nil {
t.Fatalf("failed for %v: %v", d.Src, err)
}
var hover string
if h.Synopsis != "" {
hover += h.Synopsis + "\n"
hover, err := source.FormatHover(h, r.view.Options())
if err != nil {
t.Fatal(err)
}
hover += h.Signature
hover += "\n" + h.DocumentationLink(r.view.Options())
rng, err := ident.Declaration.Range()
if err != nil {
t.Fatal(err)

View File

@ -388,12 +388,16 @@ func isPointer(T types.Type) bool {
return ok
}
// deref returns a pointer's element type; otherwise it returns typ.
// deref returns a pointer's element type, traversing as many levels as needed.
// Otherwise it returns typ.
func deref(typ types.Type) types.Type {
if p, ok := typ.Underlying().(*types.Pointer); ok {
return p.Elem()
for {
p, ok := typ.Underlying().(*types.Pointer)
if !ok {
return typ
}
typ = p.Elem()
}
return typ
}
func isTypeName(obj types.Object) bool {

View File

@ -1,6 +1,9 @@
-- funccgoexample-definition --
cgo/declarecgo.go:17:6-13: defined here as func cgo.Example()
[Example on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/cgo#Example)
cgo/declarecgo.go:17:6-13: defined here as [`cgo.Example` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/cgo#Example)
```go
func cgo.Example()
```
-- funccgoexample-definition-json --
{
"span": {
@ -16,9 +19,12 @@ cgo/declarecgo.go:17:6-13: defined here as func cgo.Example()
"offset": 160
}
},
"description": "func cgo.Example()\n[Example on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/cgo#Example)"
"description": "[`cgo.Example` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/cgo#Example)\n\n```go\nfunc cgo.Example()\n```"
}
-- funccgoexample-hover --
[`cgo.Example` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/cgo#Example)
```go
func cgo.Example()
[Example on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/cgo#Example)
```

View File

@ -2,7 +2,10 @@
package a
import "fmt"
import (
"fmt"
"sync"
)
type A string //@A
@ -16,4 +19,7 @@ func AStuff() { //@AStuff
var y string //@string,hover("string", string)
_ = make([]int, 0) //@make,hover("make", make)
var mu sync.Mutex
mu.Lock() //@Lock,hover("Lock", Lock)
}

View File

@ -1,6 +1,17 @@
-- Lock-hover --
Lock locks m\.
[`(sync.Mutex).Lock` on pkg.go.dev](https://pkg.go.dev/sync#Mutex.Lock)
```go
func (*sync.Mutex).Lock()
```
-- Random-definition --
godef/a/random.go:3:6-12: defined here as func Random() int
[Random on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Random)
godef/a/random.go:3:6-12: defined here as [`a.Random` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Random)
```go
func Random() int
```
-- Random-definition-json --
{
"span": {
@ -16,15 +27,21 @@ godef/a/random.go:3:6-12: defined here as func Random() int
"offset": 22
}
},
"description": "func Random() int\n[Random on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Random)"
"description": "[`a.Random` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Random)\n\n```go\nfunc Random() int\n```"
}
-- Random-hover --
[`a.Random` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Random)
```go
func Random() int
[Random on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Random)
```
-- Random2-definition --
godef/a/random.go:8:6-13: defined here as func Random2(y int) int
[Random2 on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Random2)
godef/a/random.go:8:6-13: defined here as [`a.Random2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Random2)
```go
func Random2(y int) int
```
-- Random2-definition-json --
{
"span": {
@ -40,39 +57,50 @@ godef/a/random.go:8:6-13: defined here as func Random2(y int) int
"offset": 78
}
},
"description": "func Random2(y int) int\n[Random2 on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Random2)"
"description": "[`a.Random2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Random2)\n\n```go\nfunc Random2(y int) int\n```"
}
-- Random2-hover --
[`a.Random2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Random2)
```go
func Random2(y int) int
[Random2 on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Random2)
```
-- err-definition --
godef/a/a.go:14:6-9: defined here as var err error
godef/a/a.go:17:6-9: defined here as ```go
var err error
```
-- err-definition-json --
{
"span": {
"uri": "file://godef/a/a.go",
"start": {
"line": 14,
"line": 17,
"column": 6,
"offset": 203
"offset": 216
},
"end": {
"line": 14,
"line": 17,
"column": 9,
"offset": 206
"offset": 219
}
},
"description": "var err error"
"description": "```go\nvar err error\n```"
}
-- err-hover --
```go
var err error
```
-- make-hover --
The make built-in function allocates and initializes an object of type slice, map, or chan (only).
The make built\-in function allocates and initializes an object of type slice, map, or chan \(only\)\.
[`make` on pkg.go.dev](https://pkg.go.dev/builtin#make)
```go
func(t Type, size ...IntegerType) Type
```
-- string-hover --
```go
string
```

View File

@ -1,6 +1,11 @@
-- Member-definition --
godef/a/d.go:6:2-8: defined here as @Member
godef/a/d.go:6:2-8: defined here as \@Member
[`(a.Thing).Member` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Thing.Member)
```go
field Member string
```
-- Member-definition-json --
{
"span": {
@ -16,15 +21,23 @@ field Member string
"offset": 61
}
},
"description": "@Member\nfield Member string"
"description": "\\@Member\n\n[`(a.Thing).Member` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Thing.Member)\n\n```go\nfield Member string\n```"
}
-- Member-hover --
@Member
field Member string
\@Member
[`(a.Thing).Member` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Thing.Member)
```go
field Member string
```
-- Method-definition --
godef/a/d.go:15:16-22: defined here as func (Thing).Method(i int) string
godef/a/d.go:15:16-22: defined here as [`(a.Thing).Method` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Thing.Method)
```go
func (Thing).Method(i int) string
```
-- Method-definition-json --
{
"span": {
@ -40,15 +53,21 @@ godef/a/d.go:15:16-22: defined here as func (Thing).Method(i int) string
"offset": 190
}
},
"description": "func (Thing).Method(i int) string"
"description": "[`(a.Thing).Method` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Thing.Method)\n\n```go\nfunc (Thing).Method(i int) string\n```"
}
-- Method-hover --
func (Thing).Method(i int) string
[`(a.Thing).Method` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Thing.Method)
```go
func (Thing).Method(i int) string
```
-- Other-definition --
godef/a/d.go:9:5-10: defined here as var Other Thing
[Other on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Other)
godef/a/d.go:9:5-10: defined here as [`a.Other` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Other)
```go
var Other Thing
```
-- Other-definition-json --
{
"span": {
@ -64,17 +83,23 @@ godef/a/d.go:9:5-10: defined here as var Other Thing
"offset": 91
}
},
"description": "var Other Thing\n[Other on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Other)"
"description": "[`a.Other` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Other)\n\n```go\nvar Other Thing\n```"
}
-- Other-hover --
[`a.Other` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Other)
```go
var Other Thing
[Other on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Other)
```
-- Thing-definition --
godef/a/d.go:5:6-11: defined here as Thing struct {
godef/a/d.go:5:6-11: defined here as [`a.Thing` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Thing)
```go
Thing struct {
Member string //@Member
}
[Thing on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Thing)
```
-- Thing-definition-json --
{
"span": {
@ -90,17 +115,23 @@ godef/a/d.go:5:6-11: defined here as Thing struct {
"offset": 35
}
},
"description": "Thing struct {\n\tMember string //@Member\n}\n[Thing on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Thing)"
"description": "[`a.Thing` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Thing)\n\n```go\nThing struct {\n\tMember string //@Member\n}\n```"
}
-- Thing-hover --
[`a.Thing` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Thing)
```go
Thing struct {
Member string //@Member
}
[Thing on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Thing)
```
-- Things-definition --
godef/a/d.go:11:6-12: defined here as func Things(val []string) []Thing
[Things on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Things)
godef/a/d.go:11:6-12: defined here as [`a.Things` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Things)
```go
func Things(val []string) []Thing
```
-- Things-definition-json --
{
"span": {
@ -116,9 +147,12 @@ godef/a/d.go:11:6-12: defined here as func Things(val []string) []Thing
"offset": 119
}
},
"description": "func Things(val []string) []Thing\n[Things on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Things)"
"description": "[`a.Things` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Things)\n\n```go\nfunc Things(val []string) []Thing\n```"
}
-- Things-hover --
[`a.Things` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Things)
```go
func Things(val []string) []Thing
[Things on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Things)
```

View File

@ -1,5 +1,7 @@
-- switchStringY-definition --
godef/a/f.go:8:9-10: defined here as var y string
godef/a/f.go:8:9-10: defined here as ```go
var y string
```
-- switchStringY-definition-json --
{
"span": {
@ -15,14 +17,17 @@ godef/a/f.go:8:9-10: defined here as var y string
"offset": 77
}
},
"description": "var y string"
"description": "```go\nvar y string\n```"
}
-- switchStringY-hover --
```go
var y string
```
-- switchY-definition --
godef/a/f.go:8:9-10: defined here as var y int
godef/a/f.go:8:9-10: defined here as ```go
var y int
```
-- switchY-definition-json --
{
"span": {
@ -38,9 +43,10 @@ godef/a/f.go:8:9-10: defined here as var y int
"offset": 77
}
},
"description": "var y int"
"description": "```go\nvar y int\n```"
}
-- switchY-hover --
```go
var y int
```

View File

@ -1,5 +1,9 @@
-- PosSum-definition --
godef/a/random.go:16:15-18: defined here as func (*Pos).Sum() int
godef/a/random.go:16:15-18: defined here as [`(a.Pos).Sum` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Pos.Sum)
```go
func (*Pos).Sum() int
```
-- PosSum-definition-json --
{
"span": {
@ -15,15 +19,21 @@ godef/a/random.go:16:15-18: defined here as func (*Pos).Sum() int
"offset": 251
}
},
"description": "func (*Pos).Sum() int"
"description": "[`(a.Pos).Sum` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Pos.Sum)\n\n```go\nfunc (*Pos).Sum() int\n```"
}
-- PosSum-hover --
func (*Pos).Sum() int
[`(a.Pos).Sum` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Pos.Sum)
```go
func (*Pos).Sum() int
```
-- PosX-definition --
godef/a/random.go:13:2-3: defined here as @mark(PosX, "x"),mark(PosY, "y")
godef/a/random.go:13:2-3: defined here as \@mark\(PosX, \"x\"\),mark\(PosY, \"y\"\)
```go
field x int
```
-- PosX-definition-json --
{
"span": {
@ -39,15 +49,19 @@ field x int
"offset": 188
}
},
"description": "@mark(PosX, \"x\"),mark(PosY, \"y\")\nfield x int"
"description": "\\@mark\\(PosX, \\\"x\\\"\\),mark\\(PosY, \\\"y\\\"\\)\n\n```go\nfield x int\n```"
}
-- PosX-hover --
@mark(PosX, "x"),mark(PosY, "y")
field x int
\@mark\(PosX, \"x\"\),mark\(PosY, \"y\"\)
```go
field x int
```
-- RandomParamY-definition --
godef/a/random.go:8:14-15: defined here as var y int
godef/a/random.go:8:14-15: defined here as ```go
var y int
```
-- RandomParamY-definition-json --
{
"span": {
@ -63,9 +77,10 @@ godef/a/random.go:8:14-15: defined here as var y int
"offset": 80
}
},
"description": "var y int"
"description": "```go\nvar y int\n```"
}
-- RandomParamY-hover --
```go
var y int
```

View File

@ -1,31 +1,41 @@
-- A-definition --
godef/a/a.go:7:6-7: defined here as A string //@A
godef/a/a.go:10:6-7: defined here as [`a.A` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#A)
[A on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#A)
```go
A string //@A
```
-- A-definition-json --
{
"span": {
"uri": "file://godef/a/a.go",
"start": {
"line": 7,
"line": 10,
"column": 6,
"offset": 75
"offset": 88
},
"end": {
"line": 7,
"line": 10,
"column": 7,
"offset": 76
"offset": 89
}
},
"description": "A string //@A\n\n[A on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#A)"
"description": "[`a.A` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#A)\n\n```go\nA string //@A\n\n```"
}
-- A-hover --
[`a.A` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#A)
```go
A string //@A
[A on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#A)
```
-- AImport-definition --
godef/b/b.go:5:2-43: defined here as package a ("golang.org/x/tools/internal/lsp/godef/a")
godef/b/b.go:5:2-43: defined here as [`a` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a)
```go
package a ("golang.org/x/tools/internal/lsp/godef/a")
```
-- AImport-definition-json --
{
"span": {
@ -41,36 +51,45 @@ godef/b/b.go:5:2-43: defined here as package a ("golang.org/x/tools/internal/lsp
"offset": 153
}
},
"description": "package a (\"golang.org/x/tools/internal/lsp/godef/a\")"
"description": "[`a` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a)\n\n```go\npackage a (\"golang.org/x/tools/internal/lsp/godef/a\")\n```"
}
-- AImport-hover --
package a ("golang.org/x/tools/internal/lsp/godef/a")
[`a` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a)
```go
package a ("golang.org/x/tools/internal/lsp/godef/a")
```
-- AStuff-definition --
godef/a/a.go:9:6-12: defined here as func a.AStuff()
[AStuff on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#AStuff)
godef/a/a.go:12:6-12: defined here as [`a.AStuff` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#AStuff)
```go
func a.AStuff()
```
-- AStuff-definition-json --
{
"span": {
"uri": "file://godef/a/a.go",
"start": {
"line": 9,
"line": 12,
"column": 6,
"offset": 95
"offset": 108
},
"end": {
"line": 9,
"line": 12,
"column": 12,
"offset": 101
"offset": 114
}
},
"description": "func a.AStuff()\n[AStuff on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#AStuff)"
"description": "[`a.AStuff` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#AStuff)\n\n```go\nfunc a.AStuff()\n```"
}
-- AStuff-hover --
[`a.AStuff` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#AStuff)
```go
func a.AStuff()
[AStuff on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#AStuff)
```
-- PackageFoo-definition --
foo/foo.go:1:1-30:16: defined here as myFoo "golang.org/x/tools/internal/lsp/foo" //@mark(myFoo, "myFoo"),godef("foo", PackageFoo),godef("myFoo", myFoo)
-- PackageFoo-definition-json --
@ -95,12 +114,15 @@ foo/foo.go:1:1-30:16: defined here as myFoo "golang.org/x/tools/internal/lsp/foo
myFoo "golang.org/x/tools/internal/lsp/foo" //@mark(myFoo, "myFoo"),godef("foo", PackageFoo),godef("myFoo", myFoo)
-- S1-definition --
godef/b/b.go:8:6-8: defined here as S1 struct {
godef/b/b.go:8:6-8: defined here as [`b.S1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1)
```go
S1 struct {
F1 int //@mark(S1F1, "F1")
S2 //@godef("S2", S2), mark(S1S2, "S2")
a.A //@godef("A", A)
}
[S1 on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1)
```
-- S1-definition-json --
{
"span": {
@ -116,19 +138,27 @@ godef/b/b.go:8:6-8: defined here as S1 struct {
"offset": 195
}
},
"description": "S1 struct {\n\tF1 int //@mark(S1F1, \"F1\")\n\tS2 //@godef(\"S2\", S2), mark(S1S2, \"S2\")\n\ta.A //@godef(\"A\", A)\n}\n[S1 on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1)"
"description": "[`b.S1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1)\n\n```go\nS1 struct {\n\tF1 int //@mark(S1F1, \"F1\")\n\tS2 //@godef(\"S2\", S2), mark(S1S2, \"S2\")\n\ta.A //@godef(\"A\", A)\n}\n```"
}
-- S1-hover --
[`b.S1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1)
```go
S1 struct {
F1 int //@mark(S1F1, "F1")
S2 //@godef("S2", S2), mark(S1S2, "S2")
a.A //@godef("A", A)
}
[S1 on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1)
```
-- S1F1-definition --
godef/b/b.go:9:2-4: defined here as @mark(S1F1, "F1")
godef/b/b.go:9:2-4: defined here as \@mark\(S1F1, \"F1\"\)
[`(b.S1).F1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1.F1)
```go
field F1 int
```
-- S1F1-definition-json --
{
"span": {
@ -144,16 +174,25 @@ field F1 int
"offset": 214
}
},
"description": "@mark(S1F1, \"F1\")\nfield F1 int"
"description": "\\@mark\\(S1F1, \\\"F1\\\"\\)\n\n[`(b.S1).F1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1.F1)\n\n```go\nfield F1 int\n```"
}
-- S1F1-hover --
@mark(S1F1, "F1")
field F1 int
\@mark\(S1F1, \"F1\"\)
[`(b.S1).F1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1.F1)
```go
field F1 int
```
-- S1S2-definition --
godef/b/b.go:10:2-4: defined here as @godef("S2", S2), mark(S1S2, "S2")
godef/b/b.go:10:2-4: defined here as \@godef\(\"S2\", S2\), mark\(S1S2, \"S2\"\)
[`(b.S1).S2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1.S2)
```go
field S2 S2
```
-- S1S2-definition-json --
{
"span": {
@ -169,20 +208,27 @@ field S2 S2
"offset": 243
}
},
"description": "@godef(\"S2\", S2), mark(S1S2, \"S2\")\nfield S2 S2"
"description": "\\@godef\\(\\\"S2\\\", S2\\), mark\\(S1S2, \\\"S2\\\"\\)\n\n[`(b.S1).S2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1.S2)\n\n```go\nfield S2 S2\n```"
}
-- S1S2-hover --
@godef("S2", S2), mark(S1S2, "S2")
field S2 S2
\@godef\(\"S2\", S2\), mark\(S1S2, \"S2\"\)
[`(b.S1).S2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1.S2)
```go
field S2 S2
```
-- S2-definition --
godef/b/b.go:14:6-8: defined here as S2 struct {
godef/b/b.go:14:6-8: defined here as [`b.S2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S2)
```go
S2 struct {
F1 string //@mark(S2F1, "F1")
F2 int //@mark(S2F2, "F2")
*a.A //@godef("A", A),godef("a",AImport)
}
[S2 on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S2)
```
-- S2-definition-json --
{
"span": {
@ -198,19 +244,27 @@ godef/b/b.go:14:6-8: defined here as S2 struct {
"offset": 322
}
},
"description": "S2 struct {\n\tF1 string //@mark(S2F1, \"F1\")\n\tF2 int //@mark(S2F2, \"F2\")\n\t*a.A //@godef(\"A\", A),godef(\"a\",AImport)\n}\n[S2 on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S2)"
"description": "[`b.S2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S2)\n\n```go\nS2 struct {\n\tF1 string //@mark(S2F1, \"F1\")\n\tF2 int //@mark(S2F2, \"F2\")\n\t*a.A //@godef(\"A\", A),godef(\"a\",AImport)\n}\n```"
}
-- S2-hover --
[`b.S2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S2)
```go
S2 struct {
F1 string //@mark(S2F1, "F1")
F2 int //@mark(S2F2, "F2")
*a.A //@godef("A", A),godef("a",AImport)
}
[S2 on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S2)
```
-- S2F1-definition --
godef/b/b.go:15:2-4: defined here as @mark(S2F1, "F1")
godef/b/b.go:15:2-4: defined here as \@mark\(S2F1, \"F1\"\)
[`(b.S2).F1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S2.F1)
```go
field F1 string
```
-- S2F1-definition-json --
{
"span": {
@ -226,16 +280,25 @@ field F1 string
"offset": 341
}
},
"description": "@mark(S2F1, \"F1\")\nfield F1 string"
"description": "\\@mark\\(S2F1, \\\"F1\\\"\\)\n\n[`(b.S2).F1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S2.F1)\n\n```go\nfield F1 string\n```"
}
-- S2F1-hover --
@mark(S2F1, "F1")
field F1 string
\@mark\(S2F1, \"F1\"\)
[`(b.S2).F1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S2.F1)
```go
field F1 string
```
-- S2F2-definition --
godef/b/b.go:16:2-4: defined here as @mark(S2F2, "F2")
godef/b/b.go:16:2-4: defined here as \@mark\(S2F2, \"F2\"\)
[`(b.S1).F2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1.F2)
```go
field F2 int
```
-- S2F2-definition-json --
{
"span": {
@ -251,13 +314,17 @@ field F2 int
"offset": 374
}
},
"description": "@mark(S2F2, \"F2\")\nfield F2 int"
"description": "\\@mark\\(S2F2, \\\"F2\\\"\\)\n\n[`(b.S1).F2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1.F2)\n\n```go\nfield F2 int\n```"
}
-- S2F2-hover --
@mark(S2F2, "F2")
field F2 int
\@mark\(S2F2, \"F2\"\)
[`(b.S1).F2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1.F2)
```go
field F2 int
```
-- Stuff-definition --
godef/a/a.go:9:6-11: defined here as func a.Stuff()
-- Stuff-definition-json --
@ -281,8 +348,11 @@ godef/a/a.go:9:6-11: defined here as func a.Stuff()
-- Stuff-hover --
func a.Stuff()
-- X-definition --
godef/b/b.go:37:7-8: defined here as const X untyped int = 0
[X on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#X)
godef/b/b.go:37:7-8: defined here as [`b.X` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#X)
```go
const X untyped int = 0
```
-- X-definition-json --
{
"span": {
@ -298,14 +368,21 @@ godef/b/b.go:37:7-8: defined here as const X untyped int = 0
"offset": 796
}
},
"description": "const X untyped int = 0\n[X on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#X)"
"description": "[`b.X` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#X)\n\n```go\nconst X untyped int = 0\n```"
}
-- X-hover --
[`b.X` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#X)
```go
const X untyped int = 0
[X on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#X)
```
-- myFoo-definition --
godef/b/b.go:4:2-7: defined here as package myFoo ("golang.org/x/tools/internal/lsp/foo")
godef/b/b.go:4:2-7: defined here as [`myFoo` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/foo)
```go
package myFoo ("golang.org/x/tools/internal/lsp/foo")
```
-- myFoo-definition-json --
{
"span": {
@ -321,9 +398,12 @@ godef/b/b.go:4:2-7: defined here as package myFoo ("golang.org/x/tools/internal/
"offset": 26
}
},
"description": "package myFoo (\"golang.org/x/tools/internal/lsp/foo\")"
"description": "[`myFoo` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/foo)\n\n```go\npackage myFoo (\"golang.org/x/tools/internal/lsp/foo\")\n```"
}
-- myFoo-hover --
package myFoo ("golang.org/x/tools/internal/lsp/foo")
[`myFoo` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/foo)
```go
package myFoo ("golang.org/x/tools/internal/lsp/foo")
```

View File

@ -1,10 +1,13 @@
-- S1-definition --
godef/b/b.go:8:6-8: defined here as S1 struct {
godef/b/b.go:8:6-8: defined here as [`b.S1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1)
```go
S1 struct {
F1 int //@mark(S1F1, "F1")
S2 //@godef("S2", S2), mark(S1S2, "S2")
a.A //@godef("A", A)
}
[S1 on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1)
```
-- S1-definition-json --
{
"span": {
@ -20,19 +23,27 @@ godef/b/b.go:8:6-8: defined here as S1 struct {
"offset": 195
}
},
"description": "S1 struct {\n\tF1 int //@mark(S1F1, \"F1\")\n\tS2 //@godef(\"S2\", S2), mark(S1S2, \"S2\")\n\ta.A //@godef(\"A\", A)\n}\n[S1 on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1)"
"description": "[`b.S1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1)\n\n```go\nS1 struct {\n\tF1 int //@mark(S1F1, \"F1\")\n\tS2 //@godef(\"S2\", S2), mark(S1S2, \"S2\")\n\ta.A //@godef(\"A\", A)\n}\n```"
}
-- S1-hover --
[`b.S1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1)
```go
S1 struct {
F1 int //@mark(S1F1, "F1")
S2 //@godef("S2", S2), mark(S1S2, "S2")
a.A //@godef("A", A)
}
[S1 on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#S1)
```
-- S1F1-definition --
godef/b/b.go:9:2-4: defined here as @mark(S1F1, "F1")
godef/b/b.go:9:2-4: defined here as \@mark\(S1F1, \"F1\"\)
[`b.F1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#F1)
```go
field F1 int
```
-- S1F1-definition-json --
{
"span": {
@ -48,10 +59,14 @@ field F1 int
"offset": 214
}
},
"description": "@mark(S1F1, \"F1\")\nfield F1 int"
"description": "\\@mark\\(S1F1, \\\"F1\\\"\\)\n\n[`b.F1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#F1)\n\n```go\nfield F1 int\n```"
}
-- S1F1-hover --
@mark(S1F1, "F1")
field F1 int
\@mark\(S1F1, \"F1\"\)
[`b.F1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b#F1)
```go
field F1 int
```

View File

@ -1,6 +1,11 @@
-- Member-definition --
godef/a/d.go:6:2-8: defined here as @Member
godef/a/d.go:6:2-8: defined here as \@Member
[`(a.Thing).Member` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Thing.Member)
```go
field Member string
```
-- Member-definition-json --
{
"span": {
@ -16,16 +21,23 @@ field Member string
"offset": 61
}
},
"description": "@Member\nfield Member string"
"description": "\\@Member\n\n[`(a.Thing).Member` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Thing.Member)\n\n```go\nfield Member string\n```"
}
-- Member-hover --
@Member
field Member string
\@Member
[`(a.Thing).Member` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Thing.Member)
```go
field Member string
```
-- Other-definition --
godef/a/d.go:9:5-10: defined here as var a.Other a.Thing
[Other on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Other)
godef/a/d.go:9:5-10: defined here as [`a.Other` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Other)
```go
var a.Other a.Thing
```
-- Other-definition-json --
{
"span": {
@ -41,17 +53,23 @@ godef/a/d.go:9:5-10: defined here as var a.Other a.Thing
"offset": 91
}
},
"description": "var a.Other a.Thing\n[Other on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Other)"
"description": "[`a.Other` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Other)\n\n```go\nvar a.Other a.Thing\n```"
}
-- Other-hover --
[`a.Other` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Other)
```go
var a.Other a.Thing
[Other on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Other)
```
-- Thing-definition --
godef/a/d.go:5:6-11: defined here as Thing struct {
godef/a/d.go:5:6-11: defined here as [`a.Thing` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Thing)
```go
Thing struct {
Member string //@Member
}
[Thing on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Thing)
```
-- Thing-definition-json --
{
"span": {
@ -67,17 +85,23 @@ godef/a/d.go:5:6-11: defined here as Thing struct {
"offset": 35
}
},
"description": "Thing struct {\n\tMember string //@Member\n}\n[Thing on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Thing)"
"description": "[`a.Thing` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Thing)\n\n```go\nThing struct {\n\tMember string //@Member\n}\n```"
}
-- Thing-hover --
[`a.Thing` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Thing)
```go
Thing struct {
Member string //@Member
}
[Thing on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Thing)
```
-- Things-definition --
godef/a/d.go:11:6-12: defined here as func a.Things(val []string) []a.Thing
[Things on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Things)
godef/a/d.go:11:6-12: defined here as [`a.Things` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Things)
```go
func a.Things(val []string) []a.Thing
```
-- Things-definition-json --
{
"span": {
@ -93,9 +117,12 @@ godef/a/d.go:11:6-12: defined here as func a.Things(val []string) []a.Thing
"offset": 119
}
},
"description": "func a.Things(val []string) []a.Thing\n[Things on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Things)"
"description": "[`a.Things` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Things)\n\n```go\nfunc a.Things(val []string) []a.Thing\n```"
}
-- Things-hover --
[`a.Things` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Things)
```go
func a.Things(val []string) []a.Thing
[Things on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a#Things)
```

View File

@ -1,5 +1,7 @@
-- myUnclosedIf-definition --
godef/broken/unclosedIf.go:7:7-19: defined here as var myUnclosedIf string
godef/broken/unclosedIf.go:7:7-19: defined here as ```go
var myUnclosedIf string
```
-- myUnclosedIf-definition-json --
{
"span": {
@ -15,9 +17,10 @@ godef/broken/unclosedIf.go:7:7-19: defined here as var myUnclosedIf string
"offset": 80
}
},
"description": "var myUnclosedIf string"
"description": "```go\nvar myUnclosedIf string\n```"
}
-- myUnclosedIf-hover --
```go
var myUnclosedIf string
```

View File

@ -11,7 +11,7 @@ FoldingRangesCount = 2
FormatCount = 6
ImportCount = 7
SuggestedFixCount = 1
DefinitionsCount = 38
DefinitionsCount = 39
TypeDefinitionsCount = 2
HighlightsCount = 41
ReferencesCount = 7