mirror of https://github.com/golang/go.git
internal/lsp: add inlay hints for composite literal types
Add inlay hints for composite literal types. This will show type
information for composite literals with no explicit types.
Example:
<struct {in, want string}>{"hello", "goodbye"}
For golang/go#52343
Change-Id: Ia1f03b82669387c864353b8033940759fa1128e7
Reviewed-on: https://go-review.googlesource.com/c/tools/+/411905
gopls-CI: kokoro <noreply+kokoro@google.com>
Run-TryBot: Suzy Mueller <suzmue@golang.org>
Reviewed-by: Jamal Carvalho <jamal@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
parent
e9870152b0
commit
1e14d994d8
|
|
@ -47,7 +47,7 @@ func InlayHint(ctx context.Context, snapshot Snapshot, fh FileHandle, _ protocol
|
|||
case *ast.GenDecl:
|
||||
hints = append(hints, constantValues(n, tmap, info)...)
|
||||
case *ast.CompositeLit:
|
||||
hints = append(hints, compositeLiterals(n, tmap, info)...)
|
||||
hints = append(hints, compositeLiterals(n, tmap, info, &q)...)
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
|
@ -181,17 +181,35 @@ func constantValues(node *ast.GenDecl, tmap *lsppos.TokenMapper, info *types.Inf
|
|||
return hints
|
||||
}
|
||||
|
||||
func compositeLiterals(node *ast.CompositeLit, tmap *lsppos.TokenMapper, info *types.Info) []protocol.InlayHint {
|
||||
func compositeLiterals(node *ast.CompositeLit, tmap *lsppos.TokenMapper, info *types.Info, q *types.Qualifier) []protocol.InlayHint {
|
||||
typ := info.TypeOf(node)
|
||||
if typ == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
prefix := ""
|
||||
if t, ok := typ.(*types.Pointer); ok {
|
||||
typ = t.Elem()
|
||||
prefix = "&"
|
||||
}
|
||||
|
||||
strct, ok := typ.Underlying().(*types.Struct)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
var hints []protocol.InlayHint
|
||||
if node.Type == nil {
|
||||
// The type for this struct is implicit, add an inlay hint.
|
||||
if start, ok := tmap.Position(node.Lbrace); ok {
|
||||
hints = append(hints, protocol.InlayHint{
|
||||
Position: &start,
|
||||
Label: buildLabel(fmt.Sprintf("%s%s", prefix, types.TypeString(typ, *q))),
|
||||
Kind: protocol.Type,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
for i, v := range node.Elts {
|
||||
if _, ok := v.(*ast.KeyValueExpr); !ok {
|
||||
start, ok := tmap.Position(v.Pos())
|
||||
|
|
@ -216,7 +234,7 @@ func buildLabel(s string) []protocol.InlayHintLabelPart {
|
|||
label := protocol.InlayHintLabelPart{
|
||||
Value: s,
|
||||
}
|
||||
if len(s) > maxLabelLength {
|
||||
if len(s) > maxLabelLength+len("...") {
|
||||
label.Value = s[:maxLabelLength] + "..."
|
||||
label.Tooltip = s
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,19 @@ func fieldNames() {
|
|||
for _, c := range []struct {
|
||||
in, want string
|
||||
}{
|
||||
{"Hello, world", "dlrow ,olleH"},
|
||||
struct{ in, want string }{"Hello, world", "dlrow ,olleH"},
|
||||
{"Hello, 世界", "界世 ,olleH"},
|
||||
{"", ""},
|
||||
} {
|
||||
fmt.Println(c.in == c.want)
|
||||
}
|
||||
}
|
||||
|
||||
func fieldNamesPointers() {
|
||||
for _, c := range []*struct {
|
||||
in, want string
|
||||
}{
|
||||
&struct{ in, want string }{"Hello, world", "dlrow ,olleH"},
|
||||
{"Hello, 世界", "界世 ,olleH"},
|
||||
{"", ""},
|
||||
} {
|
||||
|
|
|
|||
|
|
@ -4,12 +4,24 @@ package inlayHint //@inlayHint("package")
|
|||
import "fmt"
|
||||
|
||||
func fieldNames() {
|
||||
for _< int>, c< struct{in string; want strin...> := range []struct {
|
||||
for _< int>, c< struct{in string; want string}> := range []struct {
|
||||
in, want string
|
||||
}{
|
||||
{<in: >"Hello, world", <want: >"dlrow ,olleH"},
|
||||
{<in: >"Hello, 世界", <want: >"界世 ,olleH"},
|
||||
{<in: >"", <want: >""},
|
||||
struct{ in, want string }{<in: >"Hello, world", <want: >"dlrow ,olleH"},
|
||||
<struct{in string; want string}>{<in: >"Hello, 世界", <want: >"界世 ,olleH"},
|
||||
<struct{in string; want string}>{<in: >"", <want: >""},
|
||||
} {
|
||||
fmt.Println(<a...: >c.in == c.want)
|
||||
}
|
||||
}
|
||||
|
||||
func fieldNamesPointers() {
|
||||
for _< int>, c< *struct{in string; want string}> := range []*struct {
|
||||
in, want string
|
||||
}{
|
||||
&struct{ in, want string }{<in: >"Hello, world", <want: >"dlrow ,olleH"},
|
||||
<&struct{in string; want string}>{<in: >"Hello, 世界", <want: >"界世 ,olleH"},
|
||||
<&struct{in string; want string}>{<in: >"", <want: >""},
|
||||
} {
|
||||
fmt.Println(<a...: >c.in == c.want)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue