From a7c6fd066f6dcf64c13983e28e029ce7874760ff Mon Sep 17 00:00:00 2001 From: Rebecca Stambler Date: Tue, 21 Jul 2020 18:48:07 -0400 Subject: [PATCH] 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 TryBot-Result: Gobot Gobot Reviewed-by: Michael Matloob --- go/packages/golist.go | 34 +++++++++++++++++++++++++--------- go/packages/packages_test.go | 29 +++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 9 deletions(-) diff --git a/go/packages/golist.go b/go/packages/golist.go index 1a5aba9f9f..220d409878 100644 --- a/go/packages/golist.go +++ b/go/packages/golist.go @@ -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) } } diff --git a/go/packages/packages_test.go b/go/packages/packages_test.go index 2974eccd7a..a62bac4f8e 100644 --- a/go/packages/packages_test.go +++ b/go/packages/packages_test.go @@ -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 {