Updated and re-enabled statickcheck
This commit is contained in:
226
vendor/golang.org/x/tools/go/packages/packages.go
generated
vendored
226
vendor/golang.org/x/tools/go/packages/packages.go
generated
vendored
@ -19,7 +19,6 @@ import (
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
@ -31,35 +30,81 @@ import (
|
||||
// but may be slower. Load may return more information than requested.
|
||||
type LoadMode int
|
||||
|
||||
const (
|
||||
// The following constants are used to specify which fields of the Package
|
||||
// should be filled when loading is done. As a special case to provide
|
||||
// backwards compatibility, a LoadMode of 0 is equivalent to LoadFiles.
|
||||
// For all other LoadModes, the bits below specify which fields will be filled
|
||||
// in the result packages.
|
||||
// WARNING: This part of the go/packages API is EXPERIMENTAL. It might
|
||||
// be changed or removed up until April 15 2019. After that date it will
|
||||
// be frozen.
|
||||
// TODO(matloob): Remove this comment on April 15.
|
||||
|
||||
// ID and Errors (if present) will always be filled.
|
||||
|
||||
// NeedName adds Name and PkgPath.
|
||||
NeedName LoadMode = 1 << iota
|
||||
|
||||
// NeedFiles adds GoFiles and OtherFiles.
|
||||
NeedFiles
|
||||
|
||||
// NeedCompiledGoFiles adds CompiledGoFiles.
|
||||
NeedCompiledGoFiles
|
||||
|
||||
// NeedImports adds Imports. If NeedDeps is not set, the Imports field will contain
|
||||
// "placeholder" Packages with only the ID set.
|
||||
NeedImports
|
||||
|
||||
// NeedDeps adds the fields requested by the LoadMode in the packages in Imports. If NeedImports
|
||||
// is not set NeedDeps has no effect.
|
||||
NeedDeps
|
||||
|
||||
// NeedExportsFile adds ExportsFile.
|
||||
NeedExportsFile
|
||||
|
||||
// NeedTypes adds Types, Fset, and IllTyped.
|
||||
NeedTypes
|
||||
|
||||
// NeedSyntax adds Syntax.
|
||||
NeedSyntax
|
||||
|
||||
// NeedTypesInfo adds TypesInfo.
|
||||
NeedTypesInfo
|
||||
|
||||
// NeedTypesSizes adds TypesSizes.
|
||||
NeedTypesSizes
|
||||
)
|
||||
|
||||
const (
|
||||
// LoadFiles finds the packages and computes their source file lists.
|
||||
// Package fields: ID, Name, Errors, GoFiles, and OtherFiles.
|
||||
LoadFiles LoadMode = iota
|
||||
// Package fields: ID, Name, Errors, GoFiles, CompiledGoFiles, and OtherFiles.
|
||||
LoadFiles = NeedName | NeedFiles | NeedCompiledGoFiles
|
||||
|
||||
// LoadImports adds import information for each package
|
||||
// and its dependencies.
|
||||
// Package fields added: Imports.
|
||||
LoadImports
|
||||
LoadImports = LoadFiles | NeedImports | NeedDeps
|
||||
|
||||
// LoadTypes adds type information for package-level
|
||||
// declarations in the packages matching the patterns.
|
||||
// Package fields added: Types, Fset, and IllTyped.
|
||||
// Package fields added: Types, TypesSizes, Fset, and IllTyped.
|
||||
// This mode uses type information provided by the build system when
|
||||
// possible, and may fill in the ExportFile field.
|
||||
LoadTypes
|
||||
LoadTypes = LoadImports | NeedTypes | NeedTypesSizes
|
||||
|
||||
// LoadSyntax adds typed syntax trees for the packages matching the patterns.
|
||||
// Package fields added: Syntax, and TypesInfo, for direct pattern matches only.
|
||||
LoadSyntax
|
||||
LoadSyntax = LoadTypes | NeedSyntax | NeedTypesInfo
|
||||
|
||||
// LoadAllSyntax adds typed syntax trees for the packages matching the patterns
|
||||
// and all dependencies.
|
||||
// Package fields added: Types, Fset, Illtyped, Syntax, and TypesInfo,
|
||||
// Package fields added: Types, Fset, IllTyped, Syntax, and TypesInfo,
|
||||
// for all packages in the import graph.
|
||||
LoadAllSyntax
|
||||
LoadAllSyntax = LoadSyntax
|
||||
)
|
||||
|
||||
// An Config specifies details about how packages should be loaded.
|
||||
// A Config specifies details about how packages should be loaded.
|
||||
// The zero value is a valid configuration.
|
||||
// Calls to Load do not modify this struct.
|
||||
type Config struct {
|
||||
@ -92,7 +137,7 @@ type Config struct {
|
||||
BuildFlags []string
|
||||
|
||||
// Fset provides source position information for syntax trees and types.
|
||||
// If Fset is nil, the loader will create a new FileSet.
|
||||
// If Fset is nil, Load will use a new fileset, but preserve Fset's value.
|
||||
Fset *token.FileSet
|
||||
|
||||
// ParseFile is called to read and parse each file
|
||||
@ -127,9 +172,8 @@ type Config struct {
|
||||
// If the file with the given path already exists, the parser will use the
|
||||
// alternative file contents provided by the map.
|
||||
//
|
||||
// The Package.Imports map may not include packages that are imported only
|
||||
// by the alternative file contents provided by Overlay. This may cause
|
||||
// type-checking to fail.
|
||||
// Overlays provide incomplete support for when a given file doesn't
|
||||
// already exist on disk. See the package doc above for more details.
|
||||
Overlay map[string][]byte
|
||||
}
|
||||
|
||||
@ -139,6 +183,9 @@ type driver func(cfg *Config, patterns ...string) (*driverResponse, error)
|
||||
|
||||
// driverResponse contains the results for a driver query.
|
||||
type driverResponse struct {
|
||||
// Sizes, if not nil, is the types.Sizes to use when type checking.
|
||||
Sizes *types.StdSizes
|
||||
|
||||
// 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 cannot know if it is one of the roots as that requires knowledge of the
|
||||
@ -173,6 +220,7 @@ func Load(cfg *Config, patterns ...string) ([]*Package, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
l.sizes = response.Sizes
|
||||
return l.refine(response.Roots, response.Packages...)
|
||||
}
|
||||
|
||||
@ -249,6 +297,9 @@ type Package struct {
|
||||
// TypesInfo provides type information about the package's syntax trees.
|
||||
// It is set only when Syntax is set.
|
||||
TypesInfo *types.Info
|
||||
|
||||
// TypesSizes provides the effective size function for types in TypesInfo.
|
||||
TypesSizes types.Sizes
|
||||
}
|
||||
|
||||
// An Error describes a problem with a package's metadata, syntax, or types.
|
||||
@ -367,7 +418,14 @@ type loaderPackage struct {
|
||||
type loader struct {
|
||||
pkgs map[string]*loaderPackage
|
||||
Config
|
||||
sizes types.Sizes
|
||||
exportMu sync.Mutex // enforces mutual exclusion of exportdata operations
|
||||
|
||||
// TODO(matloob): Add an implied mode here and use that instead of mode.
|
||||
// Implied mode would contain all the fields we need the data for so we can
|
||||
// get the actually requested fields. We'll zero them out before returning
|
||||
// packages to the user. This will make it easier for us to get the conditions
|
||||
// where we need certain modes right.
|
||||
}
|
||||
|
||||
func newLoader(cfg *Config) *loader {
|
||||
@ -375,6 +433,9 @@ func newLoader(cfg *Config) *loader {
|
||||
if cfg != nil {
|
||||
ld.Config = *cfg
|
||||
}
|
||||
if ld.Config.Mode == 0 {
|
||||
ld.Config.Mode = LoadFiles // Preserve zero behavior of Mode for backwards compatibility.
|
||||
}
|
||||
if ld.Config.Env == nil {
|
||||
ld.Config.Env = os.Environ()
|
||||
}
|
||||
@ -387,7 +448,7 @@ func newLoader(cfg *Config) *loader {
|
||||
}
|
||||
}
|
||||
|
||||
if ld.Mode >= LoadTypes {
|
||||
if ld.Mode&NeedTypes != 0 {
|
||||
if ld.Fset == nil {
|
||||
ld.Fset = token.NewFileSet()
|
||||
}
|
||||
@ -411,28 +472,36 @@ func newLoader(cfg *Config) *loader {
|
||||
// refine connects the supplied packages into a graph and then adds type and
|
||||
// and syntax information as requested by the LoadMode.
|
||||
func (ld *loader) refine(roots []string, list ...*Package) ([]*Package, error) {
|
||||
isRoot := make(map[string]bool, len(roots))
|
||||
for _, root := range roots {
|
||||
isRoot[root] = true
|
||||
rootMap := make(map[string]int, len(roots))
|
||||
for i, root := range roots {
|
||||
rootMap[root] = i
|
||||
}
|
||||
ld.pkgs = make(map[string]*loaderPackage)
|
||||
// first pass, fixup and build the map and roots
|
||||
var initial []*loaderPackage
|
||||
var initial = make([]*loaderPackage, len(roots))
|
||||
for _, pkg := range list {
|
||||
rootIndex := -1
|
||||
if i, found := rootMap[pkg.ID]; found {
|
||||
rootIndex = i
|
||||
}
|
||||
lpkg := &loaderPackage{
|
||||
Package: pkg,
|
||||
needtypes: ld.Mode >= LoadAllSyntax ||
|
||||
ld.Mode >= LoadTypes && isRoot[pkg.ID],
|
||||
needsrc: ld.Mode >= LoadAllSyntax ||
|
||||
ld.Mode >= LoadSyntax && isRoot[pkg.ID] ||
|
||||
Package: pkg,
|
||||
needtypes: (ld.Mode&(NeedTypes|NeedTypesInfo) != 0 && rootIndex < 0) || rootIndex >= 0,
|
||||
needsrc: (ld.Mode&(NeedSyntax|NeedTypesInfo) != 0 && rootIndex < 0) || rootIndex >= 0 ||
|
||||
len(ld.Overlay) > 0 || // Overlays can invalidate export data. TODO(matloob): make this check fine-grained based on dependencies on overlaid files
|
||||
pkg.ExportFile == "" && pkg.PkgPath != "unsafe",
|
||||
}
|
||||
ld.pkgs[lpkg.ID] = lpkg
|
||||
if isRoot[lpkg.ID] {
|
||||
initial = append(initial, lpkg)
|
||||
if rootIndex >= 0 {
|
||||
initial[rootIndex] = lpkg
|
||||
lpkg.initial = true
|
||||
}
|
||||
}
|
||||
for i, root := range roots {
|
||||
if initial[i] == nil {
|
||||
return nil, fmt.Errorf("root package %v is missing", root)
|
||||
}
|
||||
}
|
||||
|
||||
// Materialize the import graph.
|
||||
|
||||
@ -491,14 +560,17 @@ func (ld *loader) refine(roots []string, list ...*Package) ([]*Package, error) {
|
||||
if lpkg.needsrc {
|
||||
srcPkgs = append(srcPkgs, lpkg)
|
||||
}
|
||||
if ld.Mode&NeedTypesSizes != 0 {
|
||||
lpkg.TypesSizes = ld.sizes
|
||||
}
|
||||
stack = stack[:len(stack)-1] // pop
|
||||
lpkg.color = black
|
||||
|
||||
return lpkg.needsrc
|
||||
}
|
||||
|
||||
if ld.Mode < LoadImports {
|
||||
//we do this to drop the stub import packages that we are not even going to try to resolve
|
||||
if ld.Mode&(NeedImports|NeedDeps) == 0 {
|
||||
// We do this to drop the stub import packages that we are not even going to try to resolve.
|
||||
for _, lpkg := range initial {
|
||||
lpkg.Imports = nil
|
||||
}
|
||||
@ -508,17 +580,19 @@ func (ld *loader) refine(roots []string, list ...*Package) ([]*Package, error) {
|
||||
visit(lpkg)
|
||||
}
|
||||
}
|
||||
for _, lpkg := range srcPkgs {
|
||||
// Complete type information is required for the
|
||||
// immediate dependencies of each source package.
|
||||
for _, ipkg := range lpkg.Imports {
|
||||
imp := ld.pkgs[ipkg.ID]
|
||||
imp.needtypes = true
|
||||
if ld.Mode&NeedDeps != 0 { // TODO(matloob): This is only the case if NeedTypes is also set, right?
|
||||
for _, lpkg := range srcPkgs {
|
||||
// Complete type information is required for the
|
||||
// immediate dependencies of each source package.
|
||||
for _, ipkg := range lpkg.Imports {
|
||||
imp := ld.pkgs[ipkg.ID]
|
||||
imp.needtypes = true
|
||||
}
|
||||
}
|
||||
}
|
||||
// Load type data if needed, starting at
|
||||
// the initial packages (roots of the import DAG).
|
||||
if ld.Mode >= LoadTypes {
|
||||
if ld.Mode&NeedTypes != 0 {
|
||||
var wg sync.WaitGroup
|
||||
for _, lpkg := range initial {
|
||||
wg.Add(1)
|
||||
@ -531,16 +605,61 @@ func (ld *loader) refine(roots []string, list ...*Package) ([]*Package, error) {
|
||||
}
|
||||
|
||||
result := make([]*Package, len(initial))
|
||||
importPlaceholders := make(map[string]*Package)
|
||||
for i, lpkg := range initial {
|
||||
result[i] = lpkg.Package
|
||||
}
|
||||
for i := range ld.pkgs {
|
||||
// Clear all unrequested fields, for extra de-Hyrum-ization.
|
||||
if ld.Mode&NeedName == 0 {
|
||||
ld.pkgs[i].Name = ""
|
||||
ld.pkgs[i].PkgPath = ""
|
||||
}
|
||||
if ld.Mode&NeedFiles == 0 {
|
||||
ld.pkgs[i].GoFiles = nil
|
||||
ld.pkgs[i].OtherFiles = nil
|
||||
}
|
||||
if ld.Mode&NeedCompiledGoFiles == 0 {
|
||||
ld.pkgs[i].CompiledGoFiles = nil
|
||||
}
|
||||
if ld.Mode&NeedImports == 0 {
|
||||
ld.pkgs[i].Imports = nil
|
||||
}
|
||||
if ld.Mode&NeedExportsFile == 0 {
|
||||
ld.pkgs[i].ExportFile = ""
|
||||
}
|
||||
if ld.Mode&NeedTypes == 0 {
|
||||
ld.pkgs[i].Types = nil
|
||||
ld.pkgs[i].Fset = nil
|
||||
ld.pkgs[i].IllTyped = false
|
||||
}
|
||||
if ld.Mode&NeedSyntax == 0 {
|
||||
ld.pkgs[i].Syntax = nil
|
||||
}
|
||||
if ld.Mode&NeedTypesInfo == 0 {
|
||||
ld.pkgs[i].TypesInfo = nil
|
||||
}
|
||||
if ld.Mode&NeedTypesSizes == 0 {
|
||||
ld.pkgs[i].TypesSizes = nil
|
||||
}
|
||||
if ld.Mode&NeedDeps == 0 {
|
||||
for j, pkg := range ld.pkgs[i].Imports {
|
||||
ph, ok := importPlaceholders[pkg.ID]
|
||||
if !ok {
|
||||
ph = &Package{ID: pkg.ID}
|
||||
importPlaceholders[pkg.ID] = ph
|
||||
}
|
||||
ld.pkgs[i].Imports[j] = ph
|
||||
}
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// loadRecursive loads the specified package and its dependencies,
|
||||
// recursively, in parallel, in topological order.
|
||||
// It is atomic and idempotent.
|
||||
// Precondition: ld.Mode >= LoadTypes.
|
||||
// Precondition: ld.Mode&NeedTypes.
|
||||
func (ld *loader) loadRecursive(lpkg *loaderPackage) {
|
||||
lpkg.loadOnce.Do(func() {
|
||||
// Load the direct dependencies, in parallel.
|
||||
@ -570,6 +689,7 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) {
|
||||
lpkg.Fset = ld.Fset
|
||||
lpkg.Syntax = []*ast.File{}
|
||||
lpkg.TypesInfo = new(types.Info)
|
||||
lpkg.TypesSizes = ld.sizes
|
||||
return
|
||||
}
|
||||
|
||||
@ -657,6 +777,7 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) {
|
||||
Scopes: make(map[ast.Node]*types.Scope),
|
||||
Selections: make(map[*ast.SelectorExpr]*types.Selection),
|
||||
}
|
||||
lpkg.TypesSizes = ld.sizes
|
||||
|
||||
importer := importerFunc(func(path string) (*types.Package, error) {
|
||||
if path == "unsafe" {
|
||||
@ -683,17 +804,6 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) {
|
||||
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
|
||||
tc := &types.Config{
|
||||
Importer: importer,
|
||||
@ -701,10 +811,10 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) {
|
||||
// Type-check bodies of functions only in non-initial packages.
|
||||
// Example: for import graph A->B->C and initial packages {A,C},
|
||||
// we can ignore function bodies in B.
|
||||
IgnoreFuncBodies: ld.Mode < LoadAllSyntax && !lpkg.initial,
|
||||
IgnoreFuncBodies: (ld.Mode&(NeedDeps|NeedTypesInfo) == 0) && !lpkg.initial,
|
||||
|
||||
Error: appendError,
|
||||
Sizes: sizes,
|
||||
Sizes: ld.sizes,
|
||||
}
|
||||
types.NewChecker(tc, ld.Fset, lpkg.Types, lpkg.TypesInfo).Files(lpkg.Syntax)
|
||||
|
||||
@ -767,6 +877,11 @@ func (ld *loader) parseFiles(filenames []string) ([]*ast.File, []error) {
|
||||
parsed := make([]*ast.File, n)
|
||||
errors := make([]error, n)
|
||||
for i, file := range filenames {
|
||||
if ld.Config.Context.Err() != nil {
|
||||
parsed[i] = nil
|
||||
errors[i] = ld.Config.Context.Err()
|
||||
continue
|
||||
}
|
||||
wg.Add(1)
|
||||
go func(i int, filename string) {
|
||||
ioLimit <- true // wait
|
||||
@ -818,7 +933,16 @@ func (ld *loader) parseFiles(filenames []string) ([]*ast.File, []error) {
|
||||
// the same file.
|
||||
//
|
||||
func sameFile(x, y string) bool {
|
||||
if filepath.Base(x) == filepath.Base(y) { // (optimisation)
|
||||
if x == y {
|
||||
// It could be the case that y doesn't exist.
|
||||
// For instance, it may be an overlay file that
|
||||
// hasn't been written to disk. To handle that case
|
||||
// let x == y through. (We added the exact absolute path
|
||||
// string to the CompiledGoFiles list, so the unwritten
|
||||
// overlay case implies x==y.)
|
||||
return true
|
||||
}
|
||||
if strings.EqualFold(filepath.Base(x), filepath.Base(y)) { // (optimisation)
|
||||
if xi, err := os.Stat(x); err == nil {
|
||||
if yi, err := os.Stat(y); err == nil {
|
||||
return os.SameFile(xi, yi)
|
||||
@ -931,5 +1055,5 @@ func (ld *loader) loadFromExportData(lpkg *loaderPackage) (*types.Package, error
|
||||
}
|
||||
|
||||
func usesExportData(cfg *Config) bool {
|
||||
return LoadTypes <= cfg.Mode && cfg.Mode < LoadAllSyntax
|
||||
return cfg.Mode&NeedExportsFile != 0 || cfg.Mode&NeedTypes != 0 && cfg.Mode&NeedTypesInfo == 0
|
||||
}
|
||||
|
Reference in New Issue
Block a user