go/packages: determine sizes by calling go list
This is more reliable than looking in the environment. Change-Id: I96c093b89faaece6b6256eefb4a4aac4d66b9cc9 Reviewed-on: https://go-review.googlesource.com/c/146757 Run-TryBot: Michael Matloob <matloob@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Alan Donovan <adonovan@google.com>
This commit is contained in:
parent
e504f914a8
commit
78dc5bac0c
|
@ -8,6 +8,7 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"go/types"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
@ -36,6 +37,17 @@ type goTooOldError struct {
|
||||||
// the build system package structure.
|
// the build system package structure.
|
||||||
// See driver for more details.
|
// See driver for more details.
|
||||||
func goListDriver(cfg *Config, patterns ...string) (*driverResponse, error) {
|
func goListDriver(cfg *Config, patterns ...string) (*driverResponse, error) {
|
||||||
|
var sizes types.Sizes
|
||||||
|
var sizeserr error
|
||||||
|
var sizeswg sync.WaitGroup
|
||||||
|
if cfg.Mode >= LoadTypes {
|
||||||
|
sizeswg.Add(1)
|
||||||
|
go func() {
|
||||||
|
sizes, sizeserr = getSizes(cfg)
|
||||||
|
sizeswg.Done()
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
// Determine files requested in contains patterns
|
// Determine files requested in contains patterns
|
||||||
var containFiles []string
|
var containFiles []string
|
||||||
var packagesNamed []string
|
var packagesNamed []string
|
||||||
|
@ -109,6 +121,12 @@ extractQueries:
|
||||||
response = &driverResponse{}
|
response = &driverResponse{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sizeswg.Wait()
|
||||||
|
if sizeserr != nil {
|
||||||
|
return nil, sizeserr
|
||||||
|
}
|
||||||
|
response.Sizes = sizes
|
||||||
|
|
||||||
if len(containFiles) == 0 && len(packagesNamed) == 0 {
|
if len(containFiles) == 0 && len(packagesNamed) == 0 {
|
||||||
return response, nil
|
return response, nil
|
||||||
}
|
}
|
||||||
|
@ -328,6 +346,18 @@ func runNamedQueries(cfg *Config, driver driver, addPkg func(*Package), queries
|
||||||
return results, nil
|
return results, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getSizes(cfg *Config) (types.Sizes, error) {
|
||||||
|
stdout, err := invokeGo(cfg, "env", "GOARCH") // TODO(matloob): perhaps merge this call with the roots call?
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
goarch := strings.TrimSpace(stdout.String())
|
||||||
|
// Assume "gc" because SizesFor doesn't respond to other compilers.
|
||||||
|
// TODO(matloob): add support for gccgo as needed.
|
||||||
|
return types.SizesFor("gc", goarch), nil
|
||||||
|
}
|
||||||
|
|
||||||
// roots selects the appropriate paths to walk based on the passed-in configuration,
|
// roots selects the appropriate paths to walk based on the passed-in configuration,
|
||||||
// particularly the environment and the presence of a go.mod in cfg.Dir's parents.
|
// particularly the environment and the presence of a go.mod in cfg.Dir's parents.
|
||||||
func roots(cfg *Config) ([]gopathwalk.Root, string, error) {
|
func roots(cfg *Config) ([]gopathwalk.Root, string, error) {
|
||||||
|
|
|
@ -19,8 +19,6 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"golang.org/x/tools/go/gcexportdata"
|
"golang.org/x/tools/go/gcexportdata"
|
||||||
|
@ -139,6 +137,9 @@ type driver func(cfg *Config, patterns ...string) (*driverResponse, error)
|
||||||
|
|
||||||
// driverResponse contains the results for a driver query.
|
// driverResponse contains the results for a driver query.
|
||||||
type driverResponse struct {
|
type driverResponse struct {
|
||||||
|
// Sizes, if not nil, is the types.Sizes to use when type checking.
|
||||||
|
Sizes types.Sizes
|
||||||
|
|
||||||
// Roots is the set of package IDs that make up the root packages.
|
// Roots is the set of package IDs that make up the root packages.
|
||||||
// We have to encode this separately because when we encode a single package
|
// We have to encode this separately because when we encode a single package
|
||||||
// we cannot know if it is one of the roots as that requires knowledge of the
|
// we cannot know if it is one of the roots as that requires knowledge of the
|
||||||
|
@ -173,6 +174,7 @@ func Load(cfg *Config, patterns ...string) ([]*Package, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
l.sizes = response.Sizes
|
||||||
return l.refine(response.Roots, response.Packages...)
|
return l.refine(response.Roots, response.Packages...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -367,6 +369,7 @@ type loaderPackage struct {
|
||||||
type loader struct {
|
type loader struct {
|
||||||
pkgs map[string]*loaderPackage
|
pkgs map[string]*loaderPackage
|
||||||
Config
|
Config
|
||||||
|
sizes types.Sizes
|
||||||
exportMu sync.Mutex // enforces mutual exclusion of exportdata operations
|
exportMu sync.Mutex // enforces mutual exclusion of exportdata operations
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -692,17 +695,6 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) {
|
||||||
panic("unreachable")
|
panic("unreachable")
|
||||||
})
|
})
|
||||||
|
|
||||||
// This is only an approximation.
|
|
||||||
// TODO(adonovan): derive Sizes from the underlying build system.
|
|
||||||
goarch := runtime.GOARCH
|
|
||||||
const goarchPrefix = "GOARCH="
|
|
||||||
for _, e := range ld.Config.Env {
|
|
||||||
if strings.HasPrefix(e, goarchPrefix) {
|
|
||||||
goarch = e[len(goarchPrefix):]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sizes := types.SizesFor("gc", goarch)
|
|
||||||
|
|
||||||
// type-check
|
// type-check
|
||||||
tc := &types.Config{
|
tc := &types.Config{
|
||||||
Importer: importer,
|
Importer: importer,
|
||||||
|
@ -713,7 +705,7 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) {
|
||||||
IgnoreFuncBodies: ld.Mode < LoadAllSyntax && !lpkg.initial,
|
IgnoreFuncBodies: ld.Mode < LoadAllSyntax && !lpkg.initial,
|
||||||
|
|
||||||
Error: appendError,
|
Error: appendError,
|
||||||
Sizes: sizes,
|
Sizes: ld.sizes,
|
||||||
}
|
}
|
||||||
types.NewChecker(tc, ld.Fset, lpkg.Types, lpkg.TypesInfo).Files(lpkg.Syntax)
|
types.NewChecker(tc, ld.Fset, lpkg.Types, lpkg.TypesInfo).Files(lpkg.Syntax)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue