go/packages: find filenames in error strings if not in position

In the case of an invalid package name (the package name is a keyword),
`go list` doesn't report any filenames associated with the package.
As we have done previously, we can parse these out of the error message.
However, it seems like, in this case, the filename is in the error
string itself, not the error position.

Updates golang/go#39986
Updates golang/go#39763

Change-Id: Id9c68a93ac4f545e4e2152540ca85b92f1df4640
Reviewed-on: https://go-review.googlesource.com/c/tools/+/244028
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Michael Matloob <matloob@golang.org>
This commit is contained in:
Rebecca Stambler 2020-07-21 18:48:07 -04:00
parent bd1e9de8d8
commit a7c6fd066f
2 changed files with 54 additions and 9 deletions

View File

@ -639,16 +639,32 @@ func (state *golistState) createDriverResponse(words ...string) (*driverResponse
// error messages. This happens if there are unrecoverable syntax
// errors in the source, so we can't match on a specific error message.
if err := p.Error; err != nil && len(err.ImportStack) == 0 && len(pkg.CompiledGoFiles) == 0 {
if split := strings.Split(err.Pos, ":"); len(split) > 1 {
if filename := split[0]; filename != "" {
if !filepath.IsAbs(filename) {
filename = filepath.Join(state.cfg.Dir, filename)
}
if info, _ := os.Stat(filename); info != nil {
pkg.CompiledGoFiles = append(pkg.CompiledGoFiles, filename)
pkg.GoFiles = append(pkg.GoFiles, filename)
}
addFilenameFromPos := func(pos string) bool {
split := strings.Split(pos, ":")
if len(split) < 1 {
return false
}
filename := strings.TrimSpace(split[0])
if filename == "" {
return false
}
if !filepath.IsAbs(filename) {
filename = filepath.Join(state.cfg.Dir, filename)
}
info, _ := os.Stat(filename)
if info == nil {
return false
}
pkg.CompiledGoFiles = append(pkg.CompiledGoFiles, filename)
pkg.GoFiles = append(pkg.GoFiles, filename)
return true
}
found := addFilenameFromPos(err.Pos)
// In some cases, go list only reports the error position in the
// error text, not the error position. One such case is when the
// file's package name is a keyword (see golang.org/issue/39763).
if !found {
addFilenameFromPos(err.Err)
}
}

View File

@ -2537,6 +2537,35 @@ func main() {
}
}
func TestInvalidPackageName(t *testing.T) {
packagestest.TestAll(t, testInvalidPackageName)
}
func testInvalidPackageName(t *testing.T, exporter packagestest.Exporter) {
testenv.NeedsGo1Point(t, 15)
exported := packagestest.Export(t, exporter, []packagestest.Module{{
Name: "golang.org/fake",
Files: map[string]interface{}{
"main.go": `package default
func main() {
}
`,
},
}})
defer exported.Cleanup()
initial, err := packages.Load(exported.Config, "golang.org/fake")
if err != nil {
t.Fatal(err)
}
pkg := initial[0]
if len(pkg.CompiledGoFiles) != 1 {
t.Fatalf("expected 1 Go file in package %s, got %v", pkg.ID, len(pkg.CompiledGoFiles))
}
}
func errorMessages(errors []packages.Error) []string {
var msgs []string
for _, err := range errors {