Open
Description
What version of Go are you using (go version
)?
➜ / go version go version go1.17 linux/amd64 ➜ / gopls version golang.org/x/tools/gopls v0.7.1 golang.org/x/tools/gopls@v0.7.1 h1:Mh3Z8Xcoq3Zy7ksSlwDV/nzQSbjFf06A+L+F8YHq55U=
Does this issue reproduce with the latest release?
Yes.
What operating system and processor architecture are you using (go env
)?
go env
Output
➜ / go env GO111MODULE="" GOARCH="amd64" GOBIN="" GOCACHE="/root/.cache/go-build" GOENV="/root/.config/go/env" GOEXE="" GOEXPERIMENT="" GOFLAGS="" GOHOSTARCH="amd64" GOHOSTOS="linux" GOINSECURE="" GOMODCACHE="/home/katsu/go/pkg/mod" GONOPROXY="" GONOSUMDB="" GOOS="linux" GOPATH="/home/katsu/go" GOPRIVATE="" GOPROXY="https://goproxy.cn" GOROOT="/usr/local/go" GOSUMDB="sum.golang.org" GOTMPDIR="" GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64" GOVCS="" GOVERSION="go1.17" GCCGO="gccgo" AR="ar" CC="gcc" CXX="g++" CGO_ENABLED="1" GOMOD="/dev/null" CGO_CFLAGS="-g -O2" CGO_CPPFLAGS="" CGO_CXXFLAGS="-g -O2" CGO_FFLAGS="-g -O2" CGO_LDFLAGS="-g -O2" PKG_CONFIG="pkg-config" GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build1623744664=/tmp/go-build -gno-record-gcc-switches"
What did you do?
- Create file x.go in VSCode.
- Hover for
O_TRUNC
in 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.
)