internal/lsp: handle embedded struct pointer definitions

When jumping to definition of an embedded struct pointer, be sure to
unwrap the pointer type so you properly jump to the pointee type.

Also, fix jumping to definition of an embedded struct inside an
anonymous struct inside a struct. The embedded struct detection was
continuing too far and thinking it wasn't an embedded struct when it
saw the anonymous struct.

Fixes golang/go#31451

Change-Id: I96017764270712a2ae02a85306605495075d12e7
GitHub-Last-Rev: 9997f60855
GitHub-Pull-Request: golang/tools#83
Reviewed-on: https://go-review.googlesource.com/c/tools/+/172583
Run-TryBot: Paul Jolly <paul@myitcv.org.uk>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Cottrell <iancottrell@google.com>
This commit is contained in:
Muir Manders 2019-04-19 15:10:38 +00:00 коммит произвёл Rebecca Stambler
Родитель 685fecacd0
Коммит aa740d4807
4 изменённых файлов: 14 добавлений и 6 удалений

Просмотреть файл

@ -24,7 +24,7 @@ import (
)
const (
expectedDefinitionsCount = 26
expectedDefinitionsCount = 28
expectedTypeDefinitionsCount = 2
)

Просмотреть файл

@ -41,7 +41,7 @@ func testLSP(t *testing.T, exporter packagestest.Exporter) {
const expectedCompletionsCount = 65
const expectedDiagnosticsCount = 16
const expectedFormatCount = 4
const expectedDefinitionsCount = 17
const expectedDefinitionsCount = 19
const expectedTypeDefinitionsCount = 2
const expectedHighlightsCount = 2
const expectedSymbolsCount = 1

Просмотреть файл

@ -76,6 +76,7 @@ func identifier(ctx context.Context, v View, f File, pos token.Pos) (*Identifier
for _, n := range path[1:] {
if field, ok := n.(*ast.Field); ok {
result.wasEmbeddedField = len(field.Names) == 0
break
}
}
result.Name = result.ident.Name
@ -88,8 +89,8 @@ func identifier(ctx context.Context, v View, f File, pos token.Pos) (*Identifier
// The original position was on the embedded field declaration, so we
// try to dig out the type and jump to that instead.
if v, ok := result.Declaration.Object.(*types.Var); ok {
if n, ok := v.Type().(*types.Named); ok {
result.Declaration.Object = n.Obj()
if typObj := typeToObject(v.Type()); typObj != nil {
result.Declaration.Object = typObj
}
}
}

11
internal/lsp/testdata/godef/b/b.go поставляемый
Просмотреть файл

@ -9,8 +9,15 @@ type S1 struct { //@S1
}
type S2 struct { //@S2
F1 string //@mark(S2F1, "F1")
F2 int //@mark(S2F2, "F2")
F1 string //@mark(S2F1, "F1")
F2 int //@mark(S2F2, "F2")
*a.A //@godef("A", A)
}
type S3 struct {
F1 struct {
a.A //@godef("A", A)
}
}
func Bar() {