Skip to content

Commit 4c53267

Browse files
committed
gopls/internal/lsp/cache: don't report a bug for standalone test files
go/packages will return test command-line-arguments test variants for standalone test files. Handle this case, and refine our bug report. Fixes golang/go#64233 Change-Id: I15fd8a50476ece58eedbf09233827f55bfb79a2e Reviewed-on: https://go-review.googlesource.com/c/tools/+/557635 LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Alan Donovan <[email protected]>
1 parent a49867f commit 4c53267

File tree

2 files changed

+81
-4
lines changed

2 files changed

+81
-4
lines changed

gopls/internal/lsp/cache/load.go

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -151,17 +151,52 @@ func (s *Snapshot) load(ctx context.Context, allowNetwork bool, scopes ...loadSc
151151
event.Log(ctx, eventName, labels...)
152152
}
153153

154+
if standalone {
155+
// Handle standalone package result.
156+
//
157+
// In general, this should just be a single "command-line-arguments"
158+
// package containing the requested file. However, if the file is a test
159+
// file, go/packages may return test variants of the command-line-arguments
160+
// package. We don't support this; theoretically we could, but it seems
161+
// unnecessarily complicated.
162+
//
163+
// Prior to golang/go#64233 we just assumed that we'd get exactly one
164+
// package here. The categorization of bug reports below may be a bit
165+
// verbose, but anticipates that perhaps we don't fully understand
166+
// possible failure modes.
167+
errorf := bug.Errorf
168+
if s.view.typ == GoPackagesDriverView {
169+
errorf = fmt.Errorf // all bets are off
170+
}
171+
172+
var standalonePkg *packages.Package
173+
for _, pkg := range pkgs {
174+
if pkg.ID == "command-line-arguments" {
175+
if standalonePkg != nil {
176+
return errorf("internal error: go/packages returned multiple standalone packages")
177+
}
178+
standalonePkg = pkg
179+
} else if packagesinternal.GetForTest(pkg) == "" && !strings.HasSuffix(pkg.ID, ".test") {
180+
return errorf("internal error: go/packages returned unexpected package %q for standalone file", pkg.ID)
181+
}
182+
}
183+
if standalonePkg == nil {
184+
return errorf("internal error: go/packages failed to return non-test standalone package")
185+
}
186+
if len(standalonePkg.CompiledGoFiles) > 0 {
187+
pkgs = []*packages.Package{standalonePkg}
188+
} else {
189+
pkgs = nil
190+
}
191+
}
192+
154193
if len(pkgs) == 0 {
155194
if err == nil {
156195
err = errNoPackages
157196
}
158197
return fmt.Errorf("packages.Load error: %w", err)
159198
}
160199

161-
if standalone && len(pkgs) > 1 {
162-
return bug.Errorf("internal error: go/packages returned multiple packages for standalone file")
163-
}
164-
165200
moduleErrs := make(map[string][]packages.Error) // module path -> errors
166201
filterFunc := s.view.filterFunc()
167202
newMetadata := make(map[PackageID]*metadata.Package)
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
This test checks the behavior of standalone packages, in particular documenting
2+
our failure to support test files as standalone packages (golang/go#64233).
3+
4+
-- go.mod --
5+
module golang.org/lsptests/a
6+
7+
go 1.20
8+
9+
-- a.go --
10+
package a
11+
12+
func F() {} //@loc(F, "F")
13+
14+
-- standalone.go --
15+
//go:build ignore
16+
package main
17+
18+
import "golang.org/lsptests/a"
19+
20+
func main() {
21+
a.F() //@def("F", F)
22+
}
23+
24+
-- standalone_test.go --
25+
//go:build ignore
26+
package main //@diag("main", re"No packages found")
27+
28+
import "golang.org/lsptests/a"
29+
30+
func main() {
31+
a.F() //@hovererr("F", "no package")
32+
}
33+
34+
-- standalone_x_test.go --
35+
//go:build ignore
36+
package main_test //@diag("main", re"No packages found")
37+
38+
import "golang.org/lsptests/a"
39+
40+
func main() {
41+
a.F() //@hovererr("F", "no package")
42+
}

0 commit comments

Comments
 (0)