diff options
author | Alan Donovan <adonovan@google.com> | 2023-01-19 11:33:09 -0500 |
---|---|---|
committer | Alan Donovan <adonovan@google.com> | 2023-01-19 17:46:57 +0000 |
commit | afea27258597edccd7de3017d62243e70a27c529 (patch) | |
tree | 4e0f947a50aa4513f3f076bf05001cae4b59bfa1 | |
parent | bb7c440efb2b3f94e9c598584cdc94a5f4e5c909 (diff) | |
download | golang-x-tools-afea27258597edccd7de3017d62243e70a27c529.tar.gz |
gopls/internal/lsp/source: make implementations2 work on embedded fields
Previously, the operation on struct{T} would fail with the error
"T is a var, not a type".
I don't like the way that each new testcase in the marker tests
incurs a quadratic logical complexity. Convenient though it is
to edit testdata/*.go files, it tends to encourage a kind of sprawl.
Do we have a precedent for self-contained marker tests that use
a txtar literal?
Updates golang/go#57898
Change-Id: I39a5cb1d96452b621bc6661094f1d735f0e32d3f
Reviewed-on: https://go-review.googlesource.com/c/tools/+/462658
Run-TryBot: Alan Donovan <adonovan@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
gopls-CI: kokoro <noreply+kokoro@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
4 files changed, 14 insertions, 4 deletions
diff --git a/gopls/internal/lsp/source/implementation2.go b/gopls/internal/lsp/source/implementation2.go index 4a8e829a8..7ca2e087e 100644 --- a/gopls/internal/lsp/source/implementation2.go +++ b/gopls/internal/lsp/source/implementation2.go @@ -274,7 +274,13 @@ func typeDeclPosition(ctx context.Context, snapshot Snapshot, uri span.URI, ppos // Is the object a type or method? Reject other kinds. var methodID string - obj := pkg.GetTypesInfo().ObjectOf(id) + obj := pkg.GetTypesInfo().Uses[id] + if obj == nil { + // Check uses first (unlike ObjectOf) so that T in + // struct{T} is treated as a reference to a type, + // not a declaration of a field. + obj = pkg.GetTypesInfo().Defs[id] + } switch obj := obj.(type) { case *types.TypeName: // ok diff --git a/gopls/internal/lsp/testdata/implementation/implementation.go b/gopls/internal/lsp/testdata/implementation/implementation.go index 5f124750e..4c1a22dd4 100644 --- a/gopls/internal/lsp/testdata/implementation/implementation.go +++ b/gopls/internal/lsp/testdata/implementation/implementation.go @@ -12,7 +12,7 @@ type ImpS struct{} //@ImpS,implementations("ImpS", Laugher, OtherLaugher) func (ImpS) Laugh() { //@mark(LaughS, "Laugh"),implementations("Laugh", Laugh, OtherLaugh) } -type Laugher interface { //@Laugher,implementations("Laugher", ImpP, OtherImpP, ImpS, OtherImpS) +type Laugher interface { //@Laugher,implementations("Laugher", ImpP, OtherImpP, ImpS, OtherImpS, embedsImpP) Laugh() //@Laugh,implementations("Laugh", LaughP, OtherLaughP, LaughS, OtherLaughS) } @@ -31,3 +31,7 @@ func (cryer) Cry(other.CryType) {} //@mark(CryImpl, "Cry"),implementations("Cry" type Empty interface{} //@implementations("Empty") var _ interface{ Joke() } //@implementations("Joke", ImpJoker) + +type embedsImpP struct { //@embedsImpP + ImpP //@implementations("ImpP", Laugher, OtherLaugher) +} diff --git a/gopls/internal/lsp/testdata/summary.txt.golden b/gopls/internal/lsp/testdata/summary.txt.golden index e44ce18c0..e0982417c 100644 --- a/gopls/internal/lsp/testdata/summary.txt.golden +++ b/gopls/internal/lsp/testdata/summary.txt.golden @@ -27,6 +27,6 @@ SymbolsCount = 1 WorkspaceSymbolsCount = 20 SignaturesCount = 33 LinksCount = 7 -ImplementationsCount = 15 +ImplementationsCount = 16 SelectionRangesCount = 3 diff --git a/gopls/internal/lsp/testdata/summary_go1.18.txt.golden b/gopls/internal/lsp/testdata/summary_go1.18.txt.golden index 80a5d23c7..b402eef2e 100644 --- a/gopls/internal/lsp/testdata/summary_go1.18.txt.golden +++ b/gopls/internal/lsp/testdata/summary_go1.18.txt.golden @@ -27,6 +27,6 @@ SymbolsCount = 2 WorkspaceSymbolsCount = 20 SignaturesCount = 33 LinksCount = 7 -ImplementationsCount = 25 +ImplementationsCount = 26 SelectionRangesCount = 3 |