Skip to content

Commit 7f77468

Browse files
findleyrstamblerre
andcommitted
[gopls-release-branch.0.7] internal/lsp/source: consider test variants when finding pkg from pos
When resolving a position to a package we must consider all packages, including intermediate test variants. This manifests, for example, when jumping to definition in a package that is imported as a test variant (see golang/go#47825). For now, fix this by threading through an 'includeTestVariants' flag to PackagesForFile. This isn't pretty, but should be a trivially safe change: the only effect will be to increase the number of packages considered in FindPackageFromPos. Since we are discussing future changes to the API for querying packages from the snapshot, now did not seem like a good time to undertake significant refactoring. A regtest based on the original issue is included. This CL is joint with [email protected]. Fixes golang/go#47825 Co-authored-by: Rebecca Stambler <[email protected]> Change-Id: I4693ec69b50ed4acd569cff87883769c1edf332b Reviewed-on: https://go-review.googlesource.com/c/tools/+/347563 Trust: Robert Findley <[email protected]> Run-TryBot: Robert Findley <[email protected]> gopls-CI: kokoro <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Rebecca Stambler <[email protected]> (cherry picked from commit e5f719f) Reviewed-on: https://go-review.googlesource.com/c/tools/+/348372
1 parent 64eabae commit 7f77468

File tree

8 files changed

+56
-15
lines changed

8 files changed

+56
-15
lines changed

gopls/internal/regtest/misc/definition_test.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"testing"
1111

1212
. "golang.org/x/tools/internal/lsp/regtest"
13+
"golang.org/x/tools/internal/testenv"
1314

1415
"golang.org/x/tools/internal/lsp/fake"
1516
"golang.org/x/tools/internal/lsp/tests"
@@ -234,3 +235,45 @@ func main() {}
234235
})
235236
}
236237
}
238+
239+
// Test for golang/go#47825.
240+
func TestImportTestVariant(t *testing.T) {
241+
testenv.NeedsGo1Point(t, 13)
242+
243+
const mod = `
244+
-- go.mod --
245+
module mod.com
246+
247+
go 1.12
248+
-- client/test/role.go --
249+
package test
250+
251+
import _ "mod.com/client"
252+
253+
type RoleSetup struct{}
254+
-- client/client_role_test.go --
255+
package client_test
256+
257+
import (
258+
"testing"
259+
_ "mod.com/client"
260+
ctest "mod.com/client/test"
261+
)
262+
263+
func TestClient(t *testing.T) {
264+
_ = ctest.RoleSetup{}
265+
}
266+
-- client/client_test.go --
267+
package client
268+
269+
import "testing"
270+
271+
func TestClient(t *testing.T) {}
272+
-- client.go --
273+
package client
274+
`
275+
Run(t, mod, func(t *testing.T, env *Env) {
276+
env.OpenFile("client/client_role_test.go")
277+
env.GoToDefinition("client/client_role_test.go", env.RegexpSearch("client/client_role_test.go", "RoleSetup"))
278+
})
279+
}

internal/lsp/cache/snapshot.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -453,10 +453,10 @@ func hashUnsavedOverlays(files map[span.URI]source.VersionedFileHandle) string {
453453
return hashContents([]byte(strings.Join(unsaved, "")))
454454
}
455455

456-
func (s *snapshot) PackagesForFile(ctx context.Context, uri span.URI, mode source.TypecheckMode) ([]source.Package, error) {
456+
func (s *snapshot) PackagesForFile(ctx context.Context, uri span.URI, mode source.TypecheckMode, includeTestVariants bool) ([]source.Package, error) {
457457
ctx = event.Label(ctx, tag.URI.Of(uri))
458458

459-
phs, err := s.packageHandlesForFile(ctx, uri, mode)
459+
phs, err := s.packageHandlesForFile(ctx, uri, mode, includeTestVariants)
460460
if err != nil {
461461
return nil, err
462462
}
@@ -474,7 +474,7 @@ func (s *snapshot) PackagesForFile(ctx context.Context, uri span.URI, mode sourc
474474
func (s *snapshot) PackageForFile(ctx context.Context, uri span.URI, mode source.TypecheckMode, pkgPolicy source.PackageFilter) (source.Package, error) {
475475
ctx = event.Label(ctx, tag.URI.Of(uri))
476476

477-
phs, err := s.packageHandlesForFile(ctx, uri, mode)
477+
phs, err := s.packageHandlesForFile(ctx, uri, mode, false)
478478
if err != nil {
479479
return nil, err
480480
}
@@ -503,7 +503,7 @@ func (s *snapshot) PackageForFile(ctx context.Context, uri span.URI, mode source
503503
return ph.check(ctx, s)
504504
}
505505

506-
func (s *snapshot) packageHandlesForFile(ctx context.Context, uri span.URI, mode source.TypecheckMode) ([]*packageHandle, error) {
506+
func (s *snapshot) packageHandlesForFile(ctx context.Context, uri span.URI, mode source.TypecheckMode, includeTestVariants bool) ([]*packageHandle, error) {
507507
// Check if we should reload metadata for the file. We don't invalidate IDs
508508
// (though we should), so the IDs will be a better source of truth than the
509509
// metadata. If there are no IDs for the file, then we should also reload.
@@ -523,7 +523,7 @@ func (s *snapshot) packageHandlesForFile(ctx context.Context, uri span.URI, mode
523523
for _, id := range knownIDs {
524524
// Filter out any intermediate test variants. We typically aren't
525525
// interested in these packages for file= style queries.
526-
if m := s.getMetadata(id); m != nil && m.IsIntermediateTestVariant {
526+
if m := s.getMetadata(id); m != nil && m.IsIntermediateTestVariant && !includeTestVariants {
527527
continue
528528
}
529529
var parseModes []source.ParseMode

internal/lsp/command.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ func (c *commandHandler) RunTests(ctx context.Context, args command.RunTestsArgs
358358

359359
func (c *commandHandler) runTests(ctx context.Context, snapshot source.Snapshot, work *progress.WorkDone, uri protocol.DocumentURI, tests, benchmarks []string) error {
360360
// TODO: fix the error reporting when this runs async.
361-
pkgs, err := snapshot.PackagesForFile(ctx, uri.SpanURI(), source.TypecheckWorkspace)
361+
pkgs, err := snapshot.PackagesForFile(ctx, uri.SpanURI(), source.TypecheckWorkspace, false)
362362
if err != nil {
363363
return err
364364
}

internal/lsp/diagnostics.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ func (s *Server) diagnoseChangedFiles(ctx context.Context, snapshot source.Snaps
153153
if snapshot.IsBuiltin(ctx, uri) {
154154
continue
155155
}
156-
pkgs, err := snapshot.PackagesForFile(ctx, uri, source.TypecheckFull)
156+
pkgs, err := snapshot.PackagesForFile(ctx, uri, source.TypecheckFull, false)
157157
if err != nil {
158158
// TODO (findleyr): we should probably do something with the error here,
159159
// but as of now this can fail repeatedly if load fails, so can be too
@@ -423,7 +423,7 @@ func (s *Server) checkForOrphanedFile(ctx context.Context, snapshot source.Snaps
423423
if snapshot.IsBuiltin(ctx, fh.URI()) {
424424
return nil
425425
}
426-
pkgs, err := snapshot.PackagesForFile(ctx, fh.URI(), source.TypecheckWorkspace)
426+
pkgs, err := snapshot.PackagesForFile(ctx, fh.URI(), source.TypecheckWorkspace, false)
427427
if len(pkgs) > 0 || err == nil {
428428
return nil
429429
}

internal/lsp/source/identifier.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ func Identifier(ctx context.Context, snapshot Snapshot, fh FileHandle, pos proto
7878
ctx, done := event.Start(ctx, "source.Identifier")
7979
defer done()
8080

81-
pkgs, err := snapshot.PackagesForFile(ctx, fh.URI(), TypecheckAll)
81+
pkgs, err := snapshot.PackagesForFile(ctx, fh.URI(), TypecheckAll, false)
8282
if err != nil {
8383
return nil, err
8484
}

internal/lsp/source/implementation.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ var (
215215
// every package that the file belongs to, in every typechecking mode
216216
// applicable.
217217
func qualifiedObjsAtProtocolPos(ctx context.Context, s Snapshot, uri span.URI, pp protocol.Position) ([]qualifiedObject, error) {
218-
pkgs, err := s.PackagesForFile(ctx, uri, TypecheckAll)
218+
pkgs, err := s.PackagesForFile(ctx, uri, TypecheckAll, false)
219219
if err != nil {
220220
return nil, err
221221
}
@@ -262,7 +262,7 @@ func qualifiedObjsAtLocation(ctx context.Context, s Snapshot, key objSearchKey,
262262
// try to be comprehensive in case we ever support variations on build
263263
// constraints.
264264

265-
pkgs, err := s.PackagesForFile(ctx, key.uri, TypecheckAll)
265+
pkgs, err := s.PackagesForFile(ctx, key.uri, TypecheckAll, false)
266266
if err != nil {
267267
return nil, err
268268
}

internal/lsp/source/util.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -282,9 +282,7 @@ func FindPackageFromPos(ctx context.Context, snapshot Snapshot, pos token.Pos) (
282282
return nil, errors.Errorf("no file for pos %v", pos)
283283
}
284284
uri := span.URIFromPath(tok.Name())
285-
// Search all packages: some callers may be working with packages not
286-
// type-checked in workspace mode.
287-
pkgs, err := snapshot.PackagesForFile(ctx, uri, TypecheckAll)
285+
pkgs, err := snapshot.PackagesForFile(ctx, uri, TypecheckAll, true)
288286
if err != nil {
289287
return nil, err
290288
}

internal/lsp/source/view.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ type Snapshot interface {
137137

138138
// PackagesForFile returns the packages that this file belongs to, checked
139139
// in mode.
140-
PackagesForFile(ctx context.Context, uri span.URI, mode TypecheckMode) ([]Package, error)
140+
PackagesForFile(ctx context.Context, uri span.URI, mode TypecheckMode, includeTestVariants bool) ([]Package, error)
141141

142142
// PackageForFile returns a single package that this file belongs to,
143143
// checked in mode and filtered by the package policy.

0 commit comments

Comments
 (0)