-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
internal/lsp: support textDocument/inlayHint for parameter names
This change implements support for textDocument/inlayHint and adds inlay hints for parameter names. For golang/go#52343. For golang/vscode-go#1631. Change-Id: I3f989838b86cef4fd2b4076cb6340010fff7c24c Reviewed-on: https://go-review.googlesource.com/c/tools/+/411094 gopls-CI: kokoro <noreply+kokoro@google.com> Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com> Reviewed-by: Suzy Mueller <suzmue@golang.org> Run-TryBot: Jamal Carvalho <jamal@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org>
- Loading branch information
Showing
5 changed files
with
205 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// Copyright 2022 The Go Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
package lsp | ||
|
||
import ( | ||
"context" | ||
|
||
"golang.org/x/tools/internal/lsp/protocol" | ||
"golang.org/x/tools/internal/lsp/source" | ||
) | ||
|
||
func (s *Server) inlayHint(ctx context.Context, params *protocol.InlayHintParams) ([]protocol.InlayHint, error) { | ||
snapshot, fh, ok, release, err := s.beginFileRequest(ctx, params.TextDocument.URI, source.Go) | ||
defer release() | ||
if !ok { | ||
return nil, err | ||
} | ||
return source.InlayHint(ctx, snapshot, fh, params.ViewPort) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
// Copyright 2022 The Go Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
package source | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"go/ast" | ||
"go/types" | ||
|
||
"golang.org/x/tools/internal/event" | ||
"golang.org/x/tools/internal/lsp/lsppos" | ||
"golang.org/x/tools/internal/lsp/protocol" | ||
) | ||
|
||
const ( | ||
maxLabelLength = 28 | ||
) | ||
|
||
func InlayHint(ctx context.Context, snapshot Snapshot, fh FileHandle, _ protocol.Range) ([]protocol.InlayHint, error) { | ||
ctx, done := event.Start(ctx, "source.InlayHint") | ||
defer done() | ||
|
||
pkg, pgf, err := GetParsedFile(ctx, snapshot, fh, NarrowestPackage) | ||
if err != nil { | ||
return nil, fmt.Errorf("getting file for InlayHint: %w", err) | ||
} | ||
|
||
tmap := lsppos.NewTokenMapper(pgf.Src, pgf.Tok) | ||
info := pkg.GetTypesInfo() | ||
|
||
var hints []protocol.InlayHint | ||
ast.Inspect(pgf.File, func(node ast.Node) bool { | ||
switch n := node.(type) { | ||
case *ast.CallExpr: | ||
hints = append(hints, parameterNames(n, tmap, info)...) | ||
} | ||
return true | ||
}) | ||
return hints, nil | ||
} | ||
|
||
func parameterNames(node *ast.CallExpr, tmap *lsppos.TokenMapper, info *types.Info) []protocol.InlayHint { | ||
signature, ok := info.TypeOf(node.Fun).(*types.Signature) | ||
if !ok { | ||
return nil | ||
} | ||
|
||
var hints []protocol.InlayHint | ||
for i, v := range node.Args { | ||
start, ok := tmap.Position(v.Pos()) | ||
if !ok { | ||
continue | ||
} | ||
params := signature.Params() | ||
// When a function has variadic params, we skip args after | ||
// params.Len(). | ||
if i > params.Len()-1 { | ||
break | ||
} | ||
value := params.At(i).Name() | ||
// param.Name is empty for built-ins like append | ||
if value == "" { | ||
continue | ||
} | ||
if signature.Variadic() && i == params.Len()-1 { | ||
value = value + "..." | ||
} | ||
hints = append(hints, protocol.InlayHint{ | ||
Position: &start, | ||
Label: buildLabel(value + ":"), | ||
Kind: protocol.Parameter, | ||
PaddingRight: true, | ||
}) | ||
} | ||
return hints | ||
} | ||
|
||
func buildLabel(s string) []protocol.InlayHintLabelPart { | ||
label := protocol.InlayHintLabelPart{ | ||
Value: s, | ||
} | ||
if len(s) > maxLabelLength { | ||
label.Value = s[:maxLabelLength] + "..." | ||
label.Tooltip = s | ||
} | ||
return []protocol.InlayHintLabelPart{label} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package inlayHint //@inlayHint("package") | ||
|
||
import "fmt" | ||
|
||
func hello(name string) string { | ||
return "Hello " + name | ||
} | ||
|
||
func helloWorld() string { | ||
return hello("World") | ||
} | ||
|
||
type foo struct{} | ||
|
||
func (*foo) bar(baz string, qux int) int { | ||
if baz != "" { | ||
return qux + 1 | ||
} | ||
return qux | ||
} | ||
|
||
func kase(foo int, bar bool, baz ...string) { | ||
fmt.Println(foo, bar, baz) | ||
} | ||
|
||
func kipp(foo string, bar, baz string) { | ||
fmt.Println(foo, bar, baz) | ||
} | ||
|
||
func plex(foo, bar string, baz string) { | ||
fmt.Println(foo, bar, baz) | ||
} | ||
|
||
func tars(foo string, bar, baz string) { | ||
fmt.Println(foo, bar, baz) | ||
} | ||
|
||
func foobar() { | ||
var x foo | ||
x.bar("", 1) | ||
kase(0, true, "c", "d", "e") | ||
kipp("a", "b", "c") | ||
plex("a", "b", "c") | ||
tars("a", "b", "c") | ||
} |
47 changes: 47 additions & 0 deletions
47
internal/lsp/testdata/inlay_hint/parameter_names.go.golden
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
-- inlayHint -- | ||
package inlayHint //@inlayHint("package") | ||
|
||
import "fmt" | ||
|
||
func hello(name string) string { | ||
return "Hello " + name | ||
} | ||
|
||
func helloWorld() string { | ||
return hello(<name:>"World") | ||
} | ||
|
||
type foo struct{} | ||
|
||
func (*foo) bar(baz string, qux int) int { | ||
if baz != "" { | ||
return qux + 1 | ||
} | ||
return qux | ||
} | ||
|
||
func kase(foo int, bar bool, baz ...string) { | ||
fmt.Println(<a...:>foo, bar, baz) | ||
} | ||
|
||
func kipp(foo string, bar, baz string) { | ||
fmt.Println(<a...:>foo, bar, baz) | ||
} | ||
|
||
func plex(foo, bar string, baz string) { | ||
fmt.Println(<a...:>foo, bar, baz) | ||
} | ||
|
||
func tars(foo string, bar, baz string) { | ||
fmt.Println(<a...:>foo, bar, baz) | ||
} | ||
|
||
func foobar() { | ||
var x foo | ||
x.bar(<baz:>"", <qux:>1) | ||
kase(<foo:>0, <bar:>true, <baz...:>"c", "d", "e") | ||
kipp(<foo:>"a", <bar:>"b", <baz:>"c") | ||
plex(<foo:>"a", <bar:>"b", <baz:>"c") | ||
tars(<foo:>"a", <bar:>"b", <baz:>"c") | ||
} | ||
|