internal/lsp/source: provide full documentation of builtin types

This change adds support for full documentation of builtin types in the
hover info, consisting of the type declaration, a link to pkg.go.dev,
and the text of the doc comments in the `builtin` pseudo-package.

Full documentation for builtin functions was already supported.
Removes the special case for the `error` interface, which is not needed
and didn't provide the full documentation anyway, only the type
declaration.

The code has to determine the parent ast.GenDecl (which holds the doc
comments) for the ast.TypeSpec of a builtin type.

Fixes golang/go#50196

Change-Id: I51a054cd7e864300ba2e51152311744b7bcf3e0c
Reviewed-on: https://go-review.googlesource.com/c/tools/+/383614
Trust: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
Trust: Hyang-Ah Hana Kim <hyangah@gmail.com>
This commit is contained in:
fzipp 2022-02-06 14:59:06 +01:00 committed by Robert Findley
parent caecc2b0ac
commit 9b156eeb91
3 changed files with 25 additions and 6 deletions

View File

@ -309,7 +309,8 @@ func HoverIdentifier(ctx context.Context, i *IdentifierInfo) (*HoverInformation,
h.LinkPath = strings.Replace(h.LinkPath, mod, mod+"@"+version, 1)
}
return h, nil
case *types.Builtin:
}
if obj.Parent() == types.Universe {
h.importPath = "builtin"
h.LinkPath = h.importPath
h.LinkAnchor = obj.Name()
@ -520,10 +521,8 @@ func HoverInfo(ctx context.Context, s Snapshot, pkg Package, obj types.Object, p
}
case *ast.TypeSpec:
if obj.Parent() == types.Universe {
if obj.Name() == "error" {
info = &HoverInformation{source: node}
} else {
info = &HoverInformation{source: node.Name} // comments not needed for builtins
if genDecl, ok := fullDecl.(*ast.GenDecl); ok {
info = formatTypeSpec(node, genDecl)
}
}
case *ast.FuncDecl:

View File

@ -217,6 +217,10 @@ func findIdentifier(ctx context.Context, snapshot Snapshot, pkg Package, pgf *Pa
return nil, errors.Errorf("no declaration for %s", result.Name)
}
result.Declaration.node = decl
if typeSpec, ok := decl.(*ast.TypeSpec); ok {
// Find the GenDecl (which has the doc comments) for the TypeSpec.
result.Declaration.fullDecl = findGenDecl(builtin.File, typeSpec)
}
// The builtin package isn't in the dependency graph, so the usual
// utilities won't work here.
@ -314,6 +318,18 @@ func findIdentifier(ctx context.Context, snapshot Snapshot, pkg Package, pgf *Pa
return result, nil
}
// findGenDecl determines the parent ast.GenDecl for a given ast.Spec.
func findGenDecl(f *ast.File, spec ast.Spec) *ast.GenDecl {
for _, decl := range f.Decls {
if genDecl, ok := decl.(*ast.GenDecl); ok {
if genDecl.Pos() <= spec.Pos() && genDecl.End() >= spec.End() {
return genDecl
}
}
}
return nil
}
// fullNode tries to extract the full spec corresponding to obj's declaration.
// If the package was not parsed in full, the declaration file will be
// re-parsed to ensure it has complete syntax.

View File

@ -164,8 +164,12 @@ func(t Type, size ...IntegerType) Type
The make built\-in function allocates and initializes an object of type slice, map, or chan \(only\)\.
-- string-hoverdef --
```go
string
type string string
```
[`string` on pkg.go.dev](https://pkg.go.dev/builtin?utm_source=gopls#string)
string is the set of all strings of 8\-bit bytes, conventionally but not necessarily representing UTF\-8\-encoded text\.
-- typesImport-hoverdef --
```go
package types ("go/types")