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 {