x/tools/gopls: show full comments for constant or variable declaration
#48,200 opened on Sep 5, 2021
Repository metrics
- Stars
- (133,883 stars)
- PR merge metrics
- (No merged PRs in 30d)
Description
What version of Go are you using (go version)?
Does this issue reproduce with the latest release?
Yes.
What operating system and processor architecture are you using (go env)?
What did you do?
- Create file x.go in VSCode.
- Hover for
O_TRUNCin following code.
package main
import "os"
func main() {
os.OpenFile("notes.txt", os.O_RDWR|os.O_TRUNC, 0755)
}
What did you expect to see?
Show truncate regular writable file when opened, which tells more than the general comments for all flags.
const O_TRUNC int = 512
os.O_TRUNC on pkg.go.dev
Flags to OpenFile wrapping those of the underlying system. Not all flags may be implemented on a given system.
truncate regular writable file when opened.
What did you see instead?
const O_TRUNC int = 512
os.O_TRUNC on pkg.go.dev
Flags to OpenFile wrapping those of the underlying system. Not all flags may be implemented on a given system.
Appendix:
1. rpc trace log
[Trace - 17:54:02.715 PM] Sending request 'textDocument/hover - (2576)'.
Params: {"textDocument":{"uri":"file:///d%3A/Projects/leetcode/0warn.go"},"position":{"line":21,"character":42}}
[Trace - 17:54:02.719 PM] Received response 'textDocument/hover - (2576)' in 4ms.
Result: {"contents":{"kind":"markdown","value":"```go\nconst os.O_TRUNC int = 512\n```\n\n[`os.O_TRUNC` on pkg.go.dev](https://pkg.go.dev/os?utm_source=gopls#O_TRUNC)\n\nFlags to OpenFile wrapping those of the underlying system\\. Not all\nflags may be implemented on a given system\\.\n"},"range":{"start":{"line":21,"character":39},"end":{"line":21,"character":46}}}
2. possible reason
In following code it seems that currently gopls prefers spec.Doc > decl.Doc > spec.Comment, which means they will not coexist and gopls will lose some key information in hover result.
https://github.com/golang/tools/blob/master/internal/lsp/source/hover.go#L476-L498
func formatVar(node ast.Spec, obj types.Object, decl *ast.GenDecl) *HoverInformation {
...
case *ast.ValueSpec:
// Try to extract the field list of an anonymous struct
if fieldList = extractFieldList(spec.Type); fieldList != nil {
break
}
comment := spec.Doc
if comment == nil {
comment = decl.Doc
}
if comment == nil {
comment = spec.Comment
}
// some evidence from debugger
>>> p spec.Doc
$7 = (go/ast.CommentGroup *) 0x0
>>> p decl.Doc.List.array[0].Text
$9 = "// Flags to OpenFile wrapping those of the underlying system. Not all"
>>> p decl.Doc.List.array[1].Text
$10 = "// flags may be implemented on a given system."
>>> p spec.Comment.List.array[0].Text
$13 = "// truncate regular writable file when opened."
3. inconsistent behaviour
If you hover for O_RDONLY or O_APPEND, gopls will only return the comment of previous line, which doesn't tell useful information and leads to an inconsistent behaviour with other flags.
https://github.com/golang/go/blob/master/src/os/file.go#L71-L84
// Flags to OpenFile wrapping those of the underlying system. Not all
// flags may be implemented on a given system.
const (
// Exactly one of O_RDONLY, O_WRONLY, or O_RDWR must be specified.
O_RDONLY int = syscall.O_RDONLY // open the file read-only.
O_WRONLY int = syscall.O_WRONLY // open the file write-only.
O_RDWR int = syscall.O_RDWR // open the file read-write.
// The remaining values may be or'ed in to control behavior.
O_APPEND int = syscall.O_APPEND // append data to the file when writing.
O_CREATE int = syscall.O_CREAT // create a new file if none exists.
O_EXCL int = syscall.O_EXCL // used with O_CREATE, file must not exist.
O_SYNC int = syscall.O_SYNC // open for synchronous I/O.
O_TRUNC int = syscall.O_TRUNC // truncate regular writable file when opened.
)