Skip to content

Commit 7590aeb

Browse files
committed
gopls/internal/lsp/source: improve method hover
This change causes (*pkg.T).F to be rendered as "(t *pkg.T) F", in other words, using declaration syntax, with the receiver name, if any (as it may be mentioned by the doc comment), instead of go/types syntax (which is a "method expression"). Fixes golang/go#62190 Change-Id: I3966449e7141a28ba84e097b868a92a41c21df52 Reviewed-on: https://go-review.googlesource.com/c/tools/+/546735 Auto-Submit: Alan Donovan <[email protected]> Reviewed-by: Robert Findley <[email protected]> Commit-Queue: Alan Donovan <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
1 parent 8e821ab commit 7590aeb

File tree

6 files changed

+55
-13
lines changed

6 files changed

+55
-13
lines changed

gopls/internal/lsp/source/hover.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package source
66

77
import (
8+
"bytes"
89
"context"
910
"encoding/json"
1011
"fmt"
@@ -220,6 +221,8 @@ func hover(ctx context.Context, snapshot *cache.Snapshot, fh file.Handle, pp pro
220221
//
221222
// TODO(rfindley): this should use FormatVarType to get proper qualification
222223
// of identifiers, and we should revisit the formatting of method set.
224+
//
225+
// TODO(adonovan): this logic belongs in objectString.
223226
_, isTypeName := obj.(*types.TypeName)
224227
_, isTypeParam := obj.Type().(*typeparams.TypeParam)
225228
if isTypeName && !isTypeParam {
@@ -695,11 +698,50 @@ func inferredSignatureString(obj types.Object, qf types.Qualifier, inferred *typ
695698
// It handles adding more information to the object string.
696699
// If spec is non-nil, it may be used to format additional declaration
697700
// syntax, and file must be the token.File describing its positions.
701+
//
702+
// Precondition: obj is not a built-in function or method.
698703
func objectString(obj types.Object, qf types.Qualifier, declPos token.Pos, file *token.File, spec ast.Spec) string {
699704
str := types.ObjectString(obj, qf)
700705

701706
switch obj := obj.(type) {
707+
case *types.Func:
708+
// We fork ObjectString to improve its rendering of methods:
709+
// specifically, we show the receiver name,
710+
// and replace the period in (T).f by a space (#62190).
711+
712+
sig := obj.Type().(*types.Signature)
713+
714+
var buf bytes.Buffer
715+
buf.WriteString("func ")
716+
if recv := sig.Recv(); recv != nil {
717+
buf.WriteByte('(')
718+
if _, ok := recv.Type().(*types.Interface); ok {
719+
// gcimporter creates abstract methods of
720+
// named interfaces using the interface type
721+
// (not the named type) as the receiver.
722+
// Don't print it in full.
723+
buf.WriteString("interface")
724+
} else {
725+
// Show receiver name (go/types does not).
726+
name := recv.Name()
727+
if name != "" && name != "_" {
728+
buf.WriteString(name)
729+
buf.WriteString(" ")
730+
}
731+
types.WriteType(&buf, recv.Type(), qf)
732+
}
733+
buf.WriteByte(')')
734+
buf.WriteByte(' ') // space (go/types uses a period)
735+
} else if s := qf(obj.Pkg()); s != "" {
736+
buf.WriteString(s)
737+
buf.WriteString(".")
738+
}
739+
buf.WriteString(obj.Name())
740+
types.WriteSignature(&buf, sig, qf)
741+
str = buf.String()
742+
702743
case *types.Const:
744+
// Show value of a constant.
703745
var (
704746
declaration = obj.Val().String() // default formatted declaration
705747
comment = "" // if non-empty, a clarifying comment

gopls/internal/test/marker/testdata/definition/embed.txt

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ type R struct {
2727
Field2 int //@loc(RField2, "Field2")
2828
}
2929

30-
func (_ R) Hey() {} //@loc(RHey, "Hey")
30+
func (r R) Hey() {} //@loc(RHey, "Hey")
3131

3232
type H interface { //@loc(H, "H")
3333
Goodbye() //@loc(HGoodbye, "Goodbye")
@@ -111,7 +111,7 @@ var _ = S1{ //@def("S1", S1),hover("S1", "S1", S1)
111111

112112
-- @AHi --
113113
```go
114-
func (a.A).Hi()
114+
func (a.A) Hi()
115115
```
116116

117117
[`(a.A).Hi` on pkg.go.dev](https://pkg.go.dev/mod.com/a#A.Hi)
@@ -126,7 +126,7 @@ field F int
126126
[`(b.Embed).F` on pkg.go.dev](https://pkg.go.dev/mod.com/b#Embed.F)
127127
-- @HGoodbye --
128128
```go
129-
func (a.H).Goodbye()
129+
func (a.H) Goodbye()
130130
```
131131

132132
@loc(HGoodbye, "Goodbye")
@@ -135,7 +135,7 @@ func (a.H).Goodbye()
135135
[`(a.H).Goodbye` on pkg.go.dev](https://pkg.go.dev/mod.com/a#H.Goodbye)
136136
-- @IB --
137137
```go
138-
func (a.I).B()
138+
func (a.I) B()
139139
```
140140

141141
@loc(IB, "B")
@@ -144,7 +144,7 @@ func (a.I).B()
144144
[`(a.I).B` on pkg.go.dev](https://pkg.go.dev/mod.com/a#I.B)
145145
-- @JHello --
146146
```go
147-
func (a.J).Hello()
147+
func (a.J) Hello()
148148
```
149149

150150
@loc(JHello, "Hello")
@@ -153,7 +153,7 @@ func (a.J).Hello()
153153
[`(a.J).Hello` on pkg.go.dev](https://pkg.go.dev/mod.com/a#J.Hello)
154154
-- @M --
155155
```go
156-
func (embed).M()
156+
func (embed) M()
157157
```
158158

159159
[`(b.Embed).M` on pkg.go.dev](https://pkg.go.dev/mod.com/b#Embed.M)
@@ -168,7 +168,7 @@ field Field2 int
168168
[`(a.R).Field2` on pkg.go.dev](https://pkg.go.dev/mod.com/a#R.Field2)
169169
-- @RHey --
170170
```go
171-
func (a.R).Hey()
171+
func (r a.R) Hey()
172172
```
173173

174174
[`(a.R).Hey` on pkg.go.dev](https://pkg.go.dev/mod.com/a#R.Hey)

gopls/internal/test/marker/testdata/definition/misc.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ type J interface {
188188
[`a.J` on pkg.go.dev](https://pkg.go.dev/mod.com#J)
189189
-- @hoverSum --
190190
```go
191-
func (*Pos).Sum() int
191+
func (p *Pos) Sum() int
192192
```
193193

194194
[`(a.Pos).Sum` on pkg.go.dev](https://pkg.go.dev/mod.com#Pos.Sum)

gopls/internal/test/marker/testdata/hover/godef.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ func (NextThing).another() string
136136
[`a.NextThing` on pkg.go.dev](https://pkg.go.dev/godef.test/a#NextThing)
137137
-- @eth --
138138
```go
139-
func (Thing).Method(i int) string
139+
func (t Thing) Method(i int) string
140140
```
141141

142142
[`(a.Thing).Method` on pkg.go.dev](https://pkg.go.dev/godef.test/a#Thing.Method)
@@ -343,7 +343,7 @@ field str string
343343
nested string
344344
-- @openMethod --
345345
```go
346-
func (interface).open() error
346+
func (interface) open() error
347347
```
348348

349349
open method comment

gopls/internal/test/marker/testdata/hover/linkable_generics.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ TODO(rfindley): should it? We should probably link to the type.
9797
[`generic.GT` on pkg.go.dev](https://pkg.go.dev/mod.com/generic#GT)
9898
-- @M --
9999
```go
100-
func (GT[P]).M(p P)
100+
func (GT[P]) M(p P)
101101
```
102102

103103
[`(generic.GT).M` on pkg.go.dev](https://pkg.go.dev/mod.com/generic#GT.M)

gopls/internal/test/marker/testdata/hover/std.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ func _() {
4646
}
4747
-- @hoverLock --
4848
```go
49-
func (*sync.Mutex).Lock()
49+
func (m *sync.Mutex) Lock()
5050
```
5151

5252
Lock locks m.
@@ -55,7 +55,7 @@ Lock locks m.
5555
[`(sync.Mutex).Lock` on pkg.go.dev](https://pkg.go.dev/sync#Mutex.Lock)
5656
-- @hoverName --
5757
```go
58-
func (*types.object).Name() string
58+
func (obj *types.object) Name() string
5959
```
6060

6161
Name returns the object's (package-local, unqualified) name.

0 commit comments

Comments
 (0)