go/packages: fix loading of syntax when types not requested

Fix a case where go/packages wasn't loading syntax if a user
requested syntax without types.

Fixes golang/go#35331

Change-Id: Ife3eda583f28cbd6189257d1ffda2ed350044a01
Reviewed-on: https://go-review.googlesource.com/c/tools/+/205160
Run-TryBot: Michael Matloob <matloob@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
This commit is contained in:
Michael Matloob 2019-11-04 13:01:47 -05:00
parent a71b6a17ce
commit d415e1c6f9
2 changed files with 35 additions and 4 deletions

View File

@ -467,7 +467,7 @@ func newLoader(cfg *Config) *loader {
ld.requestedMode = ld.Mode ld.requestedMode = ld.Mode
ld.Mode = impliedLoadMode(ld.Mode) ld.Mode = impliedLoadMode(ld.Mode)
if ld.Mode&NeedTypes != 0 { if ld.Mode&NeedTypes != 0 || ld.Mode&NeedSyntax != 0 {
if ld.Fset == nil { if ld.Fset == nil {
ld.Fset = token.NewFileSet() ld.Fset = token.NewFileSet()
} }
@ -609,9 +609,9 @@ func (ld *loader) refine(roots []string, list ...*Package) ([]*Package, error) {
} }
} }
} }
// Load type data if needed, starting at // Load type data and syntax if needed, starting at
// the initial packages (roots of the import DAG). // the initial packages (roots of the import DAG).
if ld.Mode&NeedTypes != 0 { if ld.Mode&NeedTypes != 0 || ld.Mode&NeedSyntax != 0 {
var wg sync.WaitGroup var wg sync.WaitGroup
for _, lpkg := range initial { for _, lpkg := range initial {
wg.Add(1) wg.Add(1)
@ -770,7 +770,7 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) {
lpkg.Errors = append(lpkg.Errors, errs...) lpkg.Errors = append(lpkg.Errors, errs...)
} }
if len(lpkg.CompiledGoFiles) == 0 && lpkg.ExportFile != "" { if ld.Config.Mode&NeedTypes != 0 && len(lpkg.CompiledGoFiles) == 0 && lpkg.ExportFile != "" {
// The config requested loading sources and types, but sources are missing. // The config requested loading sources and types, but sources are missing.
// Add an error to the package and fall back to loading from export data. // Add an error to the package and fall back to loading from export data.
appendError(Error{"-", fmt.Sprintf("sources missing for package %s", lpkg.ID), ParseError}) appendError(Error{"-", fmt.Sprintf("sources missing for package %s", lpkg.ID), ParseError})
@ -784,6 +784,9 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) {
} }
lpkg.Syntax = files lpkg.Syntax = files
if ld.Config.Mode&NeedTypes == 0 {
return
}
lpkg.TypesInfo = &types.Info{ lpkg.TypesInfo = &types.Info{
Types: make(map[ast.Expr]types.TypeAndValue), Types: make(map[ast.Expr]types.TypeAndValue),

View File

@ -2498,6 +2498,34 @@ func testImpliedLoadMode(t *testing.T, exporter packagestest.Exporter) {
} }
} }
func TestIssue35331(t *testing.T) {
packagestest.TestAll(t, testIssue35331)
}
func testIssue35331(t *testing.T, exporter packagestest.Exporter) {
exported := packagestest.Export(t, exporter, []packagestest.Module{{
Name: "golang.org/fake",
}})
defer exported.Cleanup()
exported.Config.Mode = packages.NeedName | packages.NeedFiles | packages.NeedCompiledGoFiles |
packages.NeedImports | packages.NeedDeps | packages.NeedSyntax
exported.Config.Tests = false
pkgs, err := packages.Load(exported.Config, "strconv")
if err != nil {
t.Fatal(err)
}
if len(pkgs) != 1 {
t.Fatalf("Expected 1 package, got %v", pkgs)
}
pkg := pkgs[0]
if len(pkg.Errors) > 0 {
t.Fatalf("Expected no errors in package, got %v", pkg.Errors)
}
if len(pkg.Syntax) == 0 {
t.Fatalf("Expected syntax on package, got none.")
}
}
func errorMessages(errors []packages.Error) []string { func errorMessages(errors []packages.Error) []string {
var msgs []string var msgs []string
for _, err := range errors { for _, err := range errors {