internal/lsp: add inlay hints for inferred type params
This will show inferred type information for generic function
call expressions.
Example:
SumNumbers<[string, int64]>(ints)
For golang/go#52343
Change-Id: I05595f236626e8fb3666af5160611e074e8265a4
Reviewed-on: https://go-review.googlesource.com/c/tools/+/412994
Reviewed-by: Suzy Mueller <suzmue@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
gopls-CI: kokoro <noreply+kokoro@google.com>
Run-TryBot: Jamal Carvalho <jamal@golang.org>
diff --git a/internal/lsp/source/inlay_hint.go b/internal/lsp/source/inlay_hint.go
index af9e715..8fe46b2 100644
--- a/internal/lsp/source/inlay_hint.go
+++ b/internal/lsp/source/inlay_hint.go
@@ -16,6 +16,7 @@
"golang.org/x/tools/internal/event"
"golang.org/x/tools/internal/lsp/lsppos"
"golang.org/x/tools/internal/lsp/protocol"
+ "golang.org/x/tools/internal/typeparams"
)
const (
@@ -40,6 +41,7 @@
switch n := node.(type) {
case *ast.CallExpr:
hints = append(hints, parameterNames(n, tmap, info)...)
+ hints = append(hints, funcTypeParams(n, tmap, info)...)
case *ast.AssignStmt:
hints = append(hints, assignVariableTypes(n, tmap, info, &q)...)
case *ast.RangeStmt:
@@ -90,6 +92,33 @@
return hints
}
+func funcTypeParams(node *ast.CallExpr, tmap *lsppos.TokenMapper, info *types.Info) []protocol.InlayHint {
+ id, ok := node.Fun.(*ast.Ident)
+ if !ok {
+ return nil
+ }
+ inst := typeparams.GetInstances(info)[id]
+ if inst.TypeArgs == nil {
+ return nil
+ }
+ start, ok := tmap.Position(id.End())
+ if !ok {
+ return nil
+ }
+ var args []string
+ for i := 0; i < inst.TypeArgs.Len(); i++ {
+ args = append(args, inst.TypeArgs.At(i).String())
+ }
+ if len(args) == 0 {
+ return nil
+ }
+ return []protocol.InlayHint{{
+ Position: &start,
+ Label: buildLabel("[" + strings.Join(args, ", ") + "]"),
+ Kind: protocol.Type,
+ }}
+}
+
func assignVariableTypes(node *ast.AssignStmt, tmap *lsppos.TokenMapper, info *types.Info, q *types.Qualifier) []protocol.InlayHint {
if node.Tok != token.DEFINE {
return nil
diff --git a/internal/lsp/testdata/inlay_hint/type_params.go b/internal/lsp/testdata/inlay_hint/type_params.go
new file mode 100644
index 0000000..3a3c7e5
--- /dev/null
+++ b/internal/lsp/testdata/inlay_hint/type_params.go
@@ -0,0 +1,45 @@
+//go:build go1.18
+// +build go1.18
+
+package inlayHint //@inlayHint("package")
+
+func main() {
+ ints := map[string]int64{
+ "first": 34,
+ "second": 12,
+ }
+
+ floats := map[string]float64{
+ "first": 35.98,
+ "second": 26.99,
+ }
+
+ SumIntsOrFloats[string, int64](ints)
+ SumIntsOrFloats[string, float64](floats)
+
+ SumIntsOrFloats(ints)
+ SumIntsOrFloats(floats)
+
+ SumNumbers(ints)
+ SumNumbers(floats)
+}
+
+type Number interface {
+ int64 | float64
+}
+
+func SumIntsOrFloats[K comparable, V int64 | float64](m map[K]V) V {
+ var s V
+ for _, v := range m {
+ s += v
+ }
+ return s
+}
+
+func SumNumbers[K comparable, V Number](m map[K]V) V {
+ var s V
+ for _, v := range m {
+ s += v
+ }
+ return s
+}
diff --git a/internal/lsp/testdata/inlay_hint/type_params.go.golden b/internal/lsp/testdata/inlay_hint/type_params.go.golden
new file mode 100644
index 0000000..4819963
--- /dev/null
+++ b/internal/lsp/testdata/inlay_hint/type_params.go.golden
@@ -0,0 +1,47 @@
+-- inlayHint --
+//go:build go1.18
+// +build go1.18
+
+package inlayHint //@inlayHint("package")
+
+func main() {
+ ints< map[string]int64> := map[string]int64{
+ "first": 34,
+ "second": 12,
+ }
+
+ floats< map[string]float64> := map[string]float64{
+ "first": 35.98,
+ "second": 26.99,
+ }
+
+ SumIntsOrFloats[string, int64](<m: >ints)
+ SumIntsOrFloats[string, float64](<m: >floats)
+
+ SumIntsOrFloats<[string, int64]>(<m: >ints)
+ SumIntsOrFloats<[string, float64]>(<m: >floats)
+
+ SumNumbers<[string, int64]>(<m: >ints)
+ SumNumbers<[string, float64]>(<m: >floats)
+}
+
+type Number interface {
+ int64 | float64
+}
+
+func SumIntsOrFloats[K comparable, V int64 | float64](m map[K]V) V {
+ var s V
+ for _< K>, v< V> := range m {
+ s += v
+ }
+ return s
+}
+
+func SumNumbers[K comparable, V Number](m map[K]V) V {
+ var s V
+ for _< K>, v< V> := range m {
+ s += v
+ }
+ return s
+}
+
diff --git a/internal/lsp/testdata/summary_go1.18.txt.golden b/internal/lsp/testdata/summary_go1.18.txt.golden
index 28a2672..7e8da12 100644
--- a/internal/lsp/testdata/summary_go1.18.txt.golden
+++ b/internal/lsp/testdata/summary_go1.18.txt.golden
@@ -19,7 +19,7 @@
DefinitionsCount = 108
TypeDefinitionsCount = 18
HighlightsCount = 69
-InlayHintsCount = 4
+InlayHintsCount = 5
ReferencesCount = 27
RenamesCount = 48
PrepareRenamesCount = 7