Update go dependencies to v1.17.0
This commit is contained in:
parent
67dce30ba6
commit
75c3c47f81
516 changed files with 48300 additions and 15154 deletions
5
vendor/golang.org/x/tools/go/internal/gcimporter/bimport.go
generated
vendored
5
vendor/golang.org/x/tools/go/internal/gcimporter/bimport.go
generated
vendored
|
|
@ -976,10 +976,11 @@ const (
|
|||
aliasTag
|
||||
)
|
||||
|
||||
var predeclOnce sync.Once
|
||||
var predecl []types.Type // initialized lazily
|
||||
|
||||
func predeclared() []types.Type {
|
||||
if predecl == nil {
|
||||
predeclOnce.Do(func() {
|
||||
// initialize lazily to be sure that all
|
||||
// elements have been initialized before
|
||||
predecl = []types.Type{ // basic types
|
||||
|
|
@ -1026,7 +1027,7 @@ func predeclared() []types.Type {
|
|||
// used internally by gc; never used by this package or in .a files
|
||||
anyType{},
|
||||
}
|
||||
}
|
||||
})
|
||||
return predecl
|
||||
}
|
||||
|
||||
|
|
|
|||
27
vendor/golang.org/x/tools/go/internal/packagesdriver/sizes.go
generated
vendored
27
vendor/golang.org/x/tools/go/internal/packagesdriver/sizes.go
generated
vendored
|
|
@ -82,15 +82,28 @@ func GetSizesGolist(ctx context.Context, buildFlags, env []string, dir string, u
|
|||
args = append(args, buildFlags...)
|
||||
args = append(args, "--", "unsafe")
|
||||
stdout, err := InvokeGo(ctx, env, dir, usesExportData, args...)
|
||||
var goarch, compiler string
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if strings.Contains(err.Error(), "cannot find main module") {
|
||||
// User's running outside of a module. All bets are off. Get GOARCH and guess compiler is gc.
|
||||
// TODO(matloob): Is this a problem in practice?
|
||||
envout, enverr := InvokeGo(ctx, env, dir, usesExportData, "env", "GOARCH")
|
||||
if enverr != nil {
|
||||
return nil, err
|
||||
}
|
||||
goarch = strings.TrimSpace(envout.String())
|
||||
compiler = "gc"
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
fields := strings.Fields(stdout.String())
|
||||
if len(fields) < 2 {
|
||||
return nil, fmt.Errorf("could not determine GOARCH and Go compiler")
|
||||
}
|
||||
goarch = fields[0]
|
||||
compiler = fields[1]
|
||||
}
|
||||
fields := strings.Fields(stdout.String())
|
||||
if len(fields) < 2 {
|
||||
return nil, fmt.Errorf("could not determine GOARCH and Go compiler")
|
||||
}
|
||||
goarch := fields[0]
|
||||
compiler := fields[1]
|
||||
return types.SizesFor(compiler, goarch), nil
|
||||
}
|
||||
|
||||
|
|
|
|||
29
vendor/golang.org/x/tools/go/packages/external.go
generated
vendored
29
vendor/golang.org/x/tools/go/packages/external.go
generated
vendored
|
|
@ -16,14 +16,29 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
// Driver
|
||||
// The Driver Protocol
|
||||
//
|
||||
// The driver, given the inputs to a call to Load, returns metadata about the packages specified.
|
||||
// This allows for different build systems to support go/packages by telling go/packages how the
|
||||
// packages' source is organized.
|
||||
// The driver is a binary, either specified by the GOPACKAGESDRIVER environment variable or in
|
||||
// the path as gopackagesdriver. It's given the inputs to load in its argv. See the package
|
||||
// documentation in doc.go for the full description of the patterns that need to be supported.
|
||||
// A driver receives as a JSON-serialized driverRequest struct in standard input and will
|
||||
// produce a JSON-serialized driverResponse (see definition in packages.go) in its standard output.
|
||||
|
||||
// driverRequest is used to provide the portion of Load's Config that is needed by a driver.
|
||||
type driverRequest struct {
|
||||
Command string `json:"command"`
|
||||
Mode LoadMode `json:"mode"`
|
||||
Env []string `json:"env"`
|
||||
BuildFlags []string `json:"build_flags"`
|
||||
Tests bool `json:"tests"`
|
||||
Overlay map[string][]byte `json:"overlay"`
|
||||
Mode LoadMode `json:"mode"`
|
||||
// Env specifies the environment the underlying build system should be run in.
|
||||
Env []string `json:"env"`
|
||||
// BuildFlags are flags that should be passed to the underlying build system.
|
||||
BuildFlags []string `json:"build_flags"`
|
||||
// Tests specifies whether the patterns should also return test packages.
|
||||
Tests bool `json:"tests"`
|
||||
// Overlay maps file paths (relative to the driver's working directory) to the byte contents
|
||||
// of overlay files.
|
||||
Overlay map[string][]byte `json:"overlay"`
|
||||
}
|
||||
|
||||
// findExternalDriver returns the file path of a tool that supplies
|
||||
|
|
|
|||
187
vendor/golang.org/x/tools/go/packages/golist.go
generated
vendored
187
vendor/golang.org/x/tools/go/packages/golist.go
generated
vendored
|
|
@ -13,6 +13,7 @@ import (
|
|||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"regexp"
|
||||
|
|
@ -20,6 +21,7 @@ import (
|
|||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
"unicode"
|
||||
|
||||
"golang.org/x/tools/go/internal/packagesdriver"
|
||||
"golang.org/x/tools/internal/gopathwalk"
|
||||
|
|
@ -71,6 +73,28 @@ func (r *responseDeduper) addRoot(id string) {
|
|||
r.dr.Roots = append(r.dr.Roots, id)
|
||||
}
|
||||
|
||||
// goInfo contains global information from the go tool.
|
||||
type goInfo struct {
|
||||
rootDirs map[string]string
|
||||
env goEnv
|
||||
}
|
||||
|
||||
type goEnv struct {
|
||||
modulesOn bool
|
||||
}
|
||||
|
||||
func determineEnv(cfg *Config) goEnv {
|
||||
buf, err := invokeGo(cfg, "env", "GOMOD")
|
||||
if err != nil {
|
||||
return goEnv{}
|
||||
}
|
||||
gomod := bytes.TrimSpace(buf.Bytes())
|
||||
|
||||
env := goEnv{}
|
||||
env.modulesOn = len(gomod) > 0
|
||||
return env
|
||||
}
|
||||
|
||||
// goListDriver uses the go list command to interpret the patterns and produce
|
||||
// the build system package structure.
|
||||
// See driver for more details.
|
||||
|
|
@ -86,6 +110,28 @@ func goListDriver(cfg *Config, patterns ...string) (*driverResponse, error) {
|
|||
}()
|
||||
}
|
||||
|
||||
// start fetching rootDirs
|
||||
var info goInfo
|
||||
var rootDirsReady, envReady = make(chan struct{}), make(chan struct{})
|
||||
go func() {
|
||||
info.rootDirs = determineRootDirs(cfg)
|
||||
close(rootDirsReady)
|
||||
}()
|
||||
go func() {
|
||||
info.env = determineEnv(cfg)
|
||||
close(envReady)
|
||||
}()
|
||||
getGoInfo := func() *goInfo {
|
||||
<-rootDirsReady
|
||||
<-envReady
|
||||
return &info
|
||||
}
|
||||
|
||||
// always pass getGoInfo to golistDriver
|
||||
golistDriver := func(cfg *Config, patterns ...string) (*driverResponse, error) {
|
||||
return golistDriver(cfg, getGoInfo, patterns...)
|
||||
}
|
||||
|
||||
// Determine files requested in contains patterns
|
||||
var containFiles []string
|
||||
var packagesNamed []string
|
||||
|
|
@ -147,7 +193,7 @@ extractQueries:
|
|||
var containsCandidates []string
|
||||
|
||||
if len(containFiles) != 0 {
|
||||
if err := runContainsQueries(cfg, golistDriver, response, containFiles); err != nil {
|
||||
if err := runContainsQueries(cfg, golistDriver, response, containFiles, getGoInfo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
|
@ -158,7 +204,7 @@ extractQueries:
|
|||
}
|
||||
}
|
||||
|
||||
modifiedPkgs, needPkgs, err := processGolistOverlay(cfg, response)
|
||||
modifiedPkgs, needPkgs, err := processGolistOverlay(cfg, response, getGoInfo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -166,7 +212,7 @@ extractQueries:
|
|||
containsCandidates = append(containsCandidates, modifiedPkgs...)
|
||||
containsCandidates = append(containsCandidates, needPkgs...)
|
||||
}
|
||||
if err := addNeededOverlayPackages(cfg, golistDriver, response, needPkgs); err != nil {
|
||||
if err := addNeededOverlayPackages(cfg, golistDriver, response, needPkgs, getGoInfo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Check candidate packages for containFiles.
|
||||
|
|
@ -198,28 +244,33 @@ extractQueries:
|
|||
return response.dr, nil
|
||||
}
|
||||
|
||||
func addNeededOverlayPackages(cfg *Config, driver driver, response *responseDeduper, pkgs []string) error {
|
||||
func addNeededOverlayPackages(cfg *Config, driver driver, response *responseDeduper, pkgs []string, getGoInfo func() *goInfo) error {
|
||||
if len(pkgs) == 0 {
|
||||
return nil
|
||||
}
|
||||
dr, err := driver(cfg, pkgs...)
|
||||
drivercfg := *cfg
|
||||
if getGoInfo().env.modulesOn {
|
||||
drivercfg.BuildFlags = append(drivercfg.BuildFlags, "-mod=readonly")
|
||||
}
|
||||
dr, err := driver(&drivercfg, pkgs...)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, pkg := range dr.Packages {
|
||||
response.addPackage(pkg)
|
||||
}
|
||||
_, needPkgs, err := processGolistOverlay(cfg, response)
|
||||
_, needPkgs, err := processGolistOverlay(cfg, response, getGoInfo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := addNeededOverlayPackages(cfg, driver, response, needPkgs); err != nil {
|
||||
if err := addNeededOverlayPackages(cfg, driver, response, needPkgs, getGoInfo); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func runContainsQueries(cfg *Config, driver driver, response *responseDeduper, queries []string) error {
|
||||
func runContainsQueries(cfg *Config, driver driver, response *responseDeduper, queries []string, goInfo func() *goInfo) error {
|
||||
for _, query := range queries {
|
||||
// TODO(matloob): Do only one query per directory.
|
||||
fdir := filepath.Dir(query)
|
||||
|
|
@ -240,6 +291,21 @@ func runContainsQueries(cfg *Config, driver driver, response *responseDeduper, q
|
|||
// Return the original error if the attempt to fall back failed.
|
||||
return err
|
||||
}
|
||||
// Special case to handle issue #33482:
|
||||
// If this is a file= query for ad-hoc packages where the file only exists on an overlay,
|
||||
// and exists outside of a module, add the file in for the package.
|
||||
if len(dirResponse.Packages) == 1 && len(dirResponse.Packages) == 1 &&
|
||||
dirResponse.Packages[0].ID == "command-line-arguments" && len(dirResponse.Packages[0].GoFiles) == 0 {
|
||||
filename := filepath.Join(pattern, filepath.Base(query)) // avoid recomputing abspath
|
||||
// TODO(matloob): check if the file is outside of a root dir?
|
||||
for path := range cfg.Overlay {
|
||||
if path == filename {
|
||||
dirResponse.Packages[0].Errors = nil
|
||||
dirResponse.Packages[0].GoFiles = []string{path}
|
||||
dirResponse.Packages[0].CompiledGoFiles = []string{path}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
isRoot := make(map[string]bool, len(dirResponse.Roots))
|
||||
for _, root := range dirResponse.Roots {
|
||||
|
|
@ -316,9 +382,7 @@ func runNamedQueries(cfg *Config, driver driver, response *responseDeduper, quer
|
|||
|
||||
startWalk := time.Now()
|
||||
gopathwalk.Walk(roots, add, gopathwalk.Options{ModulesEnabled: modRoot != "", Debug: debug})
|
||||
if debug {
|
||||
log.Printf("%v for walk", time.Since(startWalk))
|
||||
}
|
||||
cfg.Logf("%v for walk", time.Since(startWalk))
|
||||
|
||||
// Weird special case: the top-level package in a module will be in
|
||||
// whatever directory the user checked the repository out into. It's
|
||||
|
|
@ -569,7 +633,7 @@ func otherFiles(p *jsonPackage) [][]string {
|
|||
// golistDriver uses the "go list" command to expand the pattern
|
||||
// words and return metadata for the specified packages. dir may be
|
||||
// "" and env may be nil, as per os/exec.Command.
|
||||
func golistDriver(cfg *Config, words ...string) (*driverResponse, error) {
|
||||
func golistDriver(cfg *Config, rootsDirs func() *goInfo, words ...string) (*driverResponse, error) {
|
||||
// go list uses the following identifiers in ImportPath and Imports:
|
||||
//
|
||||
// "p" -- importable package or main (command)
|
||||
|
|
@ -610,6 +674,20 @@ func golistDriver(cfg *Config, words ...string) (*driverResponse, error) {
|
|||
return nil, fmt.Errorf("package missing import path: %+v", p)
|
||||
}
|
||||
|
||||
// Work around https://golang.org/issue/33157:
|
||||
// go list -e, when given an absolute path, will find the package contained at
|
||||
// that directory. But when no package exists there, it will return a fake package
|
||||
// with an error and the ImportPath set to the absolute path provided to go list.
|
||||
// Try to convert that absolute path to what its package path would be if it's
|
||||
// contained in a known module or GOPATH entry. This will allow the package to be
|
||||
// properly "reclaimed" when overlays are processed.
|
||||
if filepath.IsAbs(p.ImportPath) && p.Error != nil {
|
||||
pkgPath, ok := getPkgPath(p.ImportPath, rootsDirs)
|
||||
if ok {
|
||||
p.ImportPath = pkgPath
|
||||
}
|
||||
}
|
||||
|
||||
if old, found := seen[p.ImportPath]; found {
|
||||
if !reflect.DeepEqual(p, old) {
|
||||
return nil, fmt.Errorf("internal error: go list gives conflicting information for package %v", p.ImportPath)
|
||||
|
|
@ -713,6 +791,27 @@ func golistDriver(cfg *Config, words ...string) (*driverResponse, error) {
|
|||
return &response, nil
|
||||
}
|
||||
|
||||
// getPkgPath finds the package path of a directory if it's relative to a root directory.
|
||||
func getPkgPath(dir string, goInfo func() *goInfo) (string, bool) {
|
||||
for rdir, rpath := range goInfo().rootDirs {
|
||||
// TODO(matloob): This doesn't properly handle symlinks.
|
||||
r, err := filepath.Rel(rdir, dir)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if rpath != "" {
|
||||
// We choose only ore root even though the directory even it can belong in multiple modules
|
||||
// or GOPATH entries. This is okay because we only need to work with absolute dirs when a
|
||||
// file is missing from disk, for instance when gopls calls go/packages in an overlay.
|
||||
// Once the file is saved, gopls, or the next invocation of the tool will get the correct
|
||||
// result straight from golist.
|
||||
// TODO(matloob): Implement module tiebreaking?
|
||||
return path.Join(rpath, filepath.ToSlash(r)), true
|
||||
}
|
||||
}
|
||||
return "", false
|
||||
}
|
||||
|
||||
// absJoin absolutizes and flattens the lists of files.
|
||||
func absJoin(dir string, fileses ...[]string) (res []string) {
|
||||
for _, files := range fileses {
|
||||
|
|
@ -733,7 +832,7 @@ func golistargs(cfg *Config, words []string) []string {
|
|||
fmt.Sprintf("-compiled=%t", cfg.Mode&(NeedCompiledGoFiles|NeedSyntax|NeedTypesInfo|NeedTypesSizes) != 0),
|
||||
fmt.Sprintf("-test=%t", cfg.Tests),
|
||||
fmt.Sprintf("-export=%t", usesExportData(cfg)),
|
||||
fmt.Sprintf("-deps=%t", cfg.Mode&NeedDeps != 0),
|
||||
fmt.Sprintf("-deps=%t", cfg.Mode&NeedImports != 0),
|
||||
// go list doesn't let you pass -test and -find together,
|
||||
// probably because you'd just get the TestMain.
|
||||
fmt.Sprintf("-find=%t", !cfg.Tests && cfg.Mode&findFlags == 0),
|
||||
|
|
@ -759,11 +858,9 @@ func invokeGo(cfg *Config, args ...string) (*bytes.Buffer, error) {
|
|||
cmd.Dir = cfg.Dir
|
||||
cmd.Stdout = stdout
|
||||
cmd.Stderr = stderr
|
||||
if debug {
|
||||
defer func(start time.Time) {
|
||||
log.Printf("%s for %v, stderr: <<%s>>\n", time.Since(start), cmdDebugStr(cmd, args...), stderr)
|
||||
}(time.Now())
|
||||
}
|
||||
defer func(start time.Time) {
|
||||
cfg.Logf("%s for %v, stderr: <<%s>>\n", time.Since(start), cmdDebugStr(cmd, args...), stderr)
|
||||
}(time.Now())
|
||||
|
||||
if err := cmd.Run(); err != nil {
|
||||
// Check for 'go' executable not being found.
|
||||
|
|
@ -783,6 +880,30 @@ func invokeGo(cfg *Config, args ...string) (*bytes.Buffer, error) {
|
|||
return nil, goTooOldError{fmt.Errorf("unsupported version of go: %s: %s", exitErr, stderr)}
|
||||
}
|
||||
|
||||
// Related to #24854
|
||||
if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "unexpected directory layout") {
|
||||
return nil, fmt.Errorf("%s", stderr.String())
|
||||
}
|
||||
|
||||
// Is there an error running the C compiler in cgo? This will be reported in the "Error" field
|
||||
// and should be suppressed by go list -e.
|
||||
//
|
||||
// This condition is not perfect yet because the error message can include other error messages than runtime/cgo.
|
||||
isPkgPathRune := func(r rune) bool {
|
||||
// From https://golang.org/ref/spec#Import_declarations:
|
||||
// Implementation restriction: A compiler may restrict ImportPaths to non-empty strings
|
||||
// using only characters belonging to Unicode's L, M, N, P, and S general categories
|
||||
// (the Graphic characters without spaces) and may also exclude the
|
||||
// characters !"#$%&'()*,:;<=>?[\]^`{|} and the Unicode replacement character U+FFFD.
|
||||
return unicode.IsOneOf([]*unicode.RangeTable{unicode.L, unicode.M, unicode.N, unicode.P, unicode.S}, r) &&
|
||||
strings.IndexRune("!\"#$%&'()*,:;<=>?[\\]^`{|}\uFFFD", r) == -1
|
||||
}
|
||||
if len(stderr.String()) > 0 && strings.HasPrefix(stderr.String(), "# ") {
|
||||
if strings.HasPrefix(strings.TrimLeftFunc(stderr.String()[len("# "):], isPkgPathRune), "\n") {
|
||||
return stdout, nil
|
||||
}
|
||||
}
|
||||
|
||||
// This error only appears in stderr. See golang.org/cl/166398 for a fix in go list to show
|
||||
// the error in the Err section of stdout in case -e option is provided.
|
||||
// This fix is provided for backwards compatibility.
|
||||
|
|
@ -792,13 +913,43 @@ func invokeGo(cfg *Config, args ...string) (*bytes.Buffer, error) {
|
|||
return bytes.NewBufferString(output), nil
|
||||
}
|
||||
|
||||
// Similar to the previous error, but currently lacks a fix in Go.
|
||||
if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "named files must all be in one directory") {
|
||||
output := fmt.Sprintf(`{"ImportPath": "command-line-arguments","Incomplete": true,"Error": {"Pos": "","Err": %q}}`,
|
||||
strings.Trim(stderr.String(), "\n"))
|
||||
return bytes.NewBufferString(output), nil
|
||||
}
|
||||
|
||||
// Backwards compatibility for Go 1.11 because 1.12 and 1.13 put the directory in the ImportPath.
|
||||
// If the package doesn't exist, put the absolute path of the directory into the error message,
|
||||
// as Go 1.13 list does.
|
||||
const noSuchDirectory = "no such directory"
|
||||
if len(stderr.String()) > 0 && strings.Contains(stderr.String(), noSuchDirectory) {
|
||||
errstr := stderr.String()
|
||||
abspath := strings.TrimSpace(errstr[strings.Index(errstr, noSuchDirectory)+len(noSuchDirectory):])
|
||||
output := fmt.Sprintf(`{"ImportPath": %q,"Incomplete": true,"Error": {"Pos": "","Err": %q}}`,
|
||||
abspath, strings.Trim(stderr.String(), "\n"))
|
||||
return bytes.NewBufferString(output), nil
|
||||
}
|
||||
|
||||
// Workaround for #29280: go list -e has incorrect behavior when an ad-hoc package doesn't exist.
|
||||
// Note that the error message we look for in this case is different that the one looked for above.
|
||||
if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "no such file or directory") {
|
||||
output := fmt.Sprintf(`{"ImportPath": "command-line-arguments","Incomplete": true,"Error": {"Pos": "","Err": %q}}`,
|
||||
strings.Trim(stderr.String(), "\n"))
|
||||
return bytes.NewBufferString(output), nil
|
||||
}
|
||||
|
||||
// Workaround for #34273. go list -e with GO111MODULE=on has incorrect behavior when listing a
|
||||
// directory outside any module.
|
||||
if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "outside available modules") {
|
||||
output := fmt.Sprintf(`{"ImportPath": %q,"Incomplete": true,"Error": {"Pos": "","Err": %q}}`,
|
||||
// TODO(matloob): command-line-arguments isn't correct here.
|
||||
"command-line-arguments", strings.Trim(stderr.String(), "\n"))
|
||||
return bytes.NewBufferString(output), nil
|
||||
|
||||
}
|
||||
|
||||
// Workaround for an instance of golang.org/issue/26755: go list -e will return a non-zero exit
|
||||
// status if there's a dependency on a package that doesn't exist. But it should return
|
||||
// a zero exit status and set an error on that package.
|
||||
|
|
|
|||
42
vendor/golang.org/x/tools/go/packages/golist_overlay.go
generated
vendored
42
vendor/golang.org/x/tools/go/packages/golist_overlay.go
generated
vendored
|
|
@ -10,7 +10,6 @@ import (
|
|||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// processGolistOverlay provides rudimentary support for adding
|
||||
|
|
@ -18,7 +17,7 @@ import (
|
|||
// sometimes incorrect.
|
||||
// TODO(matloob): Handle unsupported cases, including the following:
|
||||
// - determining the correct package to add given a new import path
|
||||
func processGolistOverlay(cfg *Config, response *responseDeduper) (modifiedPkgs, needPkgs []string, err error) {
|
||||
func processGolistOverlay(cfg *Config, response *responseDeduper, rootDirs func() *goInfo) (modifiedPkgs, needPkgs []string, err error) {
|
||||
havePkgs := make(map[string]string) // importPath -> non-test package ID
|
||||
needPkgsSet := make(map[string]bool)
|
||||
modifiedPkgsSet := make(map[string]bool)
|
||||
|
|
@ -29,9 +28,6 @@ func processGolistOverlay(cfg *Config, response *responseDeduper) (modifiedPkgs,
|
|||
havePkgs[pkg.PkgPath] = pkg.ID
|
||||
}
|
||||
|
||||
var rootDirs map[string]string
|
||||
var onceGetRootDirs sync.Once
|
||||
|
||||
// If no new imports are added, it is safe to avoid loading any needPkgs.
|
||||
// Otherwise, it's hard to tell which package is actually being loaded
|
||||
// (due to vendoring) and whether any modified package will show up
|
||||
|
|
@ -42,10 +38,10 @@ func processGolistOverlay(cfg *Config, response *responseDeduper) (modifiedPkgs,
|
|||
for opath, contents := range cfg.Overlay {
|
||||
base := filepath.Base(opath)
|
||||
dir := filepath.Dir(opath)
|
||||
var pkg *Package
|
||||
var pkg *Package // if opath belongs to both a package and its test variant, this will be the test variant
|
||||
var testVariantOf *Package // if opath is a test file, this is the package it is testing
|
||||
var fileExists bool
|
||||
isTest := strings.HasSuffix(opath, "_test.go")
|
||||
isTestFile := strings.HasSuffix(opath, "_test.go")
|
||||
pkgName, ok := extractPackageName(opath, contents)
|
||||
if !ok {
|
||||
// Don't bother adding a file that doesn't even have a parsable package statement
|
||||
|
|
@ -54,20 +50,33 @@ func processGolistOverlay(cfg *Config, response *responseDeduper) (modifiedPkgs,
|
|||
}
|
||||
nextPackage:
|
||||
for _, p := range response.dr.Packages {
|
||||
if pkgName != p.Name {
|
||||
if pkgName != p.Name && p.ID != "command-line-arguments" {
|
||||
continue
|
||||
}
|
||||
for _, f := range p.GoFiles {
|
||||
if !sameFile(filepath.Dir(f), dir) {
|
||||
continue
|
||||
}
|
||||
if isTest && !hasTestFiles(p) {
|
||||
// Make sure to capture information on the package's test variant, if needed.
|
||||
if isTestFile && !hasTestFiles(p) {
|
||||
// TODO(matloob): Are there packages other than the 'production' variant
|
||||
// of a package that this can match? This shouldn't match the test main package
|
||||
// because the file is generated in another directory.
|
||||
testVariantOf = p
|
||||
continue nextPackage
|
||||
}
|
||||
if pkg != nil && p != pkg && pkg.PkgPath == p.PkgPath {
|
||||
// If we've already seen the test variant,
|
||||
// make sure to label which package it is a test variant of.
|
||||
if hasTestFiles(pkg) {
|
||||
testVariantOf = p
|
||||
continue nextPackage
|
||||
}
|
||||
// If we have already seen the package of which this is a test variant.
|
||||
if hasTestFiles(p) {
|
||||
testVariantOf = pkg
|
||||
}
|
||||
}
|
||||
pkg = p
|
||||
if filepath.Base(f) == base {
|
||||
fileExists = true
|
||||
|
|
@ -76,13 +85,10 @@ func processGolistOverlay(cfg *Config, response *responseDeduper) (modifiedPkgs,
|
|||
}
|
||||
// The overlay could have included an entirely new package.
|
||||
if pkg == nil {
|
||||
onceGetRootDirs.Do(func() {
|
||||
rootDirs = determineRootDirs(cfg)
|
||||
})
|
||||
// Try to find the module or gopath dir the file is contained in.
|
||||
// Then for modules, add the module opath to the beginning.
|
||||
var pkgPath string
|
||||
for rdir, rpath := range rootDirs {
|
||||
for rdir, rpath := range rootDirs().rootDirs {
|
||||
// TODO(matloob): This doesn't properly handle symlinks.
|
||||
r, err := filepath.Rel(rdir, dir)
|
||||
if err != nil {
|
||||
|
|
@ -106,7 +112,7 @@ func processGolistOverlay(cfg *Config, response *responseDeduper) (modifiedPkgs,
|
|||
pkgPath += "_test"
|
||||
}
|
||||
id := pkgPath
|
||||
if isTest && !isXTest {
|
||||
if isTestFile && !isXTest {
|
||||
id = fmt.Sprintf("%s [%s.test]", pkgPath, pkgPath)
|
||||
}
|
||||
// Try to reclaim a package with the same id if it exists in the response.
|
||||
|
|
@ -122,7 +128,7 @@ func processGolistOverlay(cfg *Config, response *responseDeduper) (modifiedPkgs,
|
|||
response.addPackage(pkg)
|
||||
havePkgs[pkg.PkgPath] = id
|
||||
// Add the production package's sources for a test variant.
|
||||
if isTest && !isXTest && testVariantOf != nil {
|
||||
if isTestFile && !isXTest && testVariantOf != nil {
|
||||
pkg.GoFiles = append(pkg.GoFiles, testVariantOf.GoFiles...)
|
||||
pkg.CompiledGoFiles = append(pkg.CompiledGoFiles, testVariantOf.CompiledGoFiles...)
|
||||
}
|
||||
|
|
@ -145,12 +151,16 @@ func processGolistOverlay(cfg *Config, response *responseDeduper) (modifiedPkgs,
|
|||
if !found {
|
||||
overlayAddsImports = true
|
||||
// TODO(matloob): Handle cases when the following block isn't correct.
|
||||
// These include imports of test variants, imports of vendored packages, etc.
|
||||
// These include imports of vendored packages, etc.
|
||||
id, ok := havePkgs[imp]
|
||||
if !ok {
|
||||
id = imp
|
||||
}
|
||||
pkg.Imports[imp] = &Package{ID: id}
|
||||
// Add dependencies to the non-test variant version of this package as wel.
|
||||
if testVariantOf != nil {
|
||||
testVariantOf.Imports[imp] = &Package{ID: id}
|
||||
}
|
||||
}
|
||||
}
|
||||
continue
|
||||
|
|
|
|||
118
vendor/golang.org/x/tools/go/packages/packages.go
generated
vendored
118
vendor/golang.org/x/tools/go/packages/packages.go
generated
vendored
|
|
@ -48,8 +48,7 @@ const (
|
|||
// "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 adds the fields requested by the LoadMode in the packages in Imports.
|
||||
NeedDeps
|
||||
|
||||
// NeedExportsFile adds ExportsFile.
|
||||
|
|
@ -75,7 +74,7 @@ const (
|
|||
|
||||
// Deprecated: LoadImports exists for historical compatibility
|
||||
// and should not be used. Please directly specify the needed fields using the Need values.
|
||||
LoadImports = LoadFiles | NeedImports | NeedDeps
|
||||
LoadImports = LoadFiles | NeedImports
|
||||
|
||||
// Deprecated: LoadTypes exists for historical compatibility
|
||||
// and should not be used. Please directly specify the needed fields using the Need values.
|
||||
|
|
@ -87,7 +86,7 @@ const (
|
|||
|
||||
// Deprecated: LoadAllSyntax exists for historical compatibility
|
||||
// and should not be used. Please directly specify the needed fields using the Need values.
|
||||
LoadAllSyntax = LoadSyntax
|
||||
LoadAllSyntax = LoadSyntax | NeedDeps
|
||||
)
|
||||
|
||||
// A Config specifies details about how packages should be loaded.
|
||||
|
|
@ -103,6 +102,12 @@ type Config struct {
|
|||
// If Context is nil, the load cannot be cancelled.
|
||||
Context context.Context
|
||||
|
||||
// Logf is the logger for the config.
|
||||
// If the user provides a logger, debug logging is enabled.
|
||||
// If the GOPACKAGESDEBUG environment variable is set to true,
|
||||
// but the logger is nil, default to log.Printf.
|
||||
Logf func(format string, args ...interface{})
|
||||
|
||||
// Dir is the directory in which to run the build system's query tool
|
||||
// that provides information about the packages.
|
||||
// If Dir is empty, the tool is run in the current directory.
|
||||
|
|
@ -410,11 +415,13 @@ type loader struct {
|
|||
parseCacheMu sync.Mutex
|
||||
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.
|
||||
// Config.Mode contains the implied mode (see impliedLoadMode).
|
||||
// Implied mode contains all the fields we need the data for.
|
||||
// In requestedMode there are the actually requested fields.
|
||||
// We'll zero them out before returning packages to the user.
|
||||
// This makes it easier for us to get the conditions where
|
||||
// we need certain modes right.
|
||||
requestedMode LoadMode
|
||||
}
|
||||
|
||||
type parseValue struct {
|
||||
|
|
@ -429,6 +436,17 @@ func newLoader(cfg *Config) *loader {
|
|||
}
|
||||
if cfg != nil {
|
||||
ld.Config = *cfg
|
||||
// If the user has provided a logger, use it.
|
||||
ld.Config.Logf = cfg.Logf
|
||||
}
|
||||
if ld.Config.Logf == nil {
|
||||
// If the GOPACKAGESDEBUG environment variable is set to true,
|
||||
// but the user has not provided a logger, default to log.Printf.
|
||||
if debug {
|
||||
ld.Config.Logf = log.Printf
|
||||
} else {
|
||||
ld.Config.Logf = func(format string, args ...interface{}) {}
|
||||
}
|
||||
}
|
||||
if ld.Config.Mode == 0 {
|
||||
ld.Config.Mode = NeedName | NeedFiles | NeedCompiledGoFiles // Preserve zero behavior of Mode for backwards compatibility.
|
||||
|
|
@ -445,6 +463,10 @@ func newLoader(cfg *Config) *loader {
|
|||
}
|
||||
}
|
||||
|
||||
// Save the actually requested fields. We'll zero them out before returning packages to the user.
|
||||
ld.requestedMode = ld.Mode
|
||||
ld.Mode = impliedLoadMode(ld.Mode)
|
||||
|
||||
if ld.Mode&NeedTypes != 0 {
|
||||
if ld.Fset == nil {
|
||||
ld.Fset = token.NewFileSet()
|
||||
|
|
@ -459,6 +481,7 @@ func newLoader(cfg *Config) *loader {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ld
|
||||
}
|
||||
|
||||
|
|
@ -479,8 +502,8 @@ func (ld *loader) refine(roots []string, list ...*Package) ([]*Package, error) {
|
|||
}
|
||||
lpkg := &loaderPackage{
|
||||
Package: pkg,
|
||||
needtypes: (ld.Mode&(NeedTypes|NeedTypesInfo) != 0 && rootIndex < 0) || rootIndex >= 0,
|
||||
needsrc: (ld.Mode&(NeedSyntax|NeedTypesInfo) != 0 && rootIndex < 0) || rootIndex >= 0 ||
|
||||
needtypes: (ld.Mode&(NeedTypes|NeedTypesInfo) != 0 && ld.Mode&NeedDeps != 0 && rootIndex < 0) || rootIndex >= 0,
|
||||
needsrc: (ld.Mode&(NeedSyntax|NeedTypesInfo) != 0 && ld.Mode&NeedDeps != 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",
|
||||
}
|
||||
|
|
@ -528,8 +551,7 @@ func (ld *loader) refine(roots []string, list ...*Package) ([]*Package, error) {
|
|||
stack = append(stack, lpkg) // push
|
||||
stubs := lpkg.Imports // the structure form has only stubs with the ID in the Imports
|
||||
// If NeedImports isn't set, the imports fields will all be zeroed out.
|
||||
// If NeedDeps isn't also set we want to keep the stubs.
|
||||
if ld.Mode&NeedImports != 0 && ld.Mode&NeedDeps != 0 {
|
||||
if ld.Mode&NeedImports != 0 {
|
||||
lpkg.Imports = make(map[string]*Package, len(stubs))
|
||||
for importPath, ipkg := range stubs {
|
||||
var importErr error
|
||||
|
|
@ -566,7 +588,7 @@ func (ld *loader) refine(roots []string, list ...*Package) ([]*Package, error) {
|
|||
return lpkg.needsrc
|
||||
}
|
||||
|
||||
if ld.Mode&(NeedImports|NeedDeps) == 0 {
|
||||
if ld.Mode&NeedImports == 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
|
||||
|
|
@ -577,7 +599,7 @@ func (ld *loader) refine(roots []string, list ...*Package) ([]*Package, error) {
|
|||
visit(lpkg)
|
||||
}
|
||||
}
|
||||
if ld.Mode&NeedDeps != 0 { // TODO(matloob): This is only the case if NeedTypes is also set, right?
|
||||
if ld.Mode&NeedImports != 0 && ld.Mode&NeedTypes != 0 {
|
||||
for _, lpkg := range srcPkgs {
|
||||
// Complete type information is required for the
|
||||
// immediate dependencies of each source package.
|
||||
|
|
@ -602,54 +624,44 @@ 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 {
|
||||
if ld.requestedMode&NeedName == 0 {
|
||||
ld.pkgs[i].Name = ""
|
||||
ld.pkgs[i].PkgPath = ""
|
||||
}
|
||||
if ld.Mode&NeedFiles == 0 {
|
||||
if ld.requestedMode&NeedFiles == 0 {
|
||||
ld.pkgs[i].GoFiles = nil
|
||||
ld.pkgs[i].OtherFiles = nil
|
||||
}
|
||||
if ld.Mode&NeedCompiledGoFiles == 0 {
|
||||
if ld.requestedMode&NeedCompiledGoFiles == 0 {
|
||||
ld.pkgs[i].CompiledGoFiles = nil
|
||||
}
|
||||
if ld.Mode&NeedImports == 0 {
|
||||
if ld.requestedMode&NeedImports == 0 {
|
||||
ld.pkgs[i].Imports = nil
|
||||
}
|
||||
if ld.Mode&NeedExportsFile == 0 {
|
||||
if ld.requestedMode&NeedExportsFile == 0 {
|
||||
ld.pkgs[i].ExportFile = ""
|
||||
}
|
||||
if ld.Mode&NeedTypes == 0 {
|
||||
if ld.requestedMode&NeedTypes == 0 {
|
||||
ld.pkgs[i].Types = nil
|
||||
ld.pkgs[i].Fset = nil
|
||||
ld.pkgs[i].IllTyped = false
|
||||
}
|
||||
if ld.Mode&NeedSyntax == 0 {
|
||||
if ld.requestedMode&NeedSyntax == 0 {
|
||||
ld.pkgs[i].Syntax = nil
|
||||
}
|
||||
if ld.Mode&NeedTypesInfo == 0 {
|
||||
if ld.requestedMode&NeedTypesInfo == 0 {
|
||||
ld.pkgs[i].TypesInfo = nil
|
||||
}
|
||||
if ld.Mode&NeedTypesSizes == 0 {
|
||||
if ld.requestedMode&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
|
||||
}
|
||||
|
||||
|
|
@ -670,7 +682,6 @@ func (ld *loader) loadRecursive(lpkg *loaderPackage) {
|
|||
}(imp)
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
ld.loadPackage(lpkg)
|
||||
})
|
||||
}
|
||||
|
|
@ -759,6 +770,14 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) {
|
|||
lpkg.Errors = append(lpkg.Errors, errs...)
|
||||
}
|
||||
|
||||
if len(lpkg.CompiledGoFiles) == 0 && lpkg.ExportFile != "" {
|
||||
// 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.
|
||||
appendError(Error{"-", fmt.Sprintf("sources missing for package %s", lpkg.ID), ParseError})
|
||||
ld.loadFromExportData(lpkg)
|
||||
return // can't get syntax trees for this package
|
||||
}
|
||||
|
||||
files, errs := ld.parseFiles(lpkg.CompiledGoFiles)
|
||||
for _, err := range errs {
|
||||
appendError(err)
|
||||
|
|
@ -797,7 +816,7 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) {
|
|||
if ipkg.Types != nil && ipkg.Types.Complete() {
|
||||
return ipkg.Types, nil
|
||||
}
|
||||
log.Fatalf("internal error: nil Pkg importing %q from %q", path, lpkg)
|
||||
log.Fatalf("internal error: package %q without types was imported from %q", path, lpkg)
|
||||
panic("unreachable")
|
||||
})
|
||||
|
||||
|
|
@ -808,7 +827,7 @@ 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&(NeedDeps|NeedTypesInfo) == 0) && !lpkg.initial,
|
||||
IgnoreFuncBodies: ld.Mode&NeedDeps == 0 && !lpkg.initial,
|
||||
|
||||
Error: appendError,
|
||||
Sizes: ld.sizes,
|
||||
|
|
@ -1070,6 +1089,25 @@ func (ld *loader) loadFromExportData(lpkg *loaderPackage) (*types.Package, error
|
|||
return tpkg, nil
|
||||
}
|
||||
|
||||
func usesExportData(cfg *Config) bool {
|
||||
return cfg.Mode&NeedExportsFile != 0 || cfg.Mode&NeedTypes != 0 && cfg.Mode&NeedTypesInfo == 0
|
||||
// impliedLoadMode returns loadMode with its dependencies.
|
||||
func impliedLoadMode(loadMode LoadMode) LoadMode {
|
||||
if loadMode&NeedTypesInfo != 0 && loadMode&NeedImports == 0 {
|
||||
// If NeedTypesInfo, go/packages needs to do typechecking itself so it can
|
||||
// associate type info with the AST. To do so, we need the export data
|
||||
// for dependencies, which means we need to ask for the direct dependencies.
|
||||
// NeedImports is used to ask for the direct dependencies.
|
||||
loadMode |= NeedImports
|
||||
}
|
||||
|
||||
if loadMode&NeedDeps != 0 && loadMode&NeedImports == 0 {
|
||||
// With NeedDeps we need to load at least direct dependencies.
|
||||
// NeedImports is used to ask for the direct dependencies.
|
||||
loadMode |= NeedImports
|
||||
}
|
||||
|
||||
return loadMode
|
||||
}
|
||||
|
||||
func usesExportData(cfg *Config) bool {
|
||||
return cfg.Mode&NeedExportsFile != 0 || cfg.Mode&NeedTypes != 0 && cfg.Mode&NeedDeps == 0
|
||||
}
|
||||
|
|
|
|||
36
vendor/golang.org/x/tools/internal/gopathwalk/walk.go
generated
vendored
36
vendor/golang.org/x/tools/internal/gopathwalk/walk.go
generated
vendored
|
|
@ -59,15 +59,27 @@ func SrcDirsRoots(ctx *build.Context) []Root {
|
|||
// paths of the containing source directory and the package directory.
|
||||
// add will be called concurrently.
|
||||
func Walk(roots []Root, add func(root Root, dir string), opts Options) {
|
||||
WalkSkip(roots, add, func(Root, string) bool { return false }, opts)
|
||||
}
|
||||
|
||||
// WalkSkip walks Go source directories ($GOROOT, $GOPATH, etc) to find packages.
|
||||
// For each package found, add will be called (concurrently) with the absolute
|
||||
// paths of the containing source directory and the package directory.
|
||||
// For each directory that will be scanned, skip will be called (concurrently)
|
||||
// with the absolute paths of the containing source directory and the directory.
|
||||
// If skip returns false on a directory it will be processed.
|
||||
// add will be called concurrently.
|
||||
// skip will be called concurrently.
|
||||
func WalkSkip(roots []Root, add func(root Root, dir string), skip func(root Root, dir string) bool, opts Options) {
|
||||
for _, root := range roots {
|
||||
walkDir(root, add, opts)
|
||||
walkDir(root, add, skip, opts)
|
||||
}
|
||||
}
|
||||
|
||||
func walkDir(root Root, add func(Root, string), opts Options) {
|
||||
func walkDir(root Root, add func(Root, string), skip func(root Root, dir string) bool, opts Options) {
|
||||
if _, err := os.Stat(root.Path); os.IsNotExist(err) {
|
||||
if opts.Debug {
|
||||
log.Printf("skipping nonexistant directory: %v", root.Path)
|
||||
log.Printf("skipping nonexistent directory: %v", root.Path)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
@ -77,6 +89,7 @@ func walkDir(root Root, add func(Root, string), opts Options) {
|
|||
w := &walker{
|
||||
root: root,
|
||||
add: add,
|
||||
skip: skip,
|
||||
opts: opts,
|
||||
}
|
||||
w.init()
|
||||
|
|
@ -91,9 +104,10 @@ func walkDir(root Root, add func(Root, string), opts Options) {
|
|||
|
||||
// walker is the callback for fastwalk.Walk.
|
||||
type walker struct {
|
||||
root Root // The source directory to scan.
|
||||
add func(Root, string) // The callback that will be invoked for every possible Go package dir.
|
||||
opts Options // Options passed to Walk by the user.
|
||||
root Root // The source directory to scan.
|
||||
add func(Root, string) // The callback that will be invoked for every possible Go package dir.
|
||||
skip func(Root, string) bool // The callback that will be invoked for every dir. dir is skipped if it returns true.
|
||||
opts Options // Options passed to Walk by the user.
|
||||
|
||||
ignoredDirs []os.FileInfo // The ignored directories, loaded from .goimportsignore files.
|
||||
}
|
||||
|
|
@ -151,12 +165,16 @@ func (w *walker) getIgnoredDirs(path string) []string {
|
|||
return ignoredDirs
|
||||
}
|
||||
|
||||
func (w *walker) shouldSkipDir(fi os.FileInfo) bool {
|
||||
func (w *walker) shouldSkipDir(fi os.FileInfo, dir string) bool {
|
||||
for _, ignoredDir := range w.ignoredDirs {
|
||||
if os.SameFile(fi, ignoredDir) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
if w.skip != nil {
|
||||
// Check with the user specified callback.
|
||||
return w.skip(w.root, dir)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
|
|
@ -184,7 +202,7 @@ func (w *walker) walk(path string, typ os.FileMode) error {
|
|||
return filepath.SkipDir
|
||||
}
|
||||
fi, err := os.Lstat(path)
|
||||
if err == nil && w.shouldSkipDir(fi) {
|
||||
if err == nil && w.shouldSkipDir(fi, path) {
|
||||
return filepath.SkipDir
|
||||
}
|
||||
return nil
|
||||
|
|
@ -224,7 +242,7 @@ func (w *walker) shouldTraverse(dir string, fi os.FileInfo) bool {
|
|||
if !ts.IsDir() {
|
||||
return false
|
||||
}
|
||||
if w.shouldSkipDir(ts) {
|
||||
if w.shouldSkipDir(ts, dir) {
|
||||
return false
|
||||
}
|
||||
// Check for symlink loops by statting each directory component
|
||||
|
|
|
|||
358
vendor/golang.org/x/tools/internal/imports/fix.go
generated
vendored
358
vendor/golang.org/x/tools/internal/imports/fix.go
generated
vendored
|
|
@ -13,7 +13,6 @@ import (
|
|||
"go/parser"
|
||||
"go/token"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
|
|
@ -68,10 +67,27 @@ func importGroup(env *ProcessEnv, importPath string) int {
|
|||
return 0
|
||||
}
|
||||
|
||||
// An importInfo represents a single import statement.
|
||||
type importInfo struct {
|
||||
importPath string // import path, e.g. "crypto/rand".
|
||||
name string // import name, e.g. "crand", or "" if none.
|
||||
type ImportFixType int
|
||||
|
||||
const (
|
||||
AddImport ImportFixType = iota
|
||||
DeleteImport
|
||||
SetImportName
|
||||
)
|
||||
|
||||
type ImportFix struct {
|
||||
// StmtInfo represents the import statement this fix will add, remove, or change.
|
||||
StmtInfo ImportInfo
|
||||
// IdentName is the identifier that this fix will add or remove.
|
||||
IdentName string
|
||||
// FixType is the type of fix this is (AddImport, DeleteImport, SetImportName).
|
||||
FixType ImportFixType
|
||||
}
|
||||
|
||||
// An ImportInfo represents a single import statement.
|
||||
type ImportInfo struct {
|
||||
ImportPath string // import path, e.g. "crypto/rand".
|
||||
Name string // import name, e.g. "crand", or "" if none.
|
||||
}
|
||||
|
||||
// A packageInfo represents what's known about a package.
|
||||
|
|
@ -169,10 +185,10 @@ func collectReferences(f *ast.File) references {
|
|||
return refs
|
||||
}
|
||||
|
||||
// collectImports returns all the imports in f, keyed by their package name as
|
||||
// determined by pathToName. Unnamed imports (., _) and "C" are ignored.
|
||||
func collectImports(f *ast.File) []*importInfo {
|
||||
var imports []*importInfo
|
||||
// collectImports returns all the imports in f.
|
||||
// Unnamed imports (., _) and "C" are ignored.
|
||||
func collectImports(f *ast.File) []*ImportInfo {
|
||||
var imports []*ImportInfo
|
||||
for _, imp := range f.Imports {
|
||||
var name string
|
||||
if imp.Name != nil {
|
||||
|
|
@ -182,9 +198,9 @@ func collectImports(f *ast.File) []*importInfo {
|
|||
continue
|
||||
}
|
||||
path := strings.Trim(imp.Path.Value, `"`)
|
||||
imports = append(imports, &importInfo{
|
||||
name: name,
|
||||
importPath: path,
|
||||
imports = append(imports, &ImportInfo{
|
||||
Name: name,
|
||||
ImportPath: path,
|
||||
})
|
||||
}
|
||||
return imports
|
||||
|
|
@ -192,9 +208,9 @@ func collectImports(f *ast.File) []*importInfo {
|
|||
|
||||
// findMissingImport searches pass's candidates for an import that provides
|
||||
// pkg, containing all of syms.
|
||||
func (p *pass) findMissingImport(pkg string, syms map[string]bool) *importInfo {
|
||||
func (p *pass) findMissingImport(pkg string, syms map[string]bool) *ImportInfo {
|
||||
for _, candidate := range p.candidates {
|
||||
pkgInfo, ok := p.knownPackages[candidate.importPath]
|
||||
pkgInfo, ok := p.knownPackages[candidate.ImportPath]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
|
@ -234,27 +250,33 @@ type pass struct {
|
|||
otherFiles []*ast.File // sibling files.
|
||||
|
||||
// Intermediate state, generated by load.
|
||||
existingImports map[string]*importInfo
|
||||
existingImports map[string]*ImportInfo
|
||||
allRefs references
|
||||
missingRefs references
|
||||
|
||||
// Inputs to fix. These can be augmented between successive fix calls.
|
||||
lastTry bool // indicates that this is the last call and fix should clean up as best it can.
|
||||
candidates []*importInfo // candidate imports in priority order.
|
||||
candidates []*ImportInfo // candidate imports in priority order.
|
||||
knownPackages map[string]*packageInfo // information about all known packages.
|
||||
}
|
||||
|
||||
// loadPackageNames saves the package names for everything referenced by imports.
|
||||
func (p *pass) loadPackageNames(imports []*importInfo) error {
|
||||
func (p *pass) loadPackageNames(imports []*ImportInfo) error {
|
||||
if p.env.Debug {
|
||||
p.env.Logf("loading package names for %v packages", len(imports))
|
||||
defer func() {
|
||||
p.env.Logf("done loading package names for %v packages", len(imports))
|
||||
}()
|
||||
}
|
||||
var unknown []string
|
||||
for _, imp := range imports {
|
||||
if _, ok := p.knownPackages[imp.importPath]; ok {
|
||||
if _, ok := p.knownPackages[imp.ImportPath]; ok {
|
||||
continue
|
||||
}
|
||||
unknown = append(unknown, imp.importPath)
|
||||
unknown = append(unknown, imp.ImportPath)
|
||||
}
|
||||
|
||||
names, err := p.env.getResolver().loadPackageNames(unknown, p.srcDir)
|
||||
names, err := p.env.GetResolver().loadPackageNames(unknown, p.srcDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -271,24 +293,24 @@ func (p *pass) loadPackageNames(imports []*importInfo) error {
|
|||
// importIdentifier returns the identifier that imp will introduce. It will
|
||||
// guess if the package name has not been loaded, e.g. because the source
|
||||
// is not available.
|
||||
func (p *pass) importIdentifier(imp *importInfo) string {
|
||||
if imp.name != "" {
|
||||
return imp.name
|
||||
func (p *pass) importIdentifier(imp *ImportInfo) string {
|
||||
if imp.Name != "" {
|
||||
return imp.Name
|
||||
}
|
||||
known := p.knownPackages[imp.importPath]
|
||||
known := p.knownPackages[imp.ImportPath]
|
||||
if known != nil && known.name != "" {
|
||||
return known.name
|
||||
}
|
||||
return importPathToAssumedName(imp.importPath)
|
||||
return importPathToAssumedName(imp.ImportPath)
|
||||
}
|
||||
|
||||
// load reads in everything necessary to run a pass, and reports whether the
|
||||
// file already has all the imports it needs. It fills in p.missingRefs with the
|
||||
// file's missing symbols, if any, or removes unused imports if not.
|
||||
func (p *pass) load() bool {
|
||||
func (p *pass) load() ([]*ImportFix, bool) {
|
||||
p.knownPackages = map[string]*packageInfo{}
|
||||
p.missingRefs = references{}
|
||||
p.existingImports = map[string]*importInfo{}
|
||||
p.existingImports = map[string]*ImportInfo{}
|
||||
|
||||
// Load basic information about the file in question.
|
||||
p.allRefs = collectReferences(p.f)
|
||||
|
|
@ -313,9 +335,9 @@ func (p *pass) load() bool {
|
|||
err := p.loadPackageNames(append(imports, p.candidates...))
|
||||
if err != nil {
|
||||
if p.env.Debug {
|
||||
log.Printf("loading package names: %v", err)
|
||||
p.env.Logf("loading package names: %v", err)
|
||||
}
|
||||
return false
|
||||
return nil, false
|
||||
}
|
||||
}
|
||||
for _, imp := range imports {
|
||||
|
|
@ -334,18 +356,18 @@ func (p *pass) load() bool {
|
|||
}
|
||||
}
|
||||
if len(p.missingRefs) != 0 {
|
||||
return false
|
||||
return nil, false
|
||||
}
|
||||
|
||||
return p.fix()
|
||||
}
|
||||
|
||||
// fix attempts to satisfy missing imports using p.candidates. If it finds
|
||||
// everything, or if p.lastTry is true, it adds the imports it found,
|
||||
// removes anything unused, and returns true.
|
||||
func (p *pass) fix() bool {
|
||||
// everything, or if p.lastTry is true, it updates fixes to add the imports it found,
|
||||
// delete anything unused, and update import names, and returns true.
|
||||
func (p *pass) fix() ([]*ImportFix, bool) {
|
||||
// Find missing imports.
|
||||
var selected []*importInfo
|
||||
var selected []*ImportInfo
|
||||
for left, rights := range p.missingRefs {
|
||||
if imp := p.findMissingImport(left, rights); imp != nil {
|
||||
selected = append(selected, imp)
|
||||
|
|
@ -353,10 +375,11 @@ func (p *pass) fix() bool {
|
|||
}
|
||||
|
||||
if !p.lastTry && len(selected) != len(p.missingRefs) {
|
||||
return false
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// Found everything, or giving up. Add the new imports and remove any unused.
|
||||
var fixes []*ImportFix
|
||||
for _, imp := range p.existingImports {
|
||||
// We deliberately ignore globals here, because we can't be sure
|
||||
// they're in the same package. People do things like put multiple
|
||||
|
|
@ -364,28 +387,80 @@ func (p *pass) fix() bool {
|
|||
// remove imports if they happen to have the same name as a var in
|
||||
// a different package.
|
||||
if _, ok := p.allRefs[p.importIdentifier(imp)]; !ok {
|
||||
astutil.DeleteNamedImport(p.fset, p.f, imp.name, imp.importPath)
|
||||
fixes = append(fixes, &ImportFix{
|
||||
StmtInfo: *imp,
|
||||
IdentName: p.importIdentifier(imp),
|
||||
FixType: DeleteImport,
|
||||
})
|
||||
continue
|
||||
}
|
||||
|
||||
// An existing import may need to update its import name to be correct.
|
||||
if name := p.importSpecName(imp); name != imp.Name {
|
||||
fixes = append(fixes, &ImportFix{
|
||||
StmtInfo: ImportInfo{
|
||||
Name: name,
|
||||
ImportPath: imp.ImportPath,
|
||||
},
|
||||
IdentName: p.importIdentifier(imp),
|
||||
FixType: SetImportName,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
for _, imp := range selected {
|
||||
astutil.AddNamedImport(p.fset, p.f, imp.name, imp.importPath)
|
||||
fixes = append(fixes, &ImportFix{
|
||||
StmtInfo: ImportInfo{
|
||||
Name: p.importSpecName(imp),
|
||||
ImportPath: imp.ImportPath,
|
||||
},
|
||||
IdentName: p.importIdentifier(imp),
|
||||
FixType: AddImport,
|
||||
})
|
||||
}
|
||||
|
||||
if p.loadRealPackageNames {
|
||||
for _, imp := range p.f.Imports {
|
||||
if imp.Name != nil {
|
||||
continue
|
||||
}
|
||||
path := strings.Trim(imp.Path.Value, `""`)
|
||||
ident := p.importIdentifier(&importInfo{importPath: path})
|
||||
if ident != importPathToAssumedName(path) {
|
||||
imp.Name = &ast.Ident{Name: ident, NamePos: imp.Pos()}
|
||||
return fixes, true
|
||||
}
|
||||
|
||||
// importSpecName gets the import name of imp in the import spec.
|
||||
//
|
||||
// When the import identifier matches the assumed import name, the import name does
|
||||
// not appear in the import spec.
|
||||
func (p *pass) importSpecName(imp *ImportInfo) string {
|
||||
// If we did not load the real package names, or the name is already set,
|
||||
// we just return the existing name.
|
||||
if !p.loadRealPackageNames || imp.Name != "" {
|
||||
return imp.Name
|
||||
}
|
||||
|
||||
ident := p.importIdentifier(imp)
|
||||
if ident == importPathToAssumedName(imp.ImportPath) {
|
||||
return "" // ident not needed since the assumed and real names are the same.
|
||||
}
|
||||
return ident
|
||||
}
|
||||
|
||||
// apply will perform the fixes on f in order.
|
||||
func apply(fset *token.FileSet, f *ast.File, fixes []*ImportFix) {
|
||||
for _, fix := range fixes {
|
||||
switch fix.FixType {
|
||||
case DeleteImport:
|
||||
astutil.DeleteNamedImport(fset, f, fix.StmtInfo.Name, fix.StmtInfo.ImportPath)
|
||||
case AddImport:
|
||||
astutil.AddNamedImport(fset, f, fix.StmtInfo.Name, fix.StmtInfo.ImportPath)
|
||||
case SetImportName:
|
||||
// Find the matching import path and change the name.
|
||||
for _, spec := range f.Imports {
|
||||
path := strings.Trim(spec.Path.Value, `"`)
|
||||
if path == fix.StmtInfo.ImportPath {
|
||||
spec.Name = &ast.Ident{
|
||||
Name: fix.StmtInfo.Name,
|
||||
NamePos: spec.Pos(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// assumeSiblingImportsValid assumes that siblings' use of packages is valid,
|
||||
|
|
@ -394,15 +469,15 @@ func (p *pass) assumeSiblingImportsValid() {
|
|||
for _, f := range p.otherFiles {
|
||||
refs := collectReferences(f)
|
||||
imports := collectImports(f)
|
||||
importsByName := map[string]*importInfo{}
|
||||
importsByName := map[string]*ImportInfo{}
|
||||
for _, imp := range imports {
|
||||
importsByName[p.importIdentifier(imp)] = imp
|
||||
}
|
||||
for left, rights := range refs {
|
||||
if imp, ok := importsByName[left]; ok {
|
||||
if _, ok := stdlib[imp.importPath]; ok {
|
||||
if _, ok := stdlib[imp.ImportPath]; ok {
|
||||
// We have the stdlib in memory; no need to guess.
|
||||
rights = stdlib[imp.importPath]
|
||||
rights = stdlib[imp.ImportPath]
|
||||
}
|
||||
p.addCandidate(imp, &packageInfo{
|
||||
// no name; we already know it.
|
||||
|
|
@ -415,9 +490,9 @@ func (p *pass) assumeSiblingImportsValid() {
|
|||
|
||||
// addCandidate adds a candidate import to p, and merges in the information
|
||||
// in pkg.
|
||||
func (p *pass) addCandidate(imp *importInfo, pkg *packageInfo) {
|
||||
func (p *pass) addCandidate(imp *ImportInfo, pkg *packageInfo) {
|
||||
p.candidates = append(p.candidates, imp)
|
||||
if existing, ok := p.knownPackages[imp.importPath]; ok {
|
||||
if existing, ok := p.knownPackages[imp.ImportPath]; ok {
|
||||
if existing.name == "" {
|
||||
existing.name = pkg.name
|
||||
}
|
||||
|
|
@ -425,7 +500,7 @@ func (p *pass) addCandidate(imp *importInfo, pkg *packageInfo) {
|
|||
existing.exports[export] = true
|
||||
}
|
||||
} else {
|
||||
p.knownPackages[imp.importPath] = pkg
|
||||
p.knownPackages[imp.ImportPath] = pkg
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -437,13 +512,24 @@ func (p *pass) addCandidate(imp *importInfo, pkg *packageInfo) {
|
|||
var fixImports = fixImportsDefault
|
||||
|
||||
func fixImportsDefault(fset *token.FileSet, f *ast.File, filename string, env *ProcessEnv) error {
|
||||
abs, err := filepath.Abs(filename)
|
||||
fixes, err := getFixes(fset, f, filename, env)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
apply(fset, f, fixes)
|
||||
return err
|
||||
}
|
||||
|
||||
// getFixes gets the import fixes that need to be made to f in order to fix the imports.
|
||||
// It does not modify the ast.
|
||||
func getFixes(fset *token.FileSet, f *ast.File, filename string, env *ProcessEnv) ([]*ImportFix, error) {
|
||||
abs, err := filepath.Abs(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
srcDir := filepath.Dir(abs)
|
||||
if env.Debug {
|
||||
log.Printf("fixImports(filename=%q), abs=%q, srcDir=%q ...", filename, abs, srcDir)
|
||||
env.Logf("fixImports(filename=%q), abs=%q, srcDir=%q ...", filename, abs, srcDir)
|
||||
}
|
||||
|
||||
// First pass: looking only at f, and using the naive algorithm to
|
||||
|
|
@ -451,8 +537,8 @@ func fixImportsDefault(fset *token.FileSet, f *ast.File, filename string, env *P
|
|||
// complete. We can't add any imports yet, because we don't know
|
||||
// if missing references are actually package vars.
|
||||
p := &pass{fset: fset, f: f, srcDir: srcDir}
|
||||
if p.load() {
|
||||
return nil
|
||||
if fixes, done := p.load(); done {
|
||||
return fixes, nil
|
||||
}
|
||||
|
||||
otherFiles := parseOtherFiles(fset, srcDir, filename)
|
||||
|
|
@ -460,15 +546,15 @@ func fixImportsDefault(fset *token.FileSet, f *ast.File, filename string, env *P
|
|||
// Second pass: add information from other files in the same package,
|
||||
// like their package vars and imports.
|
||||
p.otherFiles = otherFiles
|
||||
if p.load() {
|
||||
return nil
|
||||
if fixes, done := p.load(); done {
|
||||
return fixes, nil
|
||||
}
|
||||
|
||||
// Now we can try adding imports from the stdlib.
|
||||
p.assumeSiblingImportsValid()
|
||||
addStdlibCandidates(p, p.missingRefs)
|
||||
if p.fix() {
|
||||
return nil
|
||||
if fixes, done := p.fix(); done {
|
||||
return fixes, nil
|
||||
}
|
||||
|
||||
// Third pass: get real package names where we had previously used
|
||||
|
|
@ -477,25 +563,50 @@ func fixImportsDefault(fset *token.FileSet, f *ast.File, filename string, env *P
|
|||
p = &pass{fset: fset, f: f, srcDir: srcDir, env: env}
|
||||
p.loadRealPackageNames = true
|
||||
p.otherFiles = otherFiles
|
||||
if p.load() {
|
||||
return nil
|
||||
if fixes, done := p.load(); done {
|
||||
return fixes, nil
|
||||
}
|
||||
|
||||
addStdlibCandidates(p, p.missingRefs)
|
||||
p.assumeSiblingImportsValid()
|
||||
if p.fix() {
|
||||
return nil
|
||||
if fixes, done := p.fix(); done {
|
||||
return fixes, nil
|
||||
}
|
||||
|
||||
// Go look for candidates in $GOPATH, etc. We don't necessarily load
|
||||
// the real exports of sibling imports, so keep assuming their contents.
|
||||
if err := addExternalCandidates(p, p.missingRefs, filename); err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
p.lastTry = true
|
||||
p.fix()
|
||||
return nil
|
||||
fixes, _ := p.fix()
|
||||
return fixes, nil
|
||||
}
|
||||
|
||||
// getAllCandidates gets all of the candidates to be imported, regardless of if they are needed.
|
||||
func getAllCandidates(filename string, env *ProcessEnv) ([]ImportFix, error) {
|
||||
// TODO(suzmue): scan for additional candidates and filter out
|
||||
// current package.
|
||||
|
||||
// Get the stdlib candidates and sort by import path.
|
||||
var paths []string
|
||||
for importPath := range stdlib {
|
||||
paths = append(paths, importPath)
|
||||
}
|
||||
sort.Strings(paths)
|
||||
|
||||
var imports []ImportFix
|
||||
for _, importPath := range paths {
|
||||
imports = append(imports, ImportFix{
|
||||
StmtInfo: ImportInfo{
|
||||
ImportPath: importPath,
|
||||
},
|
||||
IdentName: path.Base(importPath),
|
||||
FixType: AddImport,
|
||||
})
|
||||
}
|
||||
return imports, nil
|
||||
}
|
||||
|
||||
// ProcessEnv contains environment variables and settings that affect the use of
|
||||
|
|
@ -512,7 +623,10 @@ type ProcessEnv struct {
|
|||
// If true, use go/packages regardless of the environment.
|
||||
ForceGoPackages bool
|
||||
|
||||
resolver resolver
|
||||
// Logf is the default logger for the ProcessEnv.
|
||||
Logf func(format string, args ...interface{})
|
||||
|
||||
resolver Resolver
|
||||
}
|
||||
|
||||
func (e *ProcessEnv) env() []string {
|
||||
|
|
@ -534,7 +648,7 @@ func (e *ProcessEnv) env() []string {
|
|||
return env
|
||||
}
|
||||
|
||||
func (e *ProcessEnv) getResolver() resolver {
|
||||
func (e *ProcessEnv) GetResolver() Resolver {
|
||||
if e.resolver != nil {
|
||||
return e.resolver
|
||||
}
|
||||
|
|
@ -548,7 +662,7 @@ func (e *ProcessEnv) getResolver() resolver {
|
|||
e.resolver = &gopathResolver{env: e}
|
||||
return e.resolver
|
||||
}
|
||||
e.resolver = &moduleResolver{env: e}
|
||||
e.resolver = &ModuleResolver{env: e}
|
||||
return e.resolver
|
||||
}
|
||||
|
||||
|
|
@ -577,7 +691,7 @@ func (e *ProcessEnv) invokeGo(args ...string) (*bytes.Buffer, error) {
|
|||
cmd.Dir = e.WorkingDir
|
||||
|
||||
if e.Debug {
|
||||
defer func(start time.Time) { log.Printf("%s for %v", time.Since(start), cmdDebugStr(cmd)) }(time.Now())
|
||||
defer func(start time.Time) { e.Logf("%s for %v", time.Since(start), cmdDebugStr(cmd)) }(time.Now())
|
||||
}
|
||||
if err := cmd.Run(); err != nil {
|
||||
return nil, fmt.Errorf("running go: %v (stderr:\n%s)", err, stderr)
|
||||
|
|
@ -599,7 +713,7 @@ func cmdDebugStr(cmd *exec.Cmd) string {
|
|||
func addStdlibCandidates(pass *pass, refs references) {
|
||||
add := func(pkg string) {
|
||||
pass.addCandidate(
|
||||
&importInfo{importPath: pkg},
|
||||
&ImportInfo{ImportPath: pkg},
|
||||
&packageInfo{name: path.Base(pkg), exports: stdlib[pkg]})
|
||||
}
|
||||
for left := range refs {
|
||||
|
|
@ -617,20 +731,27 @@ func addStdlibCandidates(pass *pass, refs references) {
|
|||
}
|
||||
}
|
||||
|
||||
// A resolver does the build-system-specific parts of goimports.
|
||||
type resolver interface {
|
||||
// A Resolver does the build-system-specific parts of goimports.
|
||||
type Resolver interface {
|
||||
// loadPackageNames loads the package names in importPaths.
|
||||
loadPackageNames(importPaths []string, srcDir string) (map[string]string, error)
|
||||
// scan finds (at least) the packages satisfying refs. The returned slice is unordered.
|
||||
scan(refs references) ([]*pkg, error)
|
||||
// loadExports returns the set of exported symbols in the package at dir.
|
||||
// It returns an error if the package name in dir does not match expectPackage.
|
||||
// loadExports may be called concurrently.
|
||||
loadExports(ctx context.Context, expectPackage string, pkg *pkg) (map[string]bool, error)
|
||||
}
|
||||
|
||||
// gopathResolver implements resolver for GOPATH and module workspaces using go/packages.
|
||||
// gopackagesResolver implements resolver for GOPATH and module workspaces using go/packages.
|
||||
type goPackagesResolver struct {
|
||||
env *ProcessEnv
|
||||
}
|
||||
|
||||
func (r *goPackagesResolver) loadPackageNames(importPaths []string, srcDir string) (map[string]string, error) {
|
||||
if len(importPaths) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
cfg := r.env.newPackagesConfig(packages.LoadFiles)
|
||||
pkgs, err := packages.Load(cfg, importPaths...)
|
||||
if err != nil {
|
||||
|
|
@ -674,15 +795,35 @@ func (r *goPackagesResolver) scan(refs references) ([]*pkg, error) {
|
|||
return scan, nil
|
||||
}
|
||||
|
||||
func (r *goPackagesResolver) loadExports(ctx context.Context, expectPackage string, pkg *pkg) (map[string]bool, error) {
|
||||
if pkg.goPackage == nil {
|
||||
return nil, fmt.Errorf("goPackage not set")
|
||||
}
|
||||
exports := map[string]bool{}
|
||||
fset := token.NewFileSet()
|
||||
for _, fname := range pkg.goPackage.CompiledGoFiles {
|
||||
f, err := parser.ParseFile(fset, fname, nil, 0)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parsing %s: %v", fname, err)
|
||||
}
|
||||
for name := range f.Scope.Objects {
|
||||
if ast.IsExported(name) {
|
||||
exports[name] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
return exports, nil
|
||||
}
|
||||
|
||||
func addExternalCandidates(pass *pass, refs references, filename string) error {
|
||||
dirScan, err := pass.env.getResolver().scan(refs)
|
||||
dirScan, err := pass.env.GetResolver().scan(refs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Search for imports matching potential package references.
|
||||
type result struct {
|
||||
imp *importInfo
|
||||
imp *ImportInfo
|
||||
pkg *packageInfo
|
||||
}
|
||||
results := make(chan result, len(refs))
|
||||
|
|
@ -716,8 +857,8 @@ func addExternalCandidates(pass *pass, refs references, filename string) error {
|
|||
return // No matching package.
|
||||
}
|
||||
|
||||
imp := &importInfo{
|
||||
importPath: found.importPathShort,
|
||||
imp := &ImportInfo{
|
||||
ImportPath: found.importPathShort,
|
||||
}
|
||||
|
||||
pkg := &packageInfo{
|
||||
|
|
@ -784,7 +925,7 @@ func (r *gopathResolver) loadPackageNames(importPaths []string, srcDir string) (
|
|||
return names, nil
|
||||
}
|
||||
|
||||
// importPathToNameGoPath finds out the actual package name, as declared in its .go files.
|
||||
// importPathToName finds out the actual package name, as declared in its .go files.
|
||||
// If there's a problem, it returns "".
|
||||
func importPathToName(env *ProcessEnv, importPath, srcDir string) (packageName string) {
|
||||
// Fast path for standard library without going to disk.
|
||||
|
|
@ -804,8 +945,8 @@ func importPathToName(env *ProcessEnv, importPath, srcDir string) (packageName s
|
|||
}
|
||||
|
||||
// packageDirToName is a faster version of build.Import if
|
||||
// the only thing desired is the package name. It uses build.FindOnly
|
||||
// to find the directory and then only parses one file in the package,
|
||||
// the only thing desired is the package name. Given a directory,
|
||||
// packageDirToName then only parses one file in the package,
|
||||
// trusting that the files in the directory are consistent.
|
||||
func packageDirToName(dir string) (packageName string, err error) {
|
||||
d, err := os.Open(dir)
|
||||
|
|
@ -926,6 +1067,10 @@ func (r *gopathResolver) scan(_ references) ([]*pkg, error) {
|
|||
return result, nil
|
||||
}
|
||||
|
||||
func (r *gopathResolver) loadExports(ctx context.Context, expectPackage string, pkg *pkg) (map[string]bool, error) {
|
||||
return loadExportsFromFiles(ctx, r.env, expectPackage, pkg.dir)
|
||||
}
|
||||
|
||||
// VendorlessPath returns the devendorized version of the import path ipath.
|
||||
// For example, VendorlessPath("foo/bar/vendor/a/b") returns "a/b".
|
||||
func VendorlessPath(ipath string) string {
|
||||
|
|
@ -939,33 +1084,11 @@ func VendorlessPath(ipath string) string {
|
|||
return ipath
|
||||
}
|
||||
|
||||
// loadExports returns the set of exported symbols in the package at dir.
|
||||
// It returns nil on error or if the package name in dir does not match expectPackage.
|
||||
func loadExports(ctx context.Context, env *ProcessEnv, expectPackage string, pkg *pkg) (map[string]bool, error) {
|
||||
if env.Debug {
|
||||
log.Printf("loading exports in dir %s (seeking package %s)", pkg.dir, expectPackage)
|
||||
}
|
||||
if pkg.goPackage != nil {
|
||||
exports := map[string]bool{}
|
||||
fset := token.NewFileSet()
|
||||
for _, fname := range pkg.goPackage.CompiledGoFiles {
|
||||
f, err := parser.ParseFile(fset, fname, nil, 0)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parsing %s: %v", fname, err)
|
||||
}
|
||||
for name := range f.Scope.Objects {
|
||||
if ast.IsExported(name) {
|
||||
exports[name] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
return exports, nil
|
||||
}
|
||||
|
||||
func loadExportsFromFiles(ctx context.Context, env *ProcessEnv, expectPackage string, dir string) (map[string]bool, error) {
|
||||
exports := make(map[string]bool)
|
||||
|
||||
// Look for non-test, buildable .go files which could provide exports.
|
||||
all, err := ioutil.ReadDir(pkg.dir)
|
||||
all, err := ioutil.ReadDir(dir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -975,7 +1098,7 @@ func loadExports(ctx context.Context, env *ProcessEnv, expectPackage string, pkg
|
|||
if !strings.HasSuffix(name, ".go") || strings.HasSuffix(name, "_test.go") {
|
||||
continue
|
||||
}
|
||||
match, err := env.buildContext().MatchFile(pkg.dir, fi.Name())
|
||||
match, err := env.buildContext().MatchFile(dir, fi.Name())
|
||||
if err != nil || !match {
|
||||
continue
|
||||
}
|
||||
|
|
@ -983,7 +1106,7 @@ func loadExports(ctx context.Context, env *ProcessEnv, expectPackage string, pkg
|
|||
}
|
||||
|
||||
if len(files) == 0 {
|
||||
return nil, fmt.Errorf("dir %v contains no buildable, non-test .go files", pkg.dir)
|
||||
return nil, fmt.Errorf("dir %v contains no buildable, non-test .go files", dir)
|
||||
}
|
||||
|
||||
fset := token.NewFileSet()
|
||||
|
|
@ -994,7 +1117,7 @@ func loadExports(ctx context.Context, env *ProcessEnv, expectPackage string, pkg
|
|||
default:
|
||||
}
|
||||
|
||||
fullFile := filepath.Join(pkg.dir, fi.Name())
|
||||
fullFile := filepath.Join(dir, fi.Name())
|
||||
f, err := parser.ParseFile(fset, fullFile, nil, 0)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parsing %s: %v", fullFile, err)
|
||||
|
|
@ -1006,7 +1129,7 @@ func loadExports(ctx context.Context, env *ProcessEnv, expectPackage string, pkg
|
|||
continue
|
||||
}
|
||||
if pkgName != expectPackage {
|
||||
return nil, fmt.Errorf("scan of dir %v is not expected package %v (actually %v)", pkg.dir, expectPackage, pkgName)
|
||||
return nil, fmt.Errorf("scan of dir %v is not expected package %v (actually %v)", dir, expectPackage, pkgName)
|
||||
}
|
||||
for name := range f.Scope.Objects {
|
||||
if ast.IsExported(name) {
|
||||
|
|
@ -1021,7 +1144,7 @@ func loadExports(ctx context.Context, env *ProcessEnv, expectPackage string, pkg
|
|||
exportList = append(exportList, k)
|
||||
}
|
||||
sort.Strings(exportList)
|
||||
log.Printf("loaded exports in dir %v (package %v): %v", pkg.dir, expectPackage, strings.Join(exportList, ", "))
|
||||
env.Logf("loaded exports in dir %v (package %v): %v", dir, expectPackage, strings.Join(exportList, ", "))
|
||||
}
|
||||
return exports, nil
|
||||
}
|
||||
|
|
@ -1058,7 +1181,7 @@ func findImport(ctx context.Context, pass *pass, dirScan []*pkg, pkgName string,
|
|||
sort.Sort(byDistanceOrImportPathShortLength(candidates))
|
||||
if pass.env.Debug {
|
||||
for i, c := range candidates {
|
||||
log.Printf("%s candidate %d/%d: %v in %v", pkgName, i+1, len(candidates), c.pkg.importPathShort, c.pkg.dir)
|
||||
pass.env.Logf("%s candidate %d/%d: %v in %v", pkgName, i+1, len(candidates), c.pkg.importPathShort, c.pkg.dir)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1095,10 +1218,13 @@ func findImport(ctx context.Context, pass *pass, dirScan []*pkg, pkgName string,
|
|||
wg.Done()
|
||||
}()
|
||||
|
||||
exports, err := loadExports(ctx, pass.env, pkgName, c.pkg)
|
||||
if pass.env.Debug {
|
||||
pass.env.Logf("loading exports in dir %s (seeking package %s)", c.pkg.dir, pkgName)
|
||||
}
|
||||
exports, err := pass.env.GetResolver().loadExports(ctx, pkgName, c.pkg)
|
||||
if err != nil {
|
||||
if pass.env.Debug {
|
||||
log.Printf("loading exports in dir %s (seeking package %s): %v", c.pkg.dir, pkgName, err)
|
||||
pass.env.Logf("loading exports in dir %s (seeking package %s): %v", c.pkg.dir, pkgName, err)
|
||||
}
|
||||
resc <- nil
|
||||
return
|
||||
|
|
|
|||
101
vendor/golang.org/x/tools/internal/imports/imports.go
generated
vendored
101
vendor/golang.org/x/tools/internal/imports/imports.go
generated
vendored
|
|
@ -13,12 +13,14 @@ import (
|
|||
"bytes"
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/build"
|
||||
"go/format"
|
||||
"go/parser"
|
||||
"go/printer"
|
||||
"go/token"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
|
@ -41,13 +43,10 @@ type Options struct {
|
|||
}
|
||||
|
||||
// Process implements golang.org/x/tools/imports.Process with explicit context in env.
|
||||
func Process(filename string, src []byte, opt *Options) ([]byte, error) {
|
||||
if src == nil {
|
||||
b, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
src = b
|
||||
func Process(filename string, src []byte, opt *Options) (formatted []byte, err error) {
|
||||
src, opt, err = initialize(filename, src, opt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fileSet := token.NewFileSet()
|
||||
|
|
@ -61,7 +60,93 @@ func Process(filename string, src []byte, opt *Options) ([]byte, error) {
|
|||
return nil, err
|
||||
}
|
||||
}
|
||||
return formatFile(fileSet, file, src, adjust, opt)
|
||||
}
|
||||
|
||||
// FixImports returns a list of fixes to the imports that, when applied,
|
||||
// will leave the imports in the same state as Process.
|
||||
//
|
||||
// Note that filename's directory influences which imports can be chosen,
|
||||
// so it is important that filename be accurate.
|
||||
func FixImports(filename string, src []byte, opt *Options) (fixes []*ImportFix, err error) {
|
||||
src, opt, err = initialize(filename, src, opt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fileSet := token.NewFileSet()
|
||||
file, _, err := parse(fileSet, filename, src, opt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return getFixes(fileSet, file, filename, opt.Env)
|
||||
}
|
||||
|
||||
// ApplyFix will apply all of the fixes to the file and format it.
|
||||
func ApplyFixes(fixes []*ImportFix, filename string, src []byte, opt *Options) (formatted []byte, err error) {
|
||||
src, opt, err = initialize(filename, src, opt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fileSet := token.NewFileSet()
|
||||
file, adjust, err := parse(fileSet, filename, src, opt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Apply the fixes to the file.
|
||||
apply(fileSet, file, fixes)
|
||||
|
||||
return formatFile(fileSet, file, src, adjust, opt)
|
||||
}
|
||||
|
||||
// GetAllCandidates gets all of the standard library candidate packages to import in
|
||||
// sorted order on import path.
|
||||
func GetAllCandidates(filename string, opt *Options) (pkgs []ImportFix, err error) {
|
||||
_, opt, err = initialize(filename, []byte{}, opt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return getAllCandidates(filename, opt.Env)
|
||||
}
|
||||
|
||||
// initialize sets the values for opt and src.
|
||||
// If they are provided, they are not changed. Otherwise opt is set to the
|
||||
// default values and src is read from the file system.
|
||||
func initialize(filename string, src []byte, opt *Options) ([]byte, *Options, error) {
|
||||
// Use defaults if opt is nil.
|
||||
if opt == nil {
|
||||
opt = &Options{Comments: true, TabIndent: true, TabWidth: 8}
|
||||
}
|
||||
|
||||
// Set the env if the user has not provided it.
|
||||
if opt.Env == nil {
|
||||
opt.Env = &ProcessEnv{
|
||||
GOPATH: build.Default.GOPATH,
|
||||
GOROOT: build.Default.GOROOT,
|
||||
}
|
||||
}
|
||||
|
||||
// Set the logger if the user has not provided it.
|
||||
if opt.Env.Logf == nil {
|
||||
opt.Env.Logf = log.Printf
|
||||
}
|
||||
|
||||
if src == nil {
|
||||
b, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
src = b
|
||||
}
|
||||
|
||||
return src, opt, nil
|
||||
}
|
||||
|
||||
func formatFile(fileSet *token.FileSet, file *ast.File, src []byte, adjust func(orig []byte, src []byte) []byte, opt *Options) ([]byte, error) {
|
||||
mergeImports(opt.Env, fileSet, file)
|
||||
sortImports(opt.Env, fileSet, file)
|
||||
imps := astutil.Imports(fileSet, file)
|
||||
var spacesBefore []string // import paths we need spaces before
|
||||
|
|
@ -89,7 +174,7 @@ func Process(filename string, src []byte, opt *Options) ([]byte, error) {
|
|||
printConfig := &printer.Config{Mode: printerMode, Tabwidth: opt.TabWidth}
|
||||
|
||||
var buf bytes.Buffer
|
||||
err = printConfig.Fprint(&buf, fileSet, file)
|
||||
err := printConfig.Fprint(&buf, fileSet, file)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
|||
361
vendor/golang.org/x/tools/internal/imports/mod.go
generated
vendored
361
vendor/golang.org/x/tools/internal/imports/mod.go
generated
vendored
|
|
@ -2,9 +2,10 @@ package imports
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
|
|
@ -19,37 +20,41 @@ import (
|
|||
"golang.org/x/tools/internal/module"
|
||||
)
|
||||
|
||||
// moduleResolver implements resolver for modules using the go command as little
|
||||
// ModuleResolver implements resolver for modules using the go command as little
|
||||
// as feasible.
|
||||
type moduleResolver struct {
|
||||
env *ProcessEnv
|
||||
type ModuleResolver struct {
|
||||
env *ProcessEnv
|
||||
moduleCacheDir string
|
||||
|
||||
initialized bool
|
||||
main *moduleJSON
|
||||
modsByModPath []*moduleJSON // All modules, ordered by # of path components in module Path...
|
||||
modsByDir []*moduleJSON // ...or Dir.
|
||||
Initialized bool
|
||||
Main *ModuleJSON
|
||||
ModsByModPath []*ModuleJSON // All modules, ordered by # of path components in module Path...
|
||||
ModsByDir []*ModuleJSON // ...or Dir.
|
||||
|
||||
// moduleCacheInfo stores information about the module cache.
|
||||
moduleCacheInfo *moduleCacheInfo
|
||||
}
|
||||
|
||||
type moduleJSON struct {
|
||||
type ModuleJSON struct {
|
||||
Path string // module path
|
||||
Version string // module version
|
||||
Versions []string // available module versions (with -versions)
|
||||
Replace *moduleJSON // replaced by this module
|
||||
Replace *ModuleJSON // replaced by this module
|
||||
Time *time.Time // time version was created
|
||||
Update *moduleJSON // available update, if any (with -u)
|
||||
Update *ModuleJSON // available update, if any (with -u)
|
||||
Main bool // is this the main module?
|
||||
Indirect bool // is this module only an indirect dependency of main module?
|
||||
Dir string // directory holding files for this module, if any
|
||||
GoMod string // path to go.mod file for this module, if any
|
||||
Error *moduleErrorJSON // error loading module
|
||||
Error *ModuleErrorJSON // error loading module
|
||||
}
|
||||
|
||||
type moduleErrorJSON struct {
|
||||
type ModuleErrorJSON struct {
|
||||
Err string // the error itself
|
||||
}
|
||||
|
||||
func (r *moduleResolver) init() error {
|
||||
if r.initialized {
|
||||
func (r *ModuleResolver) init() error {
|
||||
if r.Initialized {
|
||||
return nil
|
||||
}
|
||||
stdout, err := r.env.invokeGo("list", "-m", "-json", "...")
|
||||
|
|
@ -57,54 +62,73 @@ func (r *moduleResolver) init() error {
|
|||
return err
|
||||
}
|
||||
for dec := json.NewDecoder(stdout); dec.More(); {
|
||||
mod := &moduleJSON{}
|
||||
mod := &ModuleJSON{}
|
||||
if err := dec.Decode(mod); err != nil {
|
||||
return err
|
||||
}
|
||||
if mod.Dir == "" {
|
||||
if r.env.Debug {
|
||||
log.Printf("module %v has not been downloaded and will be ignored", mod.Path)
|
||||
r.env.Logf("module %v has not been downloaded and will be ignored", mod.Path)
|
||||
}
|
||||
// Can't do anything with a module that's not downloaded.
|
||||
continue
|
||||
}
|
||||
r.modsByModPath = append(r.modsByModPath, mod)
|
||||
r.modsByDir = append(r.modsByDir, mod)
|
||||
r.ModsByModPath = append(r.ModsByModPath, mod)
|
||||
r.ModsByDir = append(r.ModsByDir, mod)
|
||||
if mod.Main {
|
||||
r.main = mod
|
||||
r.Main = mod
|
||||
}
|
||||
}
|
||||
|
||||
sort.Slice(r.modsByModPath, func(i, j int) bool {
|
||||
sort.Slice(r.ModsByModPath, func(i, j int) bool {
|
||||
count := func(x int) int {
|
||||
return strings.Count(r.modsByModPath[x].Path, "/")
|
||||
return strings.Count(r.ModsByModPath[x].Path, "/")
|
||||
}
|
||||
return count(j) < count(i) // descending order
|
||||
})
|
||||
sort.Slice(r.modsByDir, func(i, j int) bool {
|
||||
sort.Slice(r.ModsByDir, func(i, j int) bool {
|
||||
count := func(x int) int {
|
||||
return strings.Count(r.modsByDir[x].Dir, "/")
|
||||
return strings.Count(r.ModsByDir[x].Dir, "/")
|
||||
}
|
||||
return count(j) < count(i) // descending order
|
||||
})
|
||||
|
||||
r.initialized = true
|
||||
if r.moduleCacheInfo == nil {
|
||||
r.moduleCacheInfo = &moduleCacheInfo{
|
||||
modCacheDirInfo: make(map[string]*directoryPackageInfo),
|
||||
}
|
||||
}
|
||||
|
||||
r.Initialized = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// findPackage returns the module and directory that contains the package at
|
||||
// the given import path, or returns nil, "" if no module is in scope.
|
||||
func (r *moduleResolver) findPackage(importPath string) (*moduleJSON, string) {
|
||||
for _, m := range r.modsByModPath {
|
||||
func (r *ModuleResolver) findPackage(importPath string) (*ModuleJSON, string) {
|
||||
// This can't find packages in the stdlib, but that's harmless for all
|
||||
// the existing code paths.
|
||||
for _, m := range r.ModsByModPath {
|
||||
if !strings.HasPrefix(importPath, m.Path) {
|
||||
continue
|
||||
}
|
||||
pathInModule := importPath[len(m.Path):]
|
||||
pkgDir := filepath.Join(m.Dir, pathInModule)
|
||||
if dirIsNestedModule(pkgDir, m) {
|
||||
if r.dirIsNestedModule(pkgDir, m) {
|
||||
continue
|
||||
}
|
||||
|
||||
if info, ok := r.moduleCacheInfo.Load(pkgDir); ok {
|
||||
if packageScanned, err := info.reachedStatus(directoryScanned); packageScanned {
|
||||
if err != nil {
|
||||
// There was some error with scanning this directory.
|
||||
// It does not contain a valid package.
|
||||
continue
|
||||
}
|
||||
return m, pkgDir
|
||||
}
|
||||
}
|
||||
|
||||
pkgFiles, err := ioutil.ReadDir(pkgDir)
|
||||
if err != nil {
|
||||
continue
|
||||
|
|
@ -124,7 +148,7 @@ func (r *moduleResolver) findPackage(importPath string) (*moduleJSON, string) {
|
|||
|
||||
// findModuleByDir returns the module that contains dir, or nil if no such
|
||||
// module is in scope.
|
||||
func (r *moduleResolver) findModuleByDir(dir string) *moduleJSON {
|
||||
func (r *ModuleResolver) findModuleByDir(dir string) *ModuleJSON {
|
||||
// This is quite tricky and may not be correct. dir could be:
|
||||
// - a package in the main module.
|
||||
// - a replace target underneath the main module's directory.
|
||||
|
|
@ -135,12 +159,12 @@ func (r *moduleResolver) findModuleByDir(dir string) *moduleJSON {
|
|||
// - in /vendor/ in -mod=vendor mode.
|
||||
// - nested module? Dunno.
|
||||
// Rumor has it that replace targets cannot contain other replace targets.
|
||||
for _, m := range r.modsByDir {
|
||||
for _, m := range r.ModsByDir {
|
||||
if !strings.HasPrefix(dir, m.Dir) {
|
||||
continue
|
||||
}
|
||||
|
||||
if dirIsNestedModule(dir, m) {
|
||||
if r.dirIsNestedModule(dir, m) {
|
||||
continue
|
||||
}
|
||||
|
||||
|
|
@ -151,18 +175,28 @@ func (r *moduleResolver) findModuleByDir(dir string) *moduleJSON {
|
|||
|
||||
// dirIsNestedModule reports if dir is contained in a nested module underneath
|
||||
// mod, not actually in mod.
|
||||
func dirIsNestedModule(dir string, mod *moduleJSON) bool {
|
||||
func (r *ModuleResolver) dirIsNestedModule(dir string, mod *ModuleJSON) bool {
|
||||
if !strings.HasPrefix(dir, mod.Dir) {
|
||||
return false
|
||||
}
|
||||
mf := findModFile(dir)
|
||||
if r.dirInModuleCache(dir) {
|
||||
// Nested modules in the module cache are pruned,
|
||||
// so it cannot be a nested module.
|
||||
return false
|
||||
}
|
||||
mf := r.findModFile(dir)
|
||||
if mf == "" {
|
||||
return false
|
||||
}
|
||||
return filepath.Dir(mf) != mod.Dir
|
||||
}
|
||||
|
||||
func findModFile(dir string) string {
|
||||
func (r *ModuleResolver) findModFile(dir string) string {
|
||||
if r.dirInModuleCache(dir) {
|
||||
matches := modCacheRegexp.FindStringSubmatch(dir)
|
||||
index := strings.Index(dir, matches[1]+"@"+matches[2])
|
||||
return filepath.Join(dir[:index], matches[1]+"@"+matches[2], "go.mod")
|
||||
}
|
||||
for {
|
||||
f := filepath.Join(dir, "go.mod")
|
||||
info, err := os.Stat(f)
|
||||
|
|
@ -177,7 +211,14 @@ func findModFile(dir string) string {
|
|||
}
|
||||
}
|
||||
|
||||
func (r *moduleResolver) loadPackageNames(importPaths []string, srcDir string) (map[string]string, error) {
|
||||
func (r *ModuleResolver) dirInModuleCache(dir string) bool {
|
||||
if r.moduleCacheDir == "" {
|
||||
return false
|
||||
}
|
||||
return strings.HasPrefix(dir, r.moduleCacheDir)
|
||||
}
|
||||
|
||||
func (r *ModuleResolver) loadPackageNames(importPaths []string, srcDir string) (map[string]string, error) {
|
||||
if err := r.init(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -196,7 +237,7 @@ func (r *moduleResolver) loadPackageNames(importPaths []string, srcDir string) (
|
|||
return names, nil
|
||||
}
|
||||
|
||||
func (r *moduleResolver) scan(_ references) ([]*pkg, error) {
|
||||
func (r *ModuleResolver) scan(_ references) ([]*pkg, error) {
|
||||
if err := r.init(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -205,15 +246,16 @@ func (r *moduleResolver) scan(_ references) ([]*pkg, error) {
|
|||
roots := []gopathwalk.Root{
|
||||
{filepath.Join(r.env.GOROOT, "/src"), gopathwalk.RootGOROOT},
|
||||
}
|
||||
if r.main != nil {
|
||||
roots = append(roots, gopathwalk.Root{r.main.Dir, gopathwalk.RootCurrentModule})
|
||||
if r.Main != nil {
|
||||
roots = append(roots, gopathwalk.Root{r.Main.Dir, gopathwalk.RootCurrentModule})
|
||||
}
|
||||
for _, p := range filepath.SplitList(r.env.GOPATH) {
|
||||
roots = append(roots, gopathwalk.Root{filepath.Join(p, "/pkg/mod"), gopathwalk.RootModuleCache})
|
||||
if r.moduleCacheDir == "" {
|
||||
r.moduleCacheDir = filepath.Join(filepath.SplitList(r.env.GOPATH)[0], "/pkg/mod")
|
||||
}
|
||||
roots = append(roots, gopathwalk.Root{r.moduleCacheDir, gopathwalk.RootModuleCache})
|
||||
|
||||
// Walk replace targets, just in case they're not in any of the above.
|
||||
for _, mod := range r.modsByModPath {
|
||||
for _, mod := range r.ModsByModPath {
|
||||
if mod.Replace != nil {
|
||||
roots = append(roots, gopathwalk.Root{mod.Dir, gopathwalk.RootOther})
|
||||
}
|
||||
|
|
@ -223,87 +265,190 @@ func (r *moduleResolver) scan(_ references) ([]*pkg, error) {
|
|||
dupCheck := make(map[string]bool)
|
||||
var mu sync.Mutex
|
||||
|
||||
gopathwalk.Walk(roots, func(root gopathwalk.Root, dir string) {
|
||||
// Packages in the module cache are immutable. If we have
|
||||
// already seen this package on a previous scan of the module
|
||||
// cache, return that result.
|
||||
skip := func(root gopathwalk.Root, dir string) bool {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
// If we have already processed this directory on this walk, skip it.
|
||||
if _, dup := dupCheck[dir]; dup {
|
||||
return true
|
||||
}
|
||||
|
||||
// If we have saved this directory information, skip it.
|
||||
info, ok := r.moduleCacheInfo.Load(dir)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
// This directory can be skipped as long as we have already scanned it.
|
||||
// Packages with errors will continue to have errors, so there is no need
|
||||
// to rescan them.
|
||||
packageScanned, _ := info.reachedStatus(directoryScanned)
|
||||
return packageScanned
|
||||
}
|
||||
|
||||
add := func(root gopathwalk.Root, dir string) {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
if _, dup := dupCheck[dir]; dup {
|
||||
return
|
||||
}
|
||||
|
||||
dupCheck[dir] = true
|
||||
|
||||
subdir := ""
|
||||
if dir != root.Path {
|
||||
subdir = dir[len(root.Path)+len("/"):]
|
||||
}
|
||||
importPath := filepath.ToSlash(subdir)
|
||||
if strings.HasPrefix(importPath, "vendor/") {
|
||||
// Ignore vendor dirs. If -mod=vendor is on, then things
|
||||
// should mostly just work, but when it's not vendor/
|
||||
// is a mess. There's no easy way to tell if it's on.
|
||||
// We can still find things in the mod cache and
|
||||
// map them into /vendor when -mod=vendor is on.
|
||||
info, err := r.scanDirForPackage(root, dir)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
switch root.Type {
|
||||
case gopathwalk.RootCurrentModule:
|
||||
importPath = path.Join(r.main.Path, filepath.ToSlash(subdir))
|
||||
case gopathwalk.RootModuleCache:
|
||||
matches := modCacheRegexp.FindStringSubmatch(subdir)
|
||||
modPath, err := module.DecodePath(filepath.ToSlash(matches[1]))
|
||||
if err != nil {
|
||||
if r.env.Debug {
|
||||
log.Printf("decoding module cache path %q: %v", subdir, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
importPath = path.Join(modPath, filepath.ToSlash(matches[3]))
|
||||
case gopathwalk.RootGOROOT:
|
||||
importPath = subdir
|
||||
if root.Type == gopathwalk.RootModuleCache {
|
||||
// Save this package information in the cache and return.
|
||||
// Packages from the module cache are added after Walk.
|
||||
r.moduleCacheInfo.Store(dir, info)
|
||||
return
|
||||
}
|
||||
|
||||
// Check if the directory is underneath a module that's in scope.
|
||||
if mod := r.findModuleByDir(dir); mod != nil {
|
||||
// It is. If dir is the target of a replace directive,
|
||||
// our guessed import path is wrong. Use the real one.
|
||||
if mod.Dir == dir {
|
||||
importPath = mod.Path
|
||||
} else {
|
||||
dirInMod := dir[len(mod.Dir)+len("/"):]
|
||||
importPath = path.Join(mod.Path, filepath.ToSlash(dirInMod))
|
||||
}
|
||||
} else {
|
||||
// The package is in an unknown module. Check that it's
|
||||
// not obviously impossible to import.
|
||||
var modFile string
|
||||
switch root.Type {
|
||||
case gopathwalk.RootModuleCache:
|
||||
matches := modCacheRegexp.FindStringSubmatch(subdir)
|
||||
modFile = filepath.Join(matches[1], "@", matches[2], "go.mod")
|
||||
default:
|
||||
modFile = findModFile(dir)
|
||||
}
|
||||
|
||||
modBytes, err := ioutil.ReadFile(modFile)
|
||||
if err == nil && !strings.HasPrefix(importPath, modulePath(modBytes)) {
|
||||
// The module's declared path does not match
|
||||
// its expected path. It probably needs a
|
||||
// replace directive we don't have.
|
||||
return
|
||||
}
|
||||
}
|
||||
// We may have discovered a package that has a different version
|
||||
// in scope already. Canonicalize to that one if possible.
|
||||
if _, canonicalDir := r.findPackage(importPath); canonicalDir != "" {
|
||||
dir = canonicalDir
|
||||
// Skip this package if there was an error loading package info.
|
||||
if info.err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
result = append(result, &pkg{
|
||||
importPathShort: VendorlessPath(importPath),
|
||||
// The rest of this function canonicalizes the packages using the results
|
||||
// of initializing the resolver from 'go list -m'.
|
||||
res, err := r.canonicalize(root.Type, info.nonCanonicalImportPath, info.dir, info.needsReplace)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
result = append(result, res)
|
||||
}
|
||||
|
||||
gopathwalk.WalkSkip(roots, add, skip, gopathwalk.Options{Debug: r.env.Debug, ModulesEnabled: true})
|
||||
|
||||
// Add the packages from the modules in the mod cache that were skipped.
|
||||
for _, dir := range r.moduleCacheInfo.Keys() {
|
||||
info, ok := r.moduleCacheInfo.Load(dir)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
// Skip this directory if we were not able to get the package information successfully.
|
||||
if scanned, err := info.reachedStatus(directoryScanned); !scanned || err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
res, err := r.canonicalize(gopathwalk.RootModuleCache, info.nonCanonicalImportPath, info.dir, info.needsReplace)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
result = append(result, res)
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// canonicalize gets the result of canonicalizing the packages using the results
|
||||
// of initializing the resolver from 'go list -m'.
|
||||
func (r *ModuleResolver) canonicalize(rootType gopathwalk.RootType, importPath, dir string, needsReplace bool) (res *pkg, err error) {
|
||||
// Packages in GOROOT are already canonical, regardless of the std/cmd modules.
|
||||
if rootType == gopathwalk.RootGOROOT {
|
||||
return &pkg{
|
||||
importPathShort: importPath,
|
||||
dir: dir,
|
||||
})
|
||||
}, gopathwalk.Options{Debug: r.env.Debug, ModulesEnabled: true})
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Check if the directory is underneath a module that's in scope.
|
||||
if mod := r.findModuleByDir(dir); mod != nil {
|
||||
// It is. If dir is the target of a replace directive,
|
||||
// our guessed import path is wrong. Use the real one.
|
||||
if mod.Dir == dir {
|
||||
importPath = mod.Path
|
||||
} else {
|
||||
dirInMod := dir[len(mod.Dir)+len("/"):]
|
||||
importPath = path.Join(mod.Path, filepath.ToSlash(dirInMod))
|
||||
}
|
||||
} else if needsReplace {
|
||||
return nil, fmt.Errorf("needed this package to be in scope: %s", dir)
|
||||
}
|
||||
|
||||
// We may have discovered a package that has a different version
|
||||
// in scope already. Canonicalize to that one if possible.
|
||||
if _, canonicalDir := r.findPackage(importPath); canonicalDir != "" {
|
||||
dir = canonicalDir
|
||||
}
|
||||
return &pkg{
|
||||
importPathShort: VendorlessPath(importPath),
|
||||
dir: dir,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (r *ModuleResolver) loadExports(ctx context.Context, expectPackage string, pkg *pkg) (map[string]bool, error) {
|
||||
if err := r.init(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return loadExportsFromFiles(ctx, r.env, expectPackage, pkg.dir)
|
||||
}
|
||||
|
||||
func (r *ModuleResolver) scanDirForPackage(root gopathwalk.Root, dir string) (directoryPackageInfo, error) {
|
||||
subdir := ""
|
||||
if dir != root.Path {
|
||||
subdir = dir[len(root.Path)+len("/"):]
|
||||
}
|
||||
importPath := filepath.ToSlash(subdir)
|
||||
if strings.HasPrefix(importPath, "vendor/") {
|
||||
// Ignore vendor dirs. If -mod=vendor is on, then things
|
||||
// should mostly just work, but when it's not vendor/
|
||||
// is a mess. There's no easy way to tell if it's on.
|
||||
// We can still find things in the mod cache and
|
||||
// map them into /vendor when -mod=vendor is on.
|
||||
return directoryPackageInfo{}, fmt.Errorf("vendor directory")
|
||||
}
|
||||
switch root.Type {
|
||||
case gopathwalk.RootCurrentModule:
|
||||
importPath = path.Join(r.Main.Path, filepath.ToSlash(subdir))
|
||||
case gopathwalk.RootModuleCache:
|
||||
matches := modCacheRegexp.FindStringSubmatch(subdir)
|
||||
if len(matches) == 0 {
|
||||
return directoryPackageInfo{
|
||||
status: directoryScanned,
|
||||
err: fmt.Errorf("invalid module cache path: %v", subdir),
|
||||
}, nil
|
||||
}
|
||||
modPath, err := module.DecodePath(filepath.ToSlash(matches[1]))
|
||||
if err != nil {
|
||||
if r.env.Debug {
|
||||
r.env.Logf("decoding module cache path %q: %v", subdir, err)
|
||||
}
|
||||
return directoryPackageInfo{
|
||||
status: directoryScanned,
|
||||
err: fmt.Errorf("decoding module cache path %q: %v", subdir, err),
|
||||
}, nil
|
||||
}
|
||||
importPath = path.Join(modPath, filepath.ToSlash(matches[3]))
|
||||
case gopathwalk.RootGOROOT:
|
||||
importPath = subdir
|
||||
}
|
||||
|
||||
result := directoryPackageInfo{
|
||||
status: directoryScanned,
|
||||
dir: dir,
|
||||
nonCanonicalImportPath: importPath,
|
||||
needsReplace: false,
|
||||
}
|
||||
if root.Type == gopathwalk.RootGOROOT {
|
||||
// stdlib packages are always in scope, despite the confusing go.mod
|
||||
return result, nil
|
||||
}
|
||||
// Check that this package is not obviously impossible to import.
|
||||
modFile := r.findModFile(dir)
|
||||
|
||||
modBytes, err := ioutil.ReadFile(modFile)
|
||||
if err == nil && !strings.HasPrefix(importPath, modulePath(modBytes)) {
|
||||
// The module's declared path does not match
|
||||
// its expected path. It probably needs a
|
||||
// replace directive we don't have.
|
||||
result.needsReplace = true
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
121
vendor/golang.org/x/tools/internal/imports/mod_cache.go
generated
vendored
Normal file
121
vendor/golang.org/x/tools/internal/imports/mod_cache.go
generated
vendored
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
package imports
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
// ModuleResolver implements Resolver for modules using the go command as little
|
||||
// as feasible.
|
||||
//
|
||||
// To find packages to import, the resolver needs to know about all of the
|
||||
// the packages that could be imported. This includes packages that are
|
||||
// already in modules that are in (1) the current module, (2) replace targets,
|
||||
// and (3) packages in the module cache. Packages in (1) and (2) may change over
|
||||
// time, as the client may edit the current module and locally replaced modules.
|
||||
// The module cache (which includes all of the packages in (3)) can only
|
||||
// ever be added to.
|
||||
//
|
||||
// The resolver can thus save state about packages in the module cache
|
||||
// and guarantee that this will not change over time. To obtain information
|
||||
// about new modules added to the module cache, the module cache should be
|
||||
// rescanned.
|
||||
//
|
||||
// It is OK to serve information about modules that have been deleted,
|
||||
// as they do still exist.
|
||||
// TODO(suzmue): can we share information with the caller about
|
||||
// what module needs to be downloaded to import this package?
|
||||
|
||||
type directoryPackageStatus int
|
||||
|
||||
const (
|
||||
_ directoryPackageStatus = iota
|
||||
directoryScanned
|
||||
)
|
||||
|
||||
type directoryPackageInfo struct {
|
||||
// status indicates the extent to which this struct has been filled in.
|
||||
status directoryPackageStatus
|
||||
// err is non-nil when there was an error trying to reach status.
|
||||
err error
|
||||
|
||||
// Set when status > directoryScanned.
|
||||
|
||||
// dir is the absolute directory of this package.
|
||||
dir string
|
||||
// nonCanonicalImportPath is the expected import path for this package.
|
||||
// This may not be an import path that can be used to import this package.
|
||||
nonCanonicalImportPath string
|
||||
// needsReplace is true if the nonCanonicalImportPath does not match the
|
||||
// the modules declared path, making it impossible to import without a
|
||||
// replace directive.
|
||||
needsReplace bool
|
||||
}
|
||||
|
||||
// reachedStatus returns true when info has a status at least target and any error associated with
|
||||
// an attempt to reach target.
|
||||
func (info *directoryPackageInfo) reachedStatus(target directoryPackageStatus) (bool, error) {
|
||||
if info.err == nil {
|
||||
return info.status >= target, nil
|
||||
}
|
||||
if info.status == target {
|
||||
return true, info.err
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// moduleCacheInfo is a concurrency safe map for storing information about
|
||||
// the directories in the module cache.
|
||||
//
|
||||
// The information in this cache is built incrementally. Entries are initialized in scan.
|
||||
// No new keys should be added in any other functions, as all directories containing
|
||||
// packages are identified in scan.
|
||||
//
|
||||
// Other functions, including loadExports and findPackage, may update entries in this cache
|
||||
// as they discover new things about the directory.
|
||||
//
|
||||
// We do not need to protect the data in the cache for multiple writes, because it only stores
|
||||
// module cache directories, which do not change. If two competing stores take place, there will be
|
||||
// one store that wins. Although this could result in a loss of information it will not be incorrect
|
||||
// and may just result in recomputing the same result later.
|
||||
//
|
||||
// TODO(suzmue): consider other concurrency strategies and data structures (RWLocks, sync.Map, etc)
|
||||
type moduleCacheInfo struct {
|
||||
mu sync.Mutex
|
||||
// modCacheDirInfo stores information about packages in
|
||||
// module cache directories. Keyed by absolute directory.
|
||||
modCacheDirInfo map[string]*directoryPackageInfo
|
||||
}
|
||||
|
||||
// Store stores the package info for dir.
|
||||
func (d *moduleCacheInfo) Store(dir string, info directoryPackageInfo) {
|
||||
d.mu.Lock()
|
||||
defer d.mu.Unlock()
|
||||
d.modCacheDirInfo[dir] = &directoryPackageInfo{
|
||||
status: info.status,
|
||||
err: info.err,
|
||||
dir: info.dir,
|
||||
nonCanonicalImportPath: info.nonCanonicalImportPath,
|
||||
needsReplace: info.needsReplace,
|
||||
}
|
||||
}
|
||||
|
||||
// Load returns a copy of the directoryPackageInfo for absolute directory dir.
|
||||
func (d *moduleCacheInfo) Load(dir string) (directoryPackageInfo, bool) {
|
||||
d.mu.Lock()
|
||||
defer d.mu.Unlock()
|
||||
info, ok := d.modCacheDirInfo[dir]
|
||||
if !ok {
|
||||
return directoryPackageInfo{}, false
|
||||
}
|
||||
return *info, true
|
||||
}
|
||||
|
||||
// Keys returns the keys currently present in d.
|
||||
func (d *moduleCacheInfo) Keys() (keys []string) {
|
||||
d.mu.Lock()
|
||||
defer d.mu.Unlock()
|
||||
for key := range d.modCacheDirInfo {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
return keys
|
||||
}
|
||||
47
vendor/golang.org/x/tools/internal/imports/sortimports.go
generated
vendored
47
vendor/golang.org/x/tools/internal/imports/sortimports.go
generated
vendored
|
|
@ -58,6 +58,53 @@ func sortImports(env *ProcessEnv, fset *token.FileSet, f *ast.File) {
|
|||
}
|
||||
}
|
||||
|
||||
// mergeImports merges all the import declarations into the first one.
|
||||
// Taken from golang.org/x/tools/ast/astutil.
|
||||
func mergeImports(env *ProcessEnv, fset *token.FileSet, f *ast.File) {
|
||||
if len(f.Decls) <= 1 {
|
||||
return
|
||||
}
|
||||
|
||||
// Merge all the import declarations into the first one.
|
||||
var first *ast.GenDecl
|
||||
for i := 0; i < len(f.Decls); i++ {
|
||||
decl := f.Decls[i]
|
||||
gen, ok := decl.(*ast.GenDecl)
|
||||
if !ok || gen.Tok != token.IMPORT || declImports(gen, "C") {
|
||||
continue
|
||||
}
|
||||
if first == nil {
|
||||
first = gen
|
||||
continue // Don't touch the first one.
|
||||
}
|
||||
// We now know there is more than one package in this import
|
||||
// declaration. Ensure that it ends up parenthesized.
|
||||
first.Lparen = first.Pos()
|
||||
// Move the imports of the other import declaration to the first one.
|
||||
for _, spec := range gen.Specs {
|
||||
spec.(*ast.ImportSpec).Path.ValuePos = first.Pos()
|
||||
first.Specs = append(first.Specs, spec)
|
||||
}
|
||||
f.Decls = append(f.Decls[:i], f.Decls[i+1:]...)
|
||||
i--
|
||||
}
|
||||
}
|
||||
|
||||
// declImports reports whether gen contains an import of path.
|
||||
// Taken from golang.org/x/tools/ast/astutil.
|
||||
func declImports(gen *ast.GenDecl, path string) bool {
|
||||
if gen.Tok != token.IMPORT {
|
||||
return false
|
||||
}
|
||||
for _, spec := range gen.Specs {
|
||||
impspec := spec.(*ast.ImportSpec)
|
||||
if importPath(impspec) == path {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func importPath(s ast.Spec) string {
|
||||
t, err := strconv.Unquote(s.(*ast.ImportSpec).Path.Value)
|
||||
if err == nil {
|
||||
|
|
|
|||
116
vendor/golang.org/x/tools/internal/imports/zstdlib.go
generated
vendored
116
vendor/golang.org/x/tools/internal/imports/zstdlib.go
generated
vendored
|
|
@ -125,6 +125,7 @@ var stdlib = map[string]map[string]bool{
|
|||
"ToTitleSpecial": true,
|
||||
"ToUpper": true,
|
||||
"ToUpperSpecial": true,
|
||||
"ToValidUTF8": true,
|
||||
"Trim": true,
|
||||
"TrimFunc": true,
|
||||
"TrimLeft": true,
|
||||
|
|
@ -304,6 +305,18 @@ var stdlib = map[string]map[string]bool{
|
|||
"Sign": true,
|
||||
"Verify": true,
|
||||
},
|
||||
"crypto/ed25519": map[string]bool{
|
||||
"GenerateKey": true,
|
||||
"NewKeyFromSeed": true,
|
||||
"PrivateKey": true,
|
||||
"PrivateKeySize": true,
|
||||
"PublicKey": true,
|
||||
"PublicKeySize": true,
|
||||
"SeedSize": true,
|
||||
"Sign": true,
|
||||
"SignatureSize": true,
|
||||
"Verify": true,
|
||||
},
|
||||
"crypto/elliptic": map[string]bool{
|
||||
"Curve": true,
|
||||
"CurveParams": true,
|
||||
|
|
@ -420,6 +433,7 @@ var stdlib = map[string]map[string]bool{
|
|||
"ECDSAWithP384AndSHA384": true,
|
||||
"ECDSAWithP521AndSHA512": true,
|
||||
"ECDSAWithSHA1": true,
|
||||
"Ed25519": true,
|
||||
"Listen": true,
|
||||
"LoadX509KeyPair": true,
|
||||
"NewLRUClientSessionCache": true,
|
||||
|
|
@ -478,35 +492,36 @@ var stdlib = map[string]map[string]bool{
|
|||
"X509KeyPair": true,
|
||||
},
|
||||
"crypto/x509": map[string]bool{
|
||||
"CANotAuthorizedForExtKeyUsage": true,
|
||||
"CANotAuthorizedForThisName": true,
|
||||
"CertPool": true,
|
||||
"Certificate": true,
|
||||
"CertificateInvalidError": true,
|
||||
"CertificateRequest": true,
|
||||
"ConstraintViolationError": true,
|
||||
"CreateCertificate": true,
|
||||
"CreateCertificateRequest": true,
|
||||
"DSA": true,
|
||||
"DSAWithSHA1": true,
|
||||
"DSAWithSHA256": true,
|
||||
"DecryptPEMBlock": true,
|
||||
"ECDSA": true,
|
||||
"ECDSAWithSHA1": true,
|
||||
"ECDSAWithSHA256": true,
|
||||
"ECDSAWithSHA384": true,
|
||||
"ECDSAWithSHA512": true,
|
||||
"EncryptPEMBlock": true,
|
||||
"ErrUnsupportedAlgorithm": true,
|
||||
"Expired": true,
|
||||
"ExtKeyUsage": true,
|
||||
"ExtKeyUsageAny": true,
|
||||
"ExtKeyUsageClientAuth": true,
|
||||
"ExtKeyUsageCodeSigning": true,
|
||||
"ExtKeyUsageEmailProtection": true,
|
||||
"ExtKeyUsageIPSECEndSystem": true,
|
||||
"ExtKeyUsageIPSECTunnel": true,
|
||||
"ExtKeyUsageIPSECUser": true,
|
||||
"CANotAuthorizedForExtKeyUsage": true,
|
||||
"CANotAuthorizedForThisName": true,
|
||||
"CertPool": true,
|
||||
"Certificate": true,
|
||||
"CertificateInvalidError": true,
|
||||
"CertificateRequest": true,
|
||||
"ConstraintViolationError": true,
|
||||
"CreateCertificate": true,
|
||||
"CreateCertificateRequest": true,
|
||||
"DSA": true,
|
||||
"DSAWithSHA1": true,
|
||||
"DSAWithSHA256": true,
|
||||
"DecryptPEMBlock": true,
|
||||
"ECDSA": true,
|
||||
"ECDSAWithSHA1": true,
|
||||
"ECDSAWithSHA256": true,
|
||||
"ECDSAWithSHA384": true,
|
||||
"ECDSAWithSHA512": true,
|
||||
"Ed25519": true,
|
||||
"EncryptPEMBlock": true,
|
||||
"ErrUnsupportedAlgorithm": true,
|
||||
"Expired": true,
|
||||
"ExtKeyUsage": true,
|
||||
"ExtKeyUsageAny": true,
|
||||
"ExtKeyUsageClientAuth": true,
|
||||
"ExtKeyUsageCodeSigning": true,
|
||||
"ExtKeyUsageEmailProtection": true,
|
||||
"ExtKeyUsageIPSECEndSystem": true,
|
||||
"ExtKeyUsageIPSECTunnel": true,
|
||||
"ExtKeyUsageIPSECUser": true,
|
||||
"ExtKeyUsageMicrosoftCommercialCodeSigning": true,
|
||||
"ExtKeyUsageMicrosoftKernelCodeSigning": true,
|
||||
"ExtKeyUsageMicrosoftServerGatedCrypto": true,
|
||||
|
|
@ -558,6 +573,7 @@ var stdlib = map[string]map[string]bool{
|
|||
"ParsePKCS8PrivateKey": true,
|
||||
"ParsePKIXPublicKey": true,
|
||||
"PublicKeyAlgorithm": true,
|
||||
"PureEd25519": true,
|
||||
"RSA": true,
|
||||
"SHA1WithRSA": true,
|
||||
"SHA256WithRSA": true,
|
||||
|
|
@ -612,8 +628,10 @@ var stdlib = map[string]map[string]bool{
|
|||
"NamedArg": true,
|
||||
"NullBool": true,
|
||||
"NullFloat64": true,
|
||||
"NullInt32": true,
|
||||
"NullInt64": true,
|
||||
"NullString": true,
|
||||
"NullTime": true,
|
||||
"Open": true,
|
||||
"OpenDB": true,
|
||||
"Out": true,
|
||||
|
|
@ -860,6 +878,7 @@ var stdlib = map[string]map[string]bool{
|
|||
"UcharType": true,
|
||||
"UintType": true,
|
||||
"UnspecifiedType": true,
|
||||
"UnsupportedType": true,
|
||||
"VoidType": true,
|
||||
},
|
||||
"debug/elf": map[string]bool{
|
||||
|
|
@ -2505,7 +2524,10 @@ var stdlib = map[string]map[string]bool{
|
|||
"UnsupportedTypeError": true,
|
||||
},
|
||||
"errors": map[string]bool{
|
||||
"New": true,
|
||||
"As": true,
|
||||
"Is": true,
|
||||
"New": true,
|
||||
"Unwrap": true,
|
||||
},
|
||||
"expvar": map[string]bool{
|
||||
"Do": true,
|
||||
|
|
@ -2615,10 +2637,12 @@ var stdlib = map[string]map[string]bool{
|
|||
"CommentMap": true,
|
||||
"CompositeLit": true,
|
||||
"Con": true,
|
||||
"Decl": true,
|
||||
"DeclStmt": true,
|
||||
"DeferStmt": true,
|
||||
"Ellipsis": true,
|
||||
"EmptyStmt": true,
|
||||
"Expr": true,
|
||||
"ExprStmt": true,
|
||||
"Field": true,
|
||||
"FieldFilter": true,
|
||||
|
|
@ -2679,7 +2703,9 @@ var stdlib = map[string]map[string]bool{
|
|||
"SendStmt": true,
|
||||
"SliceExpr": true,
|
||||
"SortImports": true,
|
||||
"Spec": true,
|
||||
"StarExpr": true,
|
||||
"Stmt": true,
|
||||
"StructType": true,
|
||||
"SwitchStmt": true,
|
||||
"Typ": true,
|
||||
|
|
@ -2725,6 +2751,7 @@ var stdlib = map[string]map[string]bool{
|
|||
"Int": true,
|
||||
"Int64Val": true,
|
||||
"Kind": true,
|
||||
"Make": true,
|
||||
"MakeBool": true,
|
||||
"MakeFloat64": true,
|
||||
"MakeFromBytes": true,
|
||||
|
|
@ -2746,6 +2773,8 @@ var stdlib = map[string]map[string]bool{
|
|||
"Uint64Val": true,
|
||||
"UnaryOp": true,
|
||||
"Unknown": true,
|
||||
"Val": true,
|
||||
"Value": true,
|
||||
},
|
||||
"go/doc": map[string]bool{
|
||||
"AllDecls": true,
|
||||
|
|
@ -2855,6 +2884,9 @@ var stdlib = map[string]map[string]bool{
|
|||
"INC": true,
|
||||
"INT": true,
|
||||
"INTERFACE": true,
|
||||
"IsExported": true,
|
||||
"IsIdentifier": true,
|
||||
"IsKeyword": true,
|
||||
"LAND": true,
|
||||
"LBRACE": true,
|
||||
"LBRACK": true,
|
||||
|
|
@ -2916,6 +2948,7 @@ var stdlib = map[string]map[string]bool{
|
|||
"Byte": true,
|
||||
"Chan": true,
|
||||
"ChanDir": true,
|
||||
"CheckExpr": true,
|
||||
"Checker": true,
|
||||
"Comparable": true,
|
||||
"Complex128": true,
|
||||
|
|
@ -2991,6 +3024,7 @@ var stdlib = map[string]map[string]bool{
|
|||
"NewTypeName": true,
|
||||
"NewVar": true,
|
||||
"Nil": true,
|
||||
"Object": true,
|
||||
"ObjectString": true,
|
||||
"Package": true,
|
||||
"PkgName": true,
|
||||
|
|
@ -3349,6 +3383,7 @@ var stdlib = map[string]map[string]bool{
|
|||
"SetFlags": true,
|
||||
"SetOutput": true,
|
||||
"SetPrefix": true,
|
||||
"Writer": true,
|
||||
},
|
||||
"log/syslog": map[string]bool{
|
||||
"Dial": true,
|
||||
|
|
@ -3801,6 +3836,7 @@ var stdlib = map[string]map[string]bool{
|
|||
"MethodTrace": true,
|
||||
"NewFileTransport": true,
|
||||
"NewRequest": true,
|
||||
"NewRequestWithContext": true,
|
||||
"NewServeMux": true,
|
||||
"NoBody": true,
|
||||
"NotFound": true,
|
||||
|
|
@ -3825,6 +3861,7 @@ var stdlib = map[string]map[string]bool{
|
|||
"SameSite": true,
|
||||
"SameSiteDefaultMode": true,
|
||||
"SameSiteLaxMode": true,
|
||||
"SameSiteNoneMode": true,
|
||||
"SameSiteStrictMode": true,
|
||||
"Serve": true,
|
||||
"ServeContent": true,
|
||||
|
|
@ -3846,6 +3883,7 @@ var stdlib = map[string]map[string]bool{
|
|||
"StatusConflict": true,
|
||||
"StatusContinue": true,
|
||||
"StatusCreated": true,
|
||||
"StatusEarlyHints": true,
|
||||
"StatusExpectationFailed": true,
|
||||
"StatusFailedDependency": true,
|
||||
"StatusForbidden": true,
|
||||
|
|
@ -4163,6 +4201,7 @@ var stdlib = map[string]map[string]bool{
|
|||
"Truncate": true,
|
||||
"Unsetenv": true,
|
||||
"UserCacheDir": true,
|
||||
"UserConfigDir": true,
|
||||
"UserHomeDir": true,
|
||||
},
|
||||
"os/exec": map[string]bool{
|
||||
|
|
@ -4293,6 +4332,7 @@ var stdlib = map[string]map[string]bool{
|
|||
"StructOf": true,
|
||||
"StructTag": true,
|
||||
"Swapper": true,
|
||||
"Type": true,
|
||||
"TypeOf": true,
|
||||
"Uint": true,
|
||||
"Uint16": true,
|
||||
|
|
@ -4588,6 +4628,7 @@ var stdlib = map[string]map[string]bool{
|
|||
"ToTitleSpecial": true,
|
||||
"ToUpper": true,
|
||||
"ToUpperSpecial": true,
|
||||
"ToValidUTF8": true,
|
||||
"Trim": true,
|
||||
"TrimFunc": true,
|
||||
"TrimLeft": true,
|
||||
|
|
@ -7989,6 +8030,7 @@ var stdlib = map[string]map[string]bool{
|
|||
"Rmdir": true,
|
||||
"RouteMessage": true,
|
||||
"RouteRIB": true,
|
||||
"RoutingMessage": true,
|
||||
"RtAttr": true,
|
||||
"RtGenmsg": true,
|
||||
"RtMetrics": true,
|
||||
|
|
@ -9357,6 +9399,7 @@ var stdlib = map[string]map[string]bool{
|
|||
"SlicePtrFromStrings": true,
|
||||
"SockFilter": true,
|
||||
"SockFprog": true,
|
||||
"Sockaddr": true,
|
||||
"SockaddrDatalink": true,
|
||||
"SockaddrGen": true,
|
||||
"SockaddrInet4": true,
|
||||
|
|
@ -9784,6 +9827,8 @@ var stdlib = map[string]map[string]bool{
|
|||
"XP1_UNI_SEND": true,
|
||||
},
|
||||
"syscall/js": map[string]bool{
|
||||
"CopyBytesToGo": true,
|
||||
"CopyBytesToJS": true,
|
||||
"Error": true,
|
||||
"Func": true,
|
||||
"FuncOf": true,
|
||||
|
|
@ -9798,8 +9843,6 @@ var stdlib = map[string]map[string]bool{
|
|||
"TypeString": true,
|
||||
"TypeSymbol": true,
|
||||
"TypeUndefined": true,
|
||||
"TypedArray": true,
|
||||
"TypedArrayOf": true,
|
||||
"Undefined": true,
|
||||
"Value": true,
|
||||
"ValueError": true,
|
||||
|
|
@ -9815,6 +9858,7 @@ var stdlib = map[string]map[string]bool{
|
|||
"CoverBlock": true,
|
||||
"CoverMode": true,
|
||||
"Coverage": true,
|
||||
"Init": true,
|
||||
"InternalBenchmark": true,
|
||||
"InternalExample": true,
|
||||
"InternalTest": true,
|
||||
|
|
@ -9828,6 +9872,7 @@ var stdlib = map[string]map[string]bool{
|
|||
"RunTests": true,
|
||||
"Short": true,
|
||||
"T": true,
|
||||
"TB": true,
|
||||
"Verbose": true,
|
||||
},
|
||||
"testing/iotest": map[string]bool{
|
||||
|
|
@ -10063,6 +10108,7 @@ var stdlib = map[string]map[string]bool{
|
|||
"Devanagari": true,
|
||||
"Diacritic": true,
|
||||
"Digit": true,
|
||||
"Dogra": true,
|
||||
"Duployan": true,
|
||||
"Egyptian_Hieroglyphs": true,
|
||||
"Elbasan": true,
|
||||
|
|
@ -10077,9 +10123,11 @@ var stdlib = map[string]map[string]bool{
|
|||
"GraphicRanges": true,
|
||||
"Greek": true,
|
||||
"Gujarati": true,
|
||||
"Gunjala_Gondi": true,
|
||||
"Gurmukhi": true,
|
||||
"Han": true,
|
||||
"Hangul": true,
|
||||
"Hanifi_Rohingya": true,
|
||||
"Hanunoo": true,
|
||||
"Hatran": true,
|
||||
"Hebrew": true,
|
||||
|
|
@ -10140,6 +10188,7 @@ var stdlib = map[string]map[string]bool{
|
|||
"Lydian": true,
|
||||
"M": true,
|
||||
"Mahajani": true,
|
||||
"Makasar": true,
|
||||
"Malayalam": true,
|
||||
"Mandaic": true,
|
||||
"Manichaean": true,
|
||||
|
|
@ -10152,6 +10201,7 @@ var stdlib = map[string]map[string]bool{
|
|||
"MaxRune": true,
|
||||
"Mc": true,
|
||||
"Me": true,
|
||||
"Medefaidrin": true,
|
||||
"Meetei_Mayek": true,
|
||||
"Mende_Kikakui": true,
|
||||
"Meroitic_Cursive": true,
|
||||
|
|
@ -10181,6 +10231,7 @@ var stdlib = map[string]map[string]bool{
|
|||
"Old_North_Arabian": true,
|
||||
"Old_Permic": true,
|
||||
"Old_Persian": true,
|
||||
"Old_Sogdian": true,
|
||||
"Old_South_Arabian": true,
|
||||
"Old_Turkic": true,
|
||||
"Oriya": true,
|
||||
|
|
@ -10241,6 +10292,7 @@ var stdlib = map[string]map[string]bool{
|
|||
"Sm": true,
|
||||
"So": true,
|
||||
"Soft_Dotted": true,
|
||||
"Sogdian": true,
|
||||
"Sora_Sompeng": true,
|
||||
"Soyombo": true,
|
||||
"Space": true,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue