internal/lsp: add inlay hints for composite literal names
For golang/go#52343.
For golang/vscode-go#1631.
Change-Id: I8fba5ddf0bd25ba0fc20f3305ce13868f426087c
Reviewed-on: https://go-review.googlesource.com/c/tools/+/411102
Run-TryBot: Jamal Carvalho <jamal@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Suzy Mueller <suzmue@golang.org>
gopls-CI: kokoro <noreply+kokoro@google.com>
diff --git a/internal/lsp/source/inlay_hint.go b/internal/lsp/source/inlay_hint.go
index 95df237..406e4ae 100644
--- a/internal/lsp/source/inlay_hint.go
+++ b/internal/lsp/source/inlay_hint.go
@@ -46,6 +46,8 @@
hints = append(hints, rangeVariableTypes(n, tmap, info, &q)...)
case *ast.GenDecl:
hints = append(hints, constantValues(n, tmap, info)...)
+ case *ast.CompositeLit:
+ hints = append(hints, compositeLiterals(n, tmap, info)...)
}
return true
})
@@ -179,6 +181,37 @@
return hints
}
+func compositeLiterals(node *ast.CompositeLit, tmap *lsppos.TokenMapper, info *types.Info) []protocol.InlayHint {
+ typ := info.TypeOf(node)
+ if typ == nil {
+ return nil
+ }
+ strct, ok := typ.Underlying().(*types.Struct)
+ if !ok {
+ return nil
+ }
+
+ var hints []protocol.InlayHint
+ for i, v := range node.Elts {
+ if _, ok := v.(*ast.KeyValueExpr); !ok {
+ start, ok := tmap.Position(v.Pos())
+ if !ok {
+ continue
+ }
+ if i > strct.NumFields()-1 {
+ break
+ }
+ hints = append(hints, protocol.InlayHint{
+ Position: &start,
+ Label: buildLabel(strct.Field(i).Name() + ":"),
+ Kind: protocol.Parameter,
+ PaddingRight: true,
+ })
+ }
+ }
+ return hints
+}
+
func buildLabel(s string) []protocol.InlayHintLabelPart {
label := protocol.InlayHintLabelPart{
Value: s,
diff --git a/internal/lsp/testdata/inlay_hint/composite_literals.go b/internal/lsp/testdata/inlay_hint/composite_literals.go
new file mode 100644
index 0000000..7eeed03
--- /dev/null
+++ b/internal/lsp/testdata/inlay_hint/composite_literals.go
@@ -0,0 +1,15 @@
+package inlayHint //@inlayHint("package")
+
+import "fmt"
+
+func fieldNames() {
+ for _, c := range []struct {
+ in, want string
+ }{
+ {"Hello, world", "dlrow ,olleH"},
+ {"Hello, 世界", "界世 ,olleH"},
+ {"", ""},
+ } {
+ fmt.Println(c.in == c.want)
+ }
+}
diff --git a/internal/lsp/testdata/inlay_hint/composite_literals.go.golden b/internal/lsp/testdata/inlay_hint/composite_literals.go.golden
new file mode 100644
index 0000000..efa87b0
--- /dev/null
+++ b/internal/lsp/testdata/inlay_hint/composite_literals.go.golden
@@ -0,0 +1,17 @@
+-- inlayHint --
+package inlayHint //@inlayHint("package")
+
+import "fmt"
+
+func fieldNames() {
+ for _<int>, c<struct{in string; want strin...> := range []struct {
+ in, want string
+ }{
+ {<in:>"Hello, world", <want:>"dlrow ,olleH"},
+ {<in:>"Hello, 世界", <want:>"界世 ,olleH"},
+ {<in:>"", <want:>""},
+ } {
+ fmt.Println(<a...:>c.in == c.want)
+ }
+}
+