Skip to content

Commit 5bad459

Browse files
muirdmstamblerre
authored andcommitted
internal/lsp: fix godef for embedded type aliases
In type myAlias = someType type _ struct { myAlias } Previously running "definition" on the "myAlias" field would take you to the definition of "someType" instead of "myAlias". This is because we were using the field's (*types.Var).Type() which has already forgotten it is an alias. Fix by instead looking up the field name ident in types.Info.Uses which yields the *types.TypeName (for the type alias). Fixes golang/go#42254. Change-Id: Idbbd0c49ba6f701f52568b3ab1143d8e24037c69 Reviewed-on: https://go-review.googlesource.com/c/tools/+/272186 Run-TryBot: Muir Manders <muir@mnd.rs> gopls-CI: kokoro <noreply+kokoro@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Rebecca Stambler <rstambler@golang.org> Reviewed-by: Muir Manders <muir@mnd.rs> Trust: Rebecca Stambler <rstambler@golang.org> Trust: Robert Findley <rfindley@google.com>
1 parent 45586dd commit 5bad459

File tree

6 files changed

+104
-82
lines changed

6 files changed

+104
-82
lines changed

internal/lsp/source/identifier.go

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -157,14 +157,6 @@ func findIdentifier(ctx context.Context, snapshot Snapshot, pkg Package, file *a
157157
enclosing: searchForEnclosing(pkg.GetTypesInfo(), path),
158158
}
159159

160-
var wasEmbeddedField bool
161-
for _, n := range path[1:] {
162-
if field, ok := n.(*ast.Field); ok {
163-
wasEmbeddedField = len(field.Names) == 0
164-
break
165-
}
166-
}
167-
168160
result.Name = result.ident.Name
169161
var err error
170162
if result.MappedRange, err = posToMappedRange(snapshot, pkg, result.ident.Pos(), result.ident.End()); err != nil {
@@ -253,13 +245,12 @@ func findIdentifier(ctx context.Context, snapshot Snapshot, pkg Package, file *a
253245
}
254246
}
255247

256-
if wasEmbeddedField {
257-
// The original position was on the embedded field declaration, so we
258-
// try to dig out the type and jump to that instead.
259-
if v, ok := result.Declaration.obj.(*types.Var); ok {
260-
if typObj := typeToObject(v.Type()); typObj != nil {
261-
result.Declaration.obj = typObj
262-
}
248+
// If the original position was an embedded field, we want to jump
249+
// to the field's type definition, not the field's definition.
250+
if v, ok := result.Declaration.obj.(*types.Var); ok && v.Embedded() {
251+
// types.Info.Uses contains the embedded field's *types.TypeName.
252+
if typeName := pkg.GetTypesInfo().Uses[ident]; typeName != nil {
253+
result.Declaration.obj = typeName
263254
}
264255
}
265256

internal/lsp/testdata/godef/a/a.go.golden

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,6 @@ func Random2(y int) int
7474
```
7575

7676
[`a.Random2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a?utm_source=gopls#Random2)
77-
-- a-hover --
78-
```go
79-
80-
```
8177
-- aPackage-hover --
8278
Package a is a package for testing go to definition\.
8379
-- err-definition --

internal/lsp/testdata/godef/b/b.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,13 @@ func _() {
2222
e.Goodbye() //@hover("Goodbye", AGoodbye)
2323
}
2424

25+
type aAlias = a.A //@mark(aAlias, "aAlias")
26+
2527
type S1 struct { //@S1
26-
F1 int //@mark(S1F1, "F1")
27-
S2 //@godef("S2", S2),mark(S1S2, "S2")
28-
a.A //@godef("A", AString)
28+
F1 int //@mark(S1F1, "F1")
29+
S2 //@godef("S2", S2),mark(S1S2, "S2")
30+
a.A //@godef("A", AString)
31+
aAlias //@godef("a", aAlias)
2932
}
3033

3134
type S2 struct { //@S2

internal/lsp/testdata/godef/b/b.go.golden

Lines changed: 72 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -143,11 +143,12 @@ func a.AStuff()
143143

144144
[`a.AStuff` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a?utm_source=gopls#AStuff)
145145
-- S1-definition --
146-
godef/b/b.go:25:6-8: defined here as ```go
146+
godef/b/b.go:27:6-8: defined here as ```go
147147
type S1 struct {
148-
F1 int //@mark(S1F1, "F1")
149-
S2 //@godef("S2", S2),mark(S1S2, "S2")
150-
a.A //@godef("A", AString)
148+
F1 int //@mark(S1F1, "F1")
149+
S2 //@godef("S2", S2),mark(S1S2, "S2")
150+
a.A //@godef("A", AString)
151+
aAlias //@godef("a", aAlias)
151152
}
152153
```
153154

@@ -157,31 +158,32 @@ type S1 struct {
157158
"span": {
158159
"uri": "file://godef/b/b.go",
159160
"start": {
160-
"line": 25,
161+
"line": 27,
161162
"column": 6,
162-
"offset": 521
163+
"offset": 566
163164
},
164165
"end": {
165-
"line": 25,
166+
"line": 27,
166167
"column": 8,
167-
"offset": 523
168+
"offset": 568
168169
}
169170
},
170-
"description": "```go\ntype S1 struct {\n\tF1 int //@mark(S1F1, \"F1\")\n\tS2 //@godef(\"S2\", S2),mark(S1S2, \"S2\")\n\ta.A //@godef(\"A\", AString)\n}\n```\n\n[`b.S1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b?utm_source=gopls#S1)"
171+
"description": "```go\ntype S1 struct {\n\tF1 int //@mark(S1F1, \"F1\")\n\tS2 //@godef(\"S2\", S2),mark(S1S2, \"S2\")\n\ta.A //@godef(\"A\", AString)\n\taAlias //@godef(\"a\", aAlias)\n}\n```\n\n[`b.S1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b?utm_source=gopls#S1)"
171172
}
172173

173174
-- S1-hover --
174175
```go
175176
type S1 struct {
176-
F1 int //@mark(S1F1, "F1")
177-
S2 //@godef("S2", S2),mark(S1S2, "S2")
178-
a.A //@godef("A", AString)
177+
F1 int //@mark(S1F1, "F1")
178+
S2 //@godef("S2", S2),mark(S1S2, "S2")
179+
a.A //@godef("A", AString)
180+
aAlias //@godef("a", aAlias)
179181
}
180182
```
181183

182184
[`b.S1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b?utm_source=gopls#S1)
183185
-- S1F1-definition --
184-
godef/b/b.go:26:2-4: defined here as ```go
186+
godef/b/b.go:28:2-4: defined here as ```go
185187
field F1 int
186188
```
187189

@@ -193,14 +195,14 @@ field F1 int
193195
"span": {
194196
"uri": "file://godef/b/b.go",
195197
"start": {
196-
"line": 26,
198+
"line": 28,
197199
"column": 2,
198-
"offset": 540
200+
"offset": 585
199201
},
200202
"end": {
201-
"line": 26,
203+
"line": 28,
202204
"column": 4,
203-
"offset": 542
205+
"offset": 587
204206
}
205207
},
206208
"description": "```go\nfield F1 int\n```\n\n[`(b.S1).F1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b?utm_source=gopls#S1.F1)\n\n\\@mark\\(S1F1, \\\"F1\\\"\\)"
@@ -215,7 +217,7 @@ field F1 int
215217

216218
\@mark\(S1F1, \"F1\"\)
217219
-- S1S2-definition --
218-
godef/b/b.go:27:2-4: defined here as ```go
220+
godef/b/b.go:29:2-4: defined here as ```go
219221
field S2 S2
220222
```
221223

@@ -227,14 +229,14 @@ field S2 S2
227229
"span": {
228230
"uri": "file://godef/b/b.go",
229231
"start": {
230-
"line": 27,
232+
"line": 29,
231233
"column": 2,
232-
"offset": 569
234+
"offset": 617
233235
},
234236
"end": {
235-
"line": 27,
237+
"line": 29,
236238
"column": 4,
237-
"offset": 571
239+
"offset": 619
238240
}
239241
},
240242
"description": "```go\nfield S2 S2\n```\n\n[`(b.S1).S2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b?utm_source=gopls#S1.S2)\n\n\\@godef\\(\\\"S2\\\", S2\\),mark\\(S1S2, \\\"S2\\\"\\)"
@@ -249,7 +251,7 @@ field S2 S2
249251

250252
\@godef\(\"S2\", S2\),mark\(S1S2, \"S2\"\)
251253
-- S2-definition --
252-
godef/b/b.go:31:6-8: defined here as ```go
254+
godef/b/b.go:34:6-8: defined here as ```go
253255
type S2 struct {
254256
F1 string //@mark(S2F1, "F1")
255257
F2 int //@mark(S2F2, "F2")
@@ -263,14 +265,14 @@ type S2 struct {
263265
"span": {
264266
"uri": "file://godef/b/b.go",
265267
"start": {
266-
"line": 31,
268+
"line": 34,
267269
"column": 6,
268-
"offset": 653
270+
"offset": 741
269271
},
270272
"end": {
271-
"line": 31,
273+
"line": 34,
272274
"column": 8,
273-
"offset": 655
275+
"offset": 743
274276
}
275277
},
276278
"description": "```go\ntype S2 struct {\n\tF1 string //@mark(S2F1, \"F1\")\n\tF2 int //@mark(S2F2, \"F2\")\n\t*a.A //@godef(\"A\", AString),godef(\"a\",AImport)\n}\n```\n\n[`b.S2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b?utm_source=gopls#S2)"
@@ -287,7 +289,7 @@ type S2 struct {
287289

288290
[`b.S2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b?utm_source=gopls#S2)
289291
-- S2F1-definition --
290-
godef/b/b.go:32:2-4: defined here as ```go
292+
godef/b/b.go:35:2-4: defined here as ```go
291293
field F1 string
292294
```
293295

@@ -299,14 +301,14 @@ field F1 string
299301
"span": {
300302
"uri": "file://godef/b/b.go",
301303
"start": {
302-
"line": 32,
304+
"line": 35,
303305
"column": 2,
304-
"offset": 672
306+
"offset": 760
305307
},
306308
"end": {
307-
"line": 32,
309+
"line": 35,
308310
"column": 4,
309-
"offset": 674
311+
"offset": 762
310312
}
311313
},
312314
"description": "```go\nfield F1 string\n```\n\n[`(b.S2).F1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b?utm_source=gopls#S2.F1)\n\n\\@mark\\(S2F1, \\\"F1\\\"\\)"
@@ -321,7 +323,7 @@ field F1 string
321323

322324
\@mark\(S2F1, \"F1\"\)
323325
-- S2F2-definition --
324-
godef/b/b.go:33:2-4: defined here as ```go
326+
godef/b/b.go:36:2-4: defined here as ```go
325327
field F2 int
326328
```
327329

@@ -333,14 +335,14 @@ field F2 int
333335
"span": {
334336
"uri": "file://godef/b/b.go",
335337
"start": {
336-
"line": 33,
338+
"line": 36,
337339
"column": 2,
338-
"offset": 705
340+
"offset": 793
339341
},
340342
"end": {
341-
"line": 33,
343+
"line": 36,
342344
"column": 4,
343-
"offset": 707
345+
"offset": 795
344346
}
345347
},
346348
"description": "```go\nfield F2 int\n```\n\n[`(b.S2).F2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b?utm_source=gopls#S2.F2)\n\n\\@mark\\(S2F2, \\\"F2\\\"\\)"
@@ -354,8 +356,36 @@ field F2 int
354356
[`(b.S2).F2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b?utm_source=gopls#S2.F2)
355357

356358
\@mark\(S2F2, \"F2\"\)
359+
-- aAlias-definition --
360+
godef/b/b.go:25:6-12: defined here as ```go
361+
type aAlias = a.A //@mark(aAlias, "aAlias")
362+
363+
```
364+
-- aAlias-definition-json --
365+
{
366+
"span": {
367+
"uri": "file://godef/b/b.go",
368+
"start": {
369+
"line": 25,
370+
"column": 6,
371+
"offset": 521
372+
},
373+
"end": {
374+
"line": 25,
375+
"column": 12,
376+
"offset": 527
377+
}
378+
},
379+
"description": "```go\ntype aAlias = a.A //@mark(aAlias, \"aAlias\")\n\n```"
380+
}
381+
382+
-- aAlias-hover --
383+
```go
384+
type aAlias = a.A //@mark(aAlias, "aAlias")
385+
386+
```
357387
-- bX-definition --
358-
godef/b/b.go:54:7-8: defined here as ```go
388+
godef/b/b.go:57:7-8: defined here as ```go
359389
const X untyped int = 0
360390
```
361391

@@ -367,14 +397,14 @@ const X untyped int = 0
367397
"span": {
368398
"uri": "file://godef/b/b.go",
369399
"start": {
370-
"line": 54,
400+
"line": 57,
371401
"column": 7,
372-
"offset": 1140
402+
"offset": 1228
373403
},
374404
"end": {
375-
"line": 54,
405+
"line": 57,
376406
"column": 8,
377-
"offset": 1141
407+
"offset": 1229
378408
}
379409
},
380410
"description": "```go\nconst X untyped int = 0\n```\n\n[`b.X` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b?utm_source=gopls#X)\n\n\\@mark\\(bX, \\\"X\\\"\\),godef\\(\\\"X\\\", bX\\)"

internal/lsp/testdata/godef/b/c.go.golden

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
-- S1-definition --
2-
godef/b/b.go:25:6-8: defined here as ```go
2+
godef/b/b.go:27:6-8: defined here as ```go
33
type S1 struct {
4-
F1 int //@mark(S1F1, "F1")
5-
S2 //@godef("S2", S2),mark(S1S2, "S2")
6-
a.A //@godef("A", AString)
4+
F1 int //@mark(S1F1, "F1")
5+
S2 //@godef("S2", S2),mark(S1S2, "S2")
6+
a.A //@godef("A", AString)
7+
aAlias //@godef("a", aAlias)
78
}
89
```
910

@@ -13,31 +14,32 @@ type S1 struct {
1314
"span": {
1415
"uri": "file://godef/b/b.go",
1516
"start": {
16-
"line": 25,
17+
"line": 27,
1718
"column": 6,
18-
"offset": 521
19+
"offset": 566
1920
},
2021
"end": {
21-
"line": 25,
22+
"line": 27,
2223
"column": 8,
23-
"offset": 523
24+
"offset": 568
2425
}
2526
},
26-
"description": "```go\ntype S1 struct {\n\tF1 int //@mark(S1F1, \"F1\")\n\tS2 //@godef(\"S2\", S2),mark(S1S2, \"S2\")\n\ta.A //@godef(\"A\", AString)\n}\n```\n\n[`b.S1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b?utm_source=gopls#S1)"
27+
"description": "```go\ntype S1 struct {\n\tF1 int //@mark(S1F1, \"F1\")\n\tS2 //@godef(\"S2\", S2),mark(S1S2, \"S2\")\n\ta.A //@godef(\"A\", AString)\n\taAlias //@godef(\"a\", aAlias)\n}\n```\n\n[`b.S1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b?utm_source=gopls#S1)"
2728
}
2829

2930
-- S1-hover --
3031
```go
3132
type S1 struct {
32-
F1 int //@mark(S1F1, "F1")
33-
S2 //@godef("S2", S2),mark(S1S2, "S2")
34-
a.A //@godef("A", AString)
33+
F1 int //@mark(S1F1, "F1")
34+
S2 //@godef("S2", S2),mark(S1S2, "S2")
35+
a.A //@godef("A", AString)
36+
aAlias //@godef("a", aAlias)
3537
}
3638
```
3739

3840
[`b.S1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b?utm_source=gopls#S1)
3941
-- S1F1-definition --
40-
godef/b/b.go:26:2-4: defined here as ```go
42+
godef/b/b.go:28:2-4: defined here as ```go
4143
field F1 int
4244
```
4345

@@ -49,14 +51,14 @@ field F1 int
4951
"span": {
5052
"uri": "file://godef/b/b.go",
5153
"start": {
52-
"line": 26,
54+
"line": 28,
5355
"column": 2,
54-
"offset": 540
56+
"offset": 585
5557
},
5658
"end": {
57-
"line": 26,
59+
"line": 28,
5860
"column": 4,
59-
"offset": 542
61+
"offset": 587
6062
}
6163
},
6264
"description": "```go\nfield F1 int\n```\n\n[`(b.S1).F1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b?utm_source=gopls#S1.F1)\n\n\\@mark\\(S1F1, \\\"F1\\\"\\)"

internal/lsp/testdata/summary.txt.golden

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ ImportCount = 8
1515
SemanticTokenCount = 2
1616
SuggestedFixCount = 38
1717
FunctionExtractionCount = 12
18-
DefinitionsCount = 63
18+
DefinitionsCount = 64
1919
TypeDefinitionsCount = 2
2020
HighlightsCount = 69
2121
ReferencesCount = 25

0 commit comments

Comments
 (0)