update golang.org/x/tools
This brings in the upstream fix
1aadbdfdbb
. (Upstream
issue is https://github.com/golang/go/issues/31163).
To create this commit, I did:
vgo get golang.org/x/tools
make update_deps
cd cmd/golangci-lint
go install -ldflags "-X 'main.version=$(git describe --tags)' -X 'main.commit=$(git rev-parse --short HEAD)' -X 'main.date=$(date)'"
Fixes #500
This commit is contained in:
parent
a871320784
commit
127f89f072
2
go.mod
2
go.mod
@ -52,7 +52,7 @@ require (
|
|||||||
golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a // indirect
|
golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a // indirect
|
||||||
golang.org/x/net v0.0.0-20190313220215-9f648a60d977 // indirect
|
golang.org/x/net v0.0.0-20190313220215-9f648a60d977 // indirect
|
||||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313 // indirect
|
golang.org/x/sys v0.0.0-20190312061237-fead79001313 // indirect
|
||||||
golang.org/x/tools v0.0.0-20190314010720-f0bfdbff1f9c
|
golang.org/x/tools v0.0.0-20190420000508-685fecacd0a0
|
||||||
gopkg.in/airbrake/gobrake.v2 v2.0.9 // indirect
|
gopkg.in/airbrake/gobrake.v2 v2.0.9 // indirect
|
||||||
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2 // indirect
|
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2 // indirect
|
||||||
gopkg.in/yaml.v2 v2.2.1
|
gopkg.in/yaml.v2 v2.2.1
|
||||||
|
4
go.sum
4
go.sum
@ -171,8 +171,8 @@ golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGm
|
|||||||
golang.org/x/tools v0.0.0-20181117154741-2ddaf7f79a09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20181117154741-2ddaf7f79a09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20181205014116-22934f0fdb62/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20181205014116-22934f0fdb62/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190121143147-24cd39ecf745/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20190121143147-24cd39ecf745/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190314010720-f0bfdbff1f9c h1:nE2ID2IbO0sUUG/3vWMz0LStAvkaW9wpnFp/65bxJw8=
|
golang.org/x/tools v0.0.0-20190420000508-685fecacd0a0 h1:pa1CyBALPFjblgkNQp7T7gEcFcG/GOG5Ck8IcnSVWGs=
|
||||||
golang.org/x/tools v0.0.0-20190314010720-f0bfdbff1f9c/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
golang.org/x/tools v0.0.0-20190420000508-685fecacd0a0/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
gopkg.in/airbrake/gobrake.v2 v2.0.9 h1:7z2uVWwn7oVeeugY1DtlPAy5H+KYgB1KeKTnqjNatLo=
|
gopkg.in/airbrake/gobrake.v2 v2.0.9 h1:7z2uVWwn7oVeeugY1DtlPAy5H+KYgB1KeKTnqjNatLo=
|
||||||
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
|
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
10
vendor/golang.org/x/tools/go/analysis/passes/stdmethods/stdmethods.go
generated
vendored
10
vendor/golang.org/x/tools/go/analysis/passes/stdmethods/stdmethods.go
generated
vendored
@ -8,7 +8,6 @@ package stdmethods
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"go/ast"
|
"go/ast"
|
||||||
"go/token"
|
|
||||||
"go/types"
|
"go/types"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -163,7 +162,7 @@ func matchParams(pass *analysis.Pass, expect []string, actual *types.Tuple, pref
|
|||||||
if i >= actual.Len() {
|
if i >= actual.Len() {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if !matchParamType(pass.Fset, pass.Pkg, x, actual.At(i).Type()) {
|
if !matchParamType(x, actual.At(i).Type()) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -174,13 +173,8 @@ func matchParams(pass *analysis.Pass, expect []string, actual *types.Tuple, pref
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Does this one type match?
|
// Does this one type match?
|
||||||
func matchParamType(fset *token.FileSet, pkg *types.Package, expect string, actual types.Type) bool {
|
func matchParamType(expect string, actual types.Type) bool {
|
||||||
expect = strings.TrimPrefix(expect, "=")
|
expect = strings.TrimPrefix(expect, "=")
|
||||||
// Strip package name if we're in that package.
|
|
||||||
if n := len(pkg.Name()); len(expect) > n && expect[:n] == pkg.Name() && expect[n] == '.' {
|
|
||||||
expect = expect[n+1:]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Overkill but easy.
|
// Overkill but easy.
|
||||||
return typeString(actual) == expect
|
return typeString(actual) == expect
|
||||||
}
|
}
|
||||||
|
40
vendor/golang.org/x/tools/go/analysis/passes/tests/tests.go
generated
vendored
40
vendor/golang.org/x/tools/go/analysis/passes/tests/tests.go
generated
vendored
@ -84,23 +84,25 @@ func isTestParam(typ ast.Expr, wantType string) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func lookup(pkg *types.Package, name string) types.Object {
|
func lookup(pkg *types.Package, name string) []types.Object {
|
||||||
if o := pkg.Scope().Lookup(name); o != nil {
|
if o := pkg.Scope().Lookup(name); o != nil {
|
||||||
return o
|
return []types.Object{o}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this package is ".../foo_test" and it imports a package
|
var ret []types.Object
|
||||||
// ".../foo", try looking in the latter package.
|
// Search through the imports to see if any of them define name.
|
||||||
// This heuristic should work even on build systems that do not
|
// It's hard to tell in general which package is being tested, so
|
||||||
// record any special link between the packages.
|
// for the purposes of the analysis, allow the object to appear
|
||||||
if basePath := strings.TrimSuffix(pkg.Path(), "_test"); basePath != pkg.Path() {
|
// in any of the imports. This guarantees there are no false positives
|
||||||
for _, imp := range pkg.Imports() {
|
// because the example needs to use the object so it must be defined
|
||||||
if imp.Path() == basePath {
|
// in the package or one if its imports. On the other hand, false
|
||||||
return imp.Scope().Lookup(name)
|
// negatives are possible, but should be rare.
|
||||||
}
|
for _, imp := range pkg.Imports() {
|
||||||
|
if obj := imp.Scope().Lookup(name); obj != nil {
|
||||||
|
ret = append(ret, obj)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkExample(pass *analysis.Pass, fn *ast.FuncDecl) {
|
func checkExample(pass *analysis.Pass, fn *ast.FuncDecl) {
|
||||||
@ -121,9 +123,9 @@ func checkExample(pass *analysis.Pass, fn *ast.FuncDecl) {
|
|||||||
exName = strings.TrimPrefix(fnName, "Example")
|
exName = strings.TrimPrefix(fnName, "Example")
|
||||||
elems = strings.SplitN(exName, "_", 3)
|
elems = strings.SplitN(exName, "_", 3)
|
||||||
ident = elems[0]
|
ident = elems[0]
|
||||||
obj = lookup(pass.Pkg, ident)
|
objs = lookup(pass.Pkg, ident)
|
||||||
)
|
)
|
||||||
if ident != "" && obj == nil {
|
if ident != "" && len(objs) == 0 {
|
||||||
// Check ExampleFoo and ExampleBadFoo.
|
// Check ExampleFoo and ExampleBadFoo.
|
||||||
pass.Reportf(fn.Pos(), "%s refers to unknown identifier: %s", fnName, ident)
|
pass.Reportf(fn.Pos(), "%s refers to unknown identifier: %s", fnName, ident)
|
||||||
// Abort since obj is absent and no subsequent checks can be performed.
|
// Abort since obj is absent and no subsequent checks can be performed.
|
||||||
@ -145,7 +147,15 @@ func checkExample(pass *analysis.Pass, fn *ast.FuncDecl) {
|
|||||||
mmbr := elems[1]
|
mmbr := elems[1]
|
||||||
if !isExampleSuffix(mmbr) {
|
if !isExampleSuffix(mmbr) {
|
||||||
// Check ExampleFoo_Method and ExampleFoo_BadMethod.
|
// Check ExampleFoo_Method and ExampleFoo_BadMethod.
|
||||||
if obj, _, _ := types.LookupFieldOrMethod(obj.Type(), true, obj.Pkg(), mmbr); obj == nil {
|
found := false
|
||||||
|
// Check if Foo.Method exists in this package or its imports.
|
||||||
|
for _, obj := range objs {
|
||||||
|
if obj, _, _ := types.LookupFieldOrMethod(obj.Type(), true, obj.Pkg(), mmbr); obj != nil {
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
pass.Reportf(fn.Pos(), "%s refers to unknown field or method: %s.%s", fnName, ident, mmbr)
|
pass.Reportf(fn.Pos(), "%s refers to unknown field or method: %s.%s", fnName, ident, mmbr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
2
vendor/golang.org/x/tools/go/packages/external.go
generated
vendored
2
vendor/golang.org/x/tools/go/packages/external.go
generated
vendored
@ -18,7 +18,7 @@ import (
|
|||||||
|
|
||||||
// Driver
|
// Driver
|
||||||
type driverRequest struct {
|
type driverRequest struct {
|
||||||
Command string `json "command"`
|
Command string `json:"command"`
|
||||||
Mode LoadMode `json:"mode"`
|
Mode LoadMode `json:"mode"`
|
||||||
Env []string `json:"env"`
|
Env []string `json:"env"`
|
||||||
BuildFlags []string `json:"build_flags"`
|
BuildFlags []string `json:"build_flags"`
|
||||||
|
85
vendor/golang.org/x/tools/go/packages/golist.go
generated
vendored
85
vendor/golang.org/x/tools/go/packages/golist.go
generated
vendored
@ -78,7 +78,7 @@ func goListDriver(cfg *Config, patterns ...string) (*driverResponse, error) {
|
|||||||
var sizes types.Sizes
|
var sizes types.Sizes
|
||||||
var sizeserr error
|
var sizeserr error
|
||||||
var sizeswg sync.WaitGroup
|
var sizeswg sync.WaitGroup
|
||||||
if cfg.Mode >= LoadTypes {
|
if cfg.Mode&NeedTypesSizes != 0 || cfg.Mode&NeedTypes != 0 {
|
||||||
sizeswg.Add(1)
|
sizeswg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
sizes, sizeserr = getSizes(cfg)
|
sizes, sizeserr = getSizes(cfg)
|
||||||
@ -121,20 +121,6 @@ extractQueries:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(matloob): Remove the definition of listfunc and just use golistPackages once go1.12 is released.
|
|
||||||
var listfunc driver
|
|
||||||
var isFallback bool
|
|
||||||
listfunc = func(cfg *Config, words ...string) (*driverResponse, error) {
|
|
||||||
response, err := golistDriverCurrent(cfg, words...)
|
|
||||||
if _, ok := err.(goTooOldError); ok {
|
|
||||||
isFallback = true
|
|
||||||
listfunc = golistDriverFallback
|
|
||||||
return listfunc(cfg, words...)
|
|
||||||
}
|
|
||||||
listfunc = golistDriverCurrent
|
|
||||||
return response, err
|
|
||||||
}
|
|
||||||
|
|
||||||
response := &responseDeduper{}
|
response := &responseDeduper{}
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
@ -142,7 +128,7 @@ extractQueries:
|
|||||||
// patterns also requires a go list call, since it's the equivalent of
|
// patterns also requires a go list call, since it's the equivalent of
|
||||||
// ".".
|
// ".".
|
||||||
if len(restPatterns) > 0 || len(patterns) == 0 {
|
if len(restPatterns) > 0 || len(patterns) == 0 {
|
||||||
dr, err := listfunc(cfg, restPatterns...)
|
dr, err := golistDriver(cfg, restPatterns...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -161,13 +147,13 @@ extractQueries:
|
|||||||
var containsCandidates []string
|
var containsCandidates []string
|
||||||
|
|
||||||
if len(containFiles) != 0 {
|
if len(containFiles) != 0 {
|
||||||
if err := runContainsQueries(cfg, listfunc, isFallback, response, containFiles); err != nil {
|
if err := runContainsQueries(cfg, golistDriver, response, containFiles); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(packagesNamed) != 0 {
|
if len(packagesNamed) != 0 {
|
||||||
if err := runNamedQueries(cfg, listfunc, response, packagesNamed); err != nil {
|
if err := runNamedQueries(cfg, golistDriver, response, packagesNamed); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -180,12 +166,8 @@ extractQueries:
|
|||||||
containsCandidates = append(containsCandidates, modifiedPkgs...)
|
containsCandidates = append(containsCandidates, modifiedPkgs...)
|
||||||
containsCandidates = append(containsCandidates, needPkgs...)
|
containsCandidates = append(containsCandidates, needPkgs...)
|
||||||
}
|
}
|
||||||
|
if err := addNeededOverlayPackages(cfg, golistDriver, response, needPkgs); err != nil {
|
||||||
if len(needPkgs) > 0 {
|
return nil, err
|
||||||
addNeededOverlayPackages(cfg, listfunc, response, needPkgs)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Check candidate packages for containFiles.
|
// Check candidate packages for containFiles.
|
||||||
if len(containFiles) > 0 {
|
if len(containFiles) > 0 {
|
||||||
@ -205,6 +187,9 @@ extractQueries:
|
|||||||
}
|
}
|
||||||
|
|
||||||
func addNeededOverlayPackages(cfg *Config, driver driver, response *responseDeduper, pkgs []string) error {
|
func addNeededOverlayPackages(cfg *Config, driver driver, response *responseDeduper, pkgs []string) error {
|
||||||
|
if len(pkgs) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
dr, err := driver(cfg, pkgs...)
|
dr, err := driver(cfg, pkgs...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -212,10 +197,15 @@ func addNeededOverlayPackages(cfg *Config, driver driver, response *responseDedu
|
|||||||
for _, pkg := range dr.Packages {
|
for _, pkg := range dr.Packages {
|
||||||
response.addPackage(pkg)
|
response.addPackage(pkg)
|
||||||
}
|
}
|
||||||
|
_, needPkgs, err := processGolistOverlay(cfg, response.dr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
addNeededOverlayPackages(cfg, driver, response, needPkgs)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func runContainsQueries(cfg *Config, driver driver, isFallback bool, response *responseDeduper, queries []string) error {
|
func runContainsQueries(cfg *Config, driver driver, response *responseDeduper, queries []string) error {
|
||||||
for _, query := range queries {
|
for _, query := range queries {
|
||||||
// TODO(matloob): Do only one query per directory.
|
// TODO(matloob): Do only one query per directory.
|
||||||
fdir := filepath.Dir(query)
|
fdir := filepath.Dir(query)
|
||||||
@ -225,11 +215,6 @@ func runContainsQueries(cfg *Config, driver driver, isFallback bool, response *r
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not determine absolute path of file= query path %q: %v", query, err)
|
return fmt.Errorf("could not determine absolute path of file= query path %q: %v", query, err)
|
||||||
}
|
}
|
||||||
if isFallback {
|
|
||||||
pattern = "."
|
|
||||||
cfg.Dir = fdir
|
|
||||||
}
|
|
||||||
|
|
||||||
dirResponse, err := driver(cfg, pattern)
|
dirResponse, err := driver(cfg, pattern)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -559,10 +544,10 @@ func otherFiles(p *jsonPackage) [][]string {
|
|||||||
return [][]string{p.CFiles, p.CXXFiles, p.MFiles, p.HFiles, p.FFiles, p.SFiles, p.SwigFiles, p.SwigCXXFiles, p.SysoFiles}
|
return [][]string{p.CFiles, p.CXXFiles, p.MFiles, p.HFiles, p.FFiles, p.SFiles, p.SwigFiles, p.SwigCXXFiles, p.SysoFiles}
|
||||||
}
|
}
|
||||||
|
|
||||||
// golistDriverCurrent uses the "go list" command to expand the
|
// golistDriver uses the "go list" command to expand the pattern
|
||||||
// pattern words and return metadata for the specified packages.
|
// words and return metadata for the specified packages. dir may be
|
||||||
// dir may be "" and env may be nil, as per os/exec.Command.
|
// "" and env may be nil, as per os/exec.Command.
|
||||||
func golistDriverCurrent(cfg *Config, words ...string) (*driverResponse, error) {
|
func golistDriver(cfg *Config, words ...string) (*driverResponse, error) {
|
||||||
// go list uses the following identifiers in ImportPath and Imports:
|
// go list uses the following identifiers in ImportPath and Imports:
|
||||||
//
|
//
|
||||||
// "p" -- importable package or main (command)
|
// "p" -- importable package or main (command)
|
||||||
@ -605,7 +590,7 @@ func golistDriverCurrent(cfg *Config, words ...string) (*driverResponse, error)
|
|||||||
|
|
||||||
if old, found := seen[p.ImportPath]; found {
|
if old, found := seen[p.ImportPath]; found {
|
||||||
if !reflect.DeepEqual(p, old) {
|
if !reflect.DeepEqual(p, old) {
|
||||||
return nil, fmt.Errorf("go list repeated package %v with different values", p.ImportPath)
|
return nil, fmt.Errorf("internal error: go list gives conflicting information for package %v", p.ImportPath)
|
||||||
}
|
}
|
||||||
// skip the duplicate
|
// skip the duplicate
|
||||||
continue
|
continue
|
||||||
@ -720,14 +705,16 @@ func absJoin(dir string, fileses ...[]string) (res []string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func golistargs(cfg *Config, words []string) []string {
|
func golistargs(cfg *Config, words []string) []string {
|
||||||
|
const findFlags = NeedImports | NeedTypes | NeedSyntax | NeedTypesInfo
|
||||||
fullargs := []string{
|
fullargs := []string{
|
||||||
"list", "-e", "-json", "-compiled",
|
"list", "-e", "-json",
|
||||||
|
fmt.Sprintf("-compiled=%t", cfg.Mode&(NeedCompiledGoFiles|NeedSyntax|NeedTypesInfo|NeedTypesSizes) != 0),
|
||||||
fmt.Sprintf("-test=%t", cfg.Tests),
|
fmt.Sprintf("-test=%t", cfg.Tests),
|
||||||
fmt.Sprintf("-export=%t", usesExportData(cfg)),
|
fmt.Sprintf("-export=%t", usesExportData(cfg)),
|
||||||
fmt.Sprintf("-deps=%t", cfg.Mode >= LoadImports),
|
fmt.Sprintf("-deps=%t", cfg.Mode&NeedDeps != 0),
|
||||||
// go list doesn't let you pass -test and -find together,
|
// go list doesn't let you pass -test and -find together,
|
||||||
// probably because you'd just get the TestMain.
|
// probably because you'd just get the TestMain.
|
||||||
fmt.Sprintf("-find=%t", cfg.Mode < LoadImports && !cfg.Tests),
|
fmt.Sprintf("-find=%t", !cfg.Tests && cfg.Mode&findFlags == 0),
|
||||||
}
|
}
|
||||||
fullargs = append(fullargs, cfg.BuildFlags...)
|
fullargs = append(fullargs, cfg.BuildFlags...)
|
||||||
fullargs = append(fullargs, "--")
|
fullargs = append(fullargs, "--")
|
||||||
@ -757,10 +744,14 @@ func invokeGo(cfg *Config, args ...string) (*bytes.Buffer, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err := cmd.Run(); err != nil {
|
if err := cmd.Run(); err != nil {
|
||||||
|
// Check for 'go' executable not being found.
|
||||||
|
if ee, ok := err.(*exec.Error); ok && ee.Err == exec.ErrNotFound {
|
||||||
|
return nil, fmt.Errorf("'go list' driver requires 'go', but %s", exec.ErrNotFound)
|
||||||
|
}
|
||||||
|
|
||||||
exitErr, ok := err.(*exec.ExitError)
|
exitErr, ok := err.(*exec.ExitError)
|
||||||
if !ok {
|
if !ok {
|
||||||
// Catastrophic error:
|
// Catastrophic error:
|
||||||
// - executable not found
|
|
||||||
// - context cancellation
|
// - context cancellation
|
||||||
return nil, fmt.Errorf("couldn't exec 'go %v': %s %T", args, err, err)
|
return nil, fmt.Errorf("couldn't exec 'go %v': %s %T", args, err, err)
|
||||||
}
|
}
|
||||||
@ -770,6 +761,22 @@ func invokeGo(cfg *Config, args ...string) (*bytes.Buffer, error) {
|
|||||||
return nil, goTooOldError{fmt.Errorf("unsupported version of go: %s: %s", exitErr, stderr)}
|
return nil, goTooOldError{fmt.Errorf("unsupported version of go: %s: %s", exitErr, stderr)}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "named files must be .go files") {
|
||||||
|
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 #29280: go list -e has incorrect behavior when an ad-hoc package doesn't exist.
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
// Export mode entails a build.
|
// Export mode entails a build.
|
||||||
// If that build fails, errors appear on stderr
|
// If that build fails, errors appear on stderr
|
||||||
// (despite the -e flag) and the Export field is blank.
|
// (despite the -e flag) and the Export field is blank.
|
||||||
|
450
vendor/golang.org/x/tools/go/packages/golist_fallback.go
generated
vendored
450
vendor/golang.org/x/tools/go/packages/golist_fallback.go
generated
vendored
@ -1,450 +0,0 @@
|
|||||||
// Copyright 2018 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package packages
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"go/build"
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"path/filepath"
|
|
||||||
"sort"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"golang.org/x/tools/go/internal/cgo"
|
|
||||||
)
|
|
||||||
|
|
||||||
// TODO(matloob): Delete this file once Go 1.12 is released.
|
|
||||||
|
|
||||||
// This file provides backwards compatibility support for
|
|
||||||
// loading for versions of Go earlier than 1.11. This support is meant to
|
|
||||||
// assist with migration to the Package API until there's
|
|
||||||
// widespread adoption of these newer Go versions.
|
|
||||||
// This support will be removed once Go 1.12 is released
|
|
||||||
// in Q1 2019.
|
|
||||||
|
|
||||||
func golistDriverFallback(cfg *Config, words ...string) (*driverResponse, error) {
|
|
||||||
// Turn absolute paths into GOROOT and GOPATH-relative paths to provide to go list.
|
|
||||||
// This will have surprising behavior if GOROOT or GOPATH contain multiple packages with the same
|
|
||||||
// path and a user provides an absolute path to a directory that's shadowed by an earlier
|
|
||||||
// directory in GOROOT or GOPATH with the same package path.
|
|
||||||
words = cleanAbsPaths(cfg, words)
|
|
||||||
|
|
||||||
original, deps, err := getDeps(cfg, words...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var tmpdir string // used for generated cgo files
|
|
||||||
var needsTestVariant []struct {
|
|
||||||
pkg, xtestPkg *Package
|
|
||||||
}
|
|
||||||
|
|
||||||
var response driverResponse
|
|
||||||
allPkgs := make(map[string]bool)
|
|
||||||
addPackage := func(p *jsonPackage, isRoot bool) {
|
|
||||||
id := p.ImportPath
|
|
||||||
|
|
||||||
if allPkgs[id] {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
allPkgs[id] = true
|
|
||||||
|
|
||||||
pkgpath := id
|
|
||||||
|
|
||||||
if pkgpath == "unsafe" {
|
|
||||||
p.GoFiles = nil // ignore fake unsafe.go file
|
|
||||||
}
|
|
||||||
|
|
||||||
importMap := func(importlist []string) map[string]*Package {
|
|
||||||
importMap := make(map[string]*Package)
|
|
||||||
for _, id := range importlist {
|
|
||||||
|
|
||||||
if id == "C" {
|
|
||||||
for _, path := range []string{"unsafe", "syscall", "runtime/cgo"} {
|
|
||||||
if pkgpath != path && importMap[path] == nil {
|
|
||||||
importMap[path] = &Package{ID: path}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
importMap[vendorlessPath(id)] = &Package{ID: id}
|
|
||||||
}
|
|
||||||
return importMap
|
|
||||||
}
|
|
||||||
compiledGoFiles := absJoin(p.Dir, p.GoFiles)
|
|
||||||
// Use a function to simplify control flow. It's just a bunch of gotos.
|
|
||||||
var cgoErrors []error
|
|
||||||
var outdir string
|
|
||||||
getOutdir := func() (string, error) {
|
|
||||||
if outdir != "" {
|
|
||||||
return outdir, nil
|
|
||||||
}
|
|
||||||
if tmpdir == "" {
|
|
||||||
if tmpdir, err = ioutil.TempDir("", "gopackages"); err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
outdir = filepath.Join(tmpdir, strings.Replace(p.ImportPath, "/", "_", -1))
|
|
||||||
if err := os.MkdirAll(outdir, 0755); err != nil {
|
|
||||||
outdir = ""
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return outdir, nil
|
|
||||||
}
|
|
||||||
processCgo := func() bool {
|
|
||||||
// Suppress any cgo errors. Any relevant errors will show up in typechecking.
|
|
||||||
// TODO(matloob): Skip running cgo if Mode < LoadTypes.
|
|
||||||
outdir, err := getOutdir()
|
|
||||||
if err != nil {
|
|
||||||
cgoErrors = append(cgoErrors, err)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
files, _, err := runCgo(p.Dir, outdir, cfg.Env)
|
|
||||||
if err != nil {
|
|
||||||
cgoErrors = append(cgoErrors, err)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
compiledGoFiles = append(compiledGoFiles, files...)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if len(p.CgoFiles) == 0 || !processCgo() {
|
|
||||||
compiledGoFiles = append(compiledGoFiles, absJoin(p.Dir, p.CgoFiles)...) // Punt to typechecker.
|
|
||||||
}
|
|
||||||
if isRoot {
|
|
||||||
response.Roots = append(response.Roots, id)
|
|
||||||
}
|
|
||||||
pkg := &Package{
|
|
||||||
ID: id,
|
|
||||||
Name: p.Name,
|
|
||||||
GoFiles: absJoin(p.Dir, p.GoFiles, p.CgoFiles),
|
|
||||||
CompiledGoFiles: compiledGoFiles,
|
|
||||||
OtherFiles: absJoin(p.Dir, otherFiles(p)...),
|
|
||||||
PkgPath: pkgpath,
|
|
||||||
Imports: importMap(p.Imports),
|
|
||||||
// TODO(matloob): set errors on the Package to cgoErrors
|
|
||||||
}
|
|
||||||
if p.Error != nil {
|
|
||||||
pkg.Errors = append(pkg.Errors, Error{
|
|
||||||
Pos: p.Error.Pos,
|
|
||||||
Msg: p.Error.Err,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
response.Packages = append(response.Packages, pkg)
|
|
||||||
if cfg.Tests && isRoot {
|
|
||||||
testID := fmt.Sprintf("%s [%s.test]", id, id)
|
|
||||||
if len(p.TestGoFiles) > 0 || len(p.XTestGoFiles) > 0 {
|
|
||||||
response.Roots = append(response.Roots, testID)
|
|
||||||
testPkg := &Package{
|
|
||||||
ID: testID,
|
|
||||||
Name: p.Name,
|
|
||||||
GoFiles: absJoin(p.Dir, p.GoFiles, p.CgoFiles, p.TestGoFiles),
|
|
||||||
CompiledGoFiles: append(compiledGoFiles, absJoin(p.Dir, p.TestGoFiles)...),
|
|
||||||
OtherFiles: absJoin(p.Dir, otherFiles(p)...),
|
|
||||||
PkgPath: pkgpath,
|
|
||||||
Imports: importMap(append(p.Imports, p.TestImports...)),
|
|
||||||
// TODO(matloob): set errors on the Package to cgoErrors
|
|
||||||
}
|
|
||||||
response.Packages = append(response.Packages, testPkg)
|
|
||||||
var xtestPkg *Package
|
|
||||||
if len(p.XTestGoFiles) > 0 {
|
|
||||||
xtestID := fmt.Sprintf("%s_test [%s.test]", id, id)
|
|
||||||
response.Roots = append(response.Roots, xtestID)
|
|
||||||
// Generate test variants for all packages q where a path exists
|
|
||||||
// such that xtestPkg -> ... -> q -> ... -> p (where p is the package under test)
|
|
||||||
// and rewrite all import map entries of p to point to testPkg (the test variant of
|
|
||||||
// p), and of each q to point to the test variant of that q.
|
|
||||||
xtestPkg = &Package{
|
|
||||||
ID: xtestID,
|
|
||||||
Name: p.Name + "_test",
|
|
||||||
GoFiles: absJoin(p.Dir, p.XTestGoFiles),
|
|
||||||
CompiledGoFiles: absJoin(p.Dir, p.XTestGoFiles),
|
|
||||||
PkgPath: pkgpath + "_test",
|
|
||||||
Imports: importMap(p.XTestImports),
|
|
||||||
}
|
|
||||||
// Add to list of packages we need to rewrite imports for to refer to test variants.
|
|
||||||
// We may need to create a test variant of a package that hasn't been loaded yet, so
|
|
||||||
// the test variants need to be created later.
|
|
||||||
needsTestVariant = append(needsTestVariant, struct{ pkg, xtestPkg *Package }{pkg, xtestPkg})
|
|
||||||
response.Packages = append(response.Packages, xtestPkg)
|
|
||||||
}
|
|
||||||
// testmain package
|
|
||||||
testmainID := id + ".test"
|
|
||||||
response.Roots = append(response.Roots, testmainID)
|
|
||||||
imports := map[string]*Package{}
|
|
||||||
imports[testPkg.PkgPath] = &Package{ID: testPkg.ID}
|
|
||||||
if xtestPkg != nil {
|
|
||||||
imports[xtestPkg.PkgPath] = &Package{ID: xtestPkg.ID}
|
|
||||||
}
|
|
||||||
testmainPkg := &Package{
|
|
||||||
ID: testmainID,
|
|
||||||
Name: "main",
|
|
||||||
PkgPath: testmainID,
|
|
||||||
Imports: imports,
|
|
||||||
}
|
|
||||||
response.Packages = append(response.Packages, testmainPkg)
|
|
||||||
outdir, err := getOutdir()
|
|
||||||
if err != nil {
|
|
||||||
testmainPkg.Errors = append(testmainPkg.Errors, Error{
|
|
||||||
Pos: "-",
|
|
||||||
Msg: fmt.Sprintf("failed to generate testmain: %v", err),
|
|
||||||
Kind: ListError,
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// Don't use a .go extension on the file, so that the tests think the file is inside GOCACHE.
|
|
||||||
// This allows the same test to test the pre- and post-Go 1.11 go list logic because the Go 1.11
|
|
||||||
// go list generates test mains in the cache, and the test code knows not to rely on paths in the
|
|
||||||
// cache to stay stable.
|
|
||||||
testmain := filepath.Join(outdir, "testmain-go")
|
|
||||||
extraimports, extradeps, err := generateTestmain(testmain, testPkg, xtestPkg)
|
|
||||||
if err != nil {
|
|
||||||
testmainPkg.Errors = append(testmainPkg.Errors, Error{
|
|
||||||
Pos: "-",
|
|
||||||
Msg: fmt.Sprintf("failed to generate testmain: %v", err),
|
|
||||||
Kind: ListError,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
deps = append(deps, extradeps...)
|
|
||||||
for _, imp := range extraimports { // testing, testing/internal/testdeps, and maybe os
|
|
||||||
imports[imp] = &Package{ID: imp}
|
|
||||||
}
|
|
||||||
testmainPkg.GoFiles = []string{testmain}
|
|
||||||
testmainPkg.CompiledGoFiles = []string{testmain}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, pkg := range original {
|
|
||||||
addPackage(pkg, true)
|
|
||||||
}
|
|
||||||
if cfg.Mode < LoadImports || len(deps) == 0 {
|
|
||||||
return &response, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
buf, err := invokeGo(cfg, golistArgsFallback(cfg, deps)...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Decode the JSON and convert it to Package form.
|
|
||||||
for dec := json.NewDecoder(buf); dec.More(); {
|
|
||||||
p := new(jsonPackage)
|
|
||||||
if err := dec.Decode(p); err != nil {
|
|
||||||
return nil, fmt.Errorf("JSON decoding failed: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
addPackage(p, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, v := range needsTestVariant {
|
|
||||||
createTestVariants(&response, v.pkg, v.xtestPkg)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &response, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func createTestVariants(response *driverResponse, pkgUnderTest, xtestPkg *Package) {
|
|
||||||
allPkgs := make(map[string]*Package)
|
|
||||||
for _, pkg := range response.Packages {
|
|
||||||
allPkgs[pkg.ID] = pkg
|
|
||||||
}
|
|
||||||
needsTestVariant := make(map[string]bool)
|
|
||||||
needsTestVariant[pkgUnderTest.ID] = true
|
|
||||||
var needsVariantRec func(p *Package) bool
|
|
||||||
needsVariantRec = func(p *Package) bool {
|
|
||||||
if needsTestVariant[p.ID] {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
for _, imp := range p.Imports {
|
|
||||||
if needsVariantRec(allPkgs[imp.ID]) {
|
|
||||||
// Don't break because we want to make sure all dependencies
|
|
||||||
// have been processed, and all required test variants of our dependencies
|
|
||||||
// exist.
|
|
||||||
needsTestVariant[p.ID] = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !needsTestVariant[p.ID] {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
// Create a clone of the package. It will share the same strings and lists of source files,
|
|
||||||
// but that's okay. It's only necessary for the Imports map to have a separate identity.
|
|
||||||
testVariant := *p
|
|
||||||
testVariant.ID = fmt.Sprintf("%s [%s.test]", p.ID, pkgUnderTest.ID)
|
|
||||||
testVariant.Imports = make(map[string]*Package)
|
|
||||||
for imp, pkg := range p.Imports {
|
|
||||||
testVariant.Imports[imp] = pkg
|
|
||||||
if needsTestVariant[pkg.ID] {
|
|
||||||
testVariant.Imports[imp] = &Package{ID: fmt.Sprintf("%s [%s.test]", pkg.ID, pkgUnderTest.ID)}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
response.Packages = append(response.Packages, &testVariant)
|
|
||||||
return needsTestVariant[p.ID]
|
|
||||||
}
|
|
||||||
// finally, update the xtest package's imports
|
|
||||||
for imp, pkg := range xtestPkg.Imports {
|
|
||||||
if allPkgs[pkg.ID] == nil {
|
|
||||||
fmt.Printf("for %s: package %s doesn't exist\n", xtestPkg.ID, pkg.ID)
|
|
||||||
}
|
|
||||||
if needsVariantRec(allPkgs[pkg.ID]) {
|
|
||||||
xtestPkg.Imports[imp] = &Package{ID: fmt.Sprintf("%s [%s.test]", pkg.ID, pkgUnderTest.ID)}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// cleanAbsPaths replaces all absolute paths with GOPATH- and GOROOT-relative
|
|
||||||
// paths. If an absolute path is not GOPATH- or GOROOT- relative, it is left as an
|
|
||||||
// absolute path so an error can be returned later.
|
|
||||||
func cleanAbsPaths(cfg *Config, words []string) []string {
|
|
||||||
var searchpaths []string
|
|
||||||
var cleaned = make([]string, len(words))
|
|
||||||
for i := range cleaned {
|
|
||||||
cleaned[i] = words[i]
|
|
||||||
// Ignore relative directory paths (they must already be goroot-relative) and Go source files
|
|
||||||
// (absolute source files are already allowed for ad-hoc packages).
|
|
||||||
// TODO(matloob): Can there be non-.go files in ad-hoc packages.
|
|
||||||
if !filepath.IsAbs(cleaned[i]) || strings.HasSuffix(cleaned[i], ".go") {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
// otherwise, it's an absolute path. Search GOPATH and GOROOT to find it.
|
|
||||||
if searchpaths == nil {
|
|
||||||
cmd := exec.Command("go", "env", "GOPATH", "GOROOT")
|
|
||||||
cmd.Env = cfg.Env
|
|
||||||
out, err := cmd.Output()
|
|
||||||
if err != nil {
|
|
||||||
searchpaths = []string{}
|
|
||||||
continue // suppress the error, it will show up again when running go list
|
|
||||||
}
|
|
||||||
lines := strings.Split(string(out), "\n")
|
|
||||||
if len(lines) != 3 || lines[0] == "" || lines[1] == "" || lines[2] != "" {
|
|
||||||
continue // suppress error
|
|
||||||
}
|
|
||||||
// first line is GOPATH
|
|
||||||
for _, path := range filepath.SplitList(lines[0]) {
|
|
||||||
searchpaths = append(searchpaths, filepath.Join(path, "src"))
|
|
||||||
}
|
|
||||||
// second line is GOROOT
|
|
||||||
searchpaths = append(searchpaths, filepath.Join(lines[1], "src"))
|
|
||||||
}
|
|
||||||
for _, sp := range searchpaths {
|
|
||||||
if strings.HasPrefix(cleaned[i], sp) {
|
|
||||||
cleaned[i] = strings.TrimPrefix(cleaned[i], sp)
|
|
||||||
cleaned[i] = strings.TrimLeft(cleaned[i], string(filepath.Separator))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return cleaned
|
|
||||||
}
|
|
||||||
|
|
||||||
// vendorlessPath returns the devendorized version of the import path ipath.
|
|
||||||
// For example, VendorlessPath("foo/bar/vendor/a/b") returns "a/b".
|
|
||||||
// Copied from golang.org/x/tools/imports/fix.go.
|
|
||||||
func vendorlessPath(ipath string) string {
|
|
||||||
// Devendorize for use in import statement.
|
|
||||||
if i := strings.LastIndex(ipath, "/vendor/"); i >= 0 {
|
|
||||||
return ipath[i+len("/vendor/"):]
|
|
||||||
}
|
|
||||||
if strings.HasPrefix(ipath, "vendor/") {
|
|
||||||
return ipath[len("vendor/"):]
|
|
||||||
}
|
|
||||||
return ipath
|
|
||||||
}
|
|
||||||
|
|
||||||
// getDeps runs an initial go list to determine all the dependency packages.
|
|
||||||
func getDeps(cfg *Config, words ...string) (initial []*jsonPackage, deps []string, err error) {
|
|
||||||
buf, err := invokeGo(cfg, golistArgsFallback(cfg, words)...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
depsSet := make(map[string]bool)
|
|
||||||
var testImports []string
|
|
||||||
|
|
||||||
// Extract deps from the JSON.
|
|
||||||
for dec := json.NewDecoder(buf); dec.More(); {
|
|
||||||
p := new(jsonPackage)
|
|
||||||
if err := dec.Decode(p); err != nil {
|
|
||||||
return nil, nil, fmt.Errorf("JSON decoding failed: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
initial = append(initial, p)
|
|
||||||
for _, dep := range p.Deps {
|
|
||||||
depsSet[dep] = true
|
|
||||||
}
|
|
||||||
if cfg.Tests {
|
|
||||||
// collect the additional imports of the test packages.
|
|
||||||
pkgTestImports := append(p.TestImports, p.XTestImports...)
|
|
||||||
for _, imp := range pkgTestImports {
|
|
||||||
if depsSet[imp] {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
depsSet[imp] = true
|
|
||||||
testImports = append(testImports, imp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Get the deps of the packages imported by tests.
|
|
||||||
if len(testImports) > 0 {
|
|
||||||
buf, err = invokeGo(cfg, golistArgsFallback(cfg, testImports)...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
// Extract deps from the JSON.
|
|
||||||
for dec := json.NewDecoder(buf); dec.More(); {
|
|
||||||
p := new(jsonPackage)
|
|
||||||
if err := dec.Decode(p); err != nil {
|
|
||||||
return nil, nil, fmt.Errorf("JSON decoding failed: %v", err)
|
|
||||||
}
|
|
||||||
for _, dep := range p.Deps {
|
|
||||||
depsSet[dep] = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, orig := range initial {
|
|
||||||
delete(depsSet, orig.ImportPath)
|
|
||||||
}
|
|
||||||
|
|
||||||
deps = make([]string, 0, len(depsSet))
|
|
||||||
for dep := range depsSet {
|
|
||||||
deps = append(deps, dep)
|
|
||||||
}
|
|
||||||
sort.Strings(deps) // ensure output is deterministic
|
|
||||||
return initial, deps, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func golistArgsFallback(cfg *Config, words []string) []string {
|
|
||||||
fullargs := []string{"list", "-e", "-json"}
|
|
||||||
fullargs = append(fullargs, cfg.BuildFlags...)
|
|
||||||
fullargs = append(fullargs, "--")
|
|
||||||
fullargs = append(fullargs, words...)
|
|
||||||
return fullargs
|
|
||||||
}
|
|
||||||
|
|
||||||
func runCgo(pkgdir, tmpdir string, env []string) (files, displayfiles []string, err error) {
|
|
||||||
// Use go/build to open cgo files and determine the cgo flags, etc, from them.
|
|
||||||
// This is tricky so it's best to avoid reimplementing as much as we can, and
|
|
||||||
// we plan to delete this support once Go 1.12 is released anyways.
|
|
||||||
// TODO(matloob): This isn't completely correct because we're using the Default
|
|
||||||
// context. Perhaps we should more accurately fill in the context.
|
|
||||||
bp, err := build.ImportDir(pkgdir, build.ImportMode(0))
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
for _, ev := range env {
|
|
||||||
if v := strings.TrimPrefix(ev, "CGO_CPPFLAGS"); v != ev {
|
|
||||||
bp.CgoCPPFLAGS = append(bp.CgoCPPFLAGS, strings.Fields(v)...)
|
|
||||||
} else if v := strings.TrimPrefix(ev, "CGO_CFLAGS"); v != ev {
|
|
||||||
bp.CgoCFLAGS = append(bp.CgoCFLAGS, strings.Fields(v)...)
|
|
||||||
} else if v := strings.TrimPrefix(ev, "CGO_CXXFLAGS"); v != ev {
|
|
||||||
bp.CgoCXXFLAGS = append(bp.CgoCXXFLAGS, strings.Fields(v)...)
|
|
||||||
} else if v := strings.TrimPrefix(ev, "CGO_LDFLAGS"); v != ev {
|
|
||||||
bp.CgoLDFLAGS = append(bp.CgoLDFLAGS, strings.Fields(v)...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return cgo.Run(bp, pkgdir, tmpdir, true)
|
|
||||||
}
|
|
318
vendor/golang.org/x/tools/go/packages/golist_fallback_testmain.go
generated
vendored
318
vendor/golang.org/x/tools/go/packages/golist_fallback_testmain.go
generated
vendored
@ -1,318 +0,0 @@
|
|||||||
// Copyright 2018 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// This file is largely based on the Go 1.10-era cmd/go/internal/test/test.go
|
|
||||||
// testmain generation code.
|
|
||||||
|
|
||||||
package packages
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"go/ast"
|
|
||||||
"go/doc"
|
|
||||||
"go/parser"
|
|
||||||
"go/token"
|
|
||||||
"os"
|
|
||||||
"sort"
|
|
||||||
"strings"
|
|
||||||
"text/template"
|
|
||||||
"unicode"
|
|
||||||
"unicode/utf8"
|
|
||||||
)
|
|
||||||
|
|
||||||
// TODO(matloob): Delete this file once Go 1.12 is released.
|
|
||||||
|
|
||||||
// This file complements golist_fallback.go by providing
|
|
||||||
// support for generating testmains.
|
|
||||||
|
|
||||||
func generateTestmain(out string, testPkg, xtestPkg *Package) (extraimports, extradeps []string, err error) {
|
|
||||||
testFuncs, err := loadTestFuncs(testPkg, xtestPkg)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
extraimports = []string{"testing", "testing/internal/testdeps"}
|
|
||||||
if testFuncs.TestMain == nil {
|
|
||||||
extraimports = append(extraimports, "os")
|
|
||||||
}
|
|
||||||
// Transitive dependencies of ("testing", "testing/internal/testdeps").
|
|
||||||
// os is part of the transitive closure so it and its transitive dependencies are
|
|
||||||
// included regardless of whether it's imported in the template below.
|
|
||||||
extradeps = []string{
|
|
||||||
"errors",
|
|
||||||
"internal/cpu",
|
|
||||||
"unsafe",
|
|
||||||
"internal/bytealg",
|
|
||||||
"internal/race",
|
|
||||||
"runtime/internal/atomic",
|
|
||||||
"runtime/internal/sys",
|
|
||||||
"runtime",
|
|
||||||
"sync/atomic",
|
|
||||||
"sync",
|
|
||||||
"io",
|
|
||||||
"unicode",
|
|
||||||
"unicode/utf8",
|
|
||||||
"bytes",
|
|
||||||
"math",
|
|
||||||
"syscall",
|
|
||||||
"time",
|
|
||||||
"internal/poll",
|
|
||||||
"internal/syscall/unix",
|
|
||||||
"internal/testlog",
|
|
||||||
"os",
|
|
||||||
"math/bits",
|
|
||||||
"strconv",
|
|
||||||
"reflect",
|
|
||||||
"fmt",
|
|
||||||
"sort",
|
|
||||||
"strings",
|
|
||||||
"flag",
|
|
||||||
"runtime/debug",
|
|
||||||
"context",
|
|
||||||
"runtime/trace",
|
|
||||||
"testing",
|
|
||||||
"bufio",
|
|
||||||
"regexp/syntax",
|
|
||||||
"regexp",
|
|
||||||
"compress/flate",
|
|
||||||
"encoding/binary",
|
|
||||||
"hash",
|
|
||||||
"hash/crc32",
|
|
||||||
"compress/gzip",
|
|
||||||
"path/filepath",
|
|
||||||
"io/ioutil",
|
|
||||||
"text/tabwriter",
|
|
||||||
"runtime/pprof",
|
|
||||||
"testing/internal/testdeps",
|
|
||||||
}
|
|
||||||
return extraimports, extradeps, writeTestmain(out, testFuncs)
|
|
||||||
}
|
|
||||||
|
|
||||||
// The following is adapted from the cmd/go testmain generation code.
|
|
||||||
|
|
||||||
// isTestFunc tells whether fn has the type of a testing function. arg
|
|
||||||
// specifies the parameter type we look for: B, M or T.
|
|
||||||
func isTestFunc(fn *ast.FuncDecl, arg string) bool {
|
|
||||||
if fn.Type.Results != nil && len(fn.Type.Results.List) > 0 ||
|
|
||||||
fn.Type.Params.List == nil ||
|
|
||||||
len(fn.Type.Params.List) != 1 ||
|
|
||||||
len(fn.Type.Params.List[0].Names) > 1 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
ptr, ok := fn.Type.Params.List[0].Type.(*ast.StarExpr)
|
|
||||||
if !ok {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
// We can't easily check that the type is *testing.M
|
|
||||||
// because we don't know how testing has been imported,
|
|
||||||
// but at least check that it's *M or *something.M.
|
|
||||||
// Same applies for B and T.
|
|
||||||
if name, ok := ptr.X.(*ast.Ident); ok && name.Name == arg {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if sel, ok := ptr.X.(*ast.SelectorExpr); ok && sel.Sel.Name == arg {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// isTest tells whether name looks like a test (or benchmark, according to prefix).
|
|
||||||
// It is a Test (say) if there is a character after Test that is not a lower-case letter.
|
|
||||||
// We don't want TesticularCancer.
|
|
||||||
func isTest(name, prefix string) bool {
|
|
||||||
if !strings.HasPrefix(name, prefix) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if len(name) == len(prefix) { // "Test" is ok
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
rune, _ := utf8.DecodeRuneInString(name[len(prefix):])
|
|
||||||
return !unicode.IsLower(rune)
|
|
||||||
}
|
|
||||||
|
|
||||||
// loadTestFuncs returns the testFuncs describing the tests that will be run.
|
|
||||||
func loadTestFuncs(ptest, pxtest *Package) (*testFuncs, error) {
|
|
||||||
t := &testFuncs{
|
|
||||||
TestPackage: ptest,
|
|
||||||
XTestPackage: pxtest,
|
|
||||||
}
|
|
||||||
for _, file := range ptest.GoFiles {
|
|
||||||
if !strings.HasSuffix(file, "_test.go") {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if err := t.load(file, "_test", &t.ImportTest, &t.NeedTest); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if pxtest != nil {
|
|
||||||
for _, file := range pxtest.GoFiles {
|
|
||||||
if err := t.load(file, "_xtest", &t.ImportXtest, &t.NeedXtest); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return t, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// writeTestmain writes the _testmain.go file for t to the file named out.
|
|
||||||
func writeTestmain(out string, t *testFuncs) error {
|
|
||||||
f, err := os.Create(out)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer f.Close()
|
|
||||||
|
|
||||||
if err := testmainTmpl.Execute(f, t); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type testFuncs struct {
|
|
||||||
Tests []testFunc
|
|
||||||
Benchmarks []testFunc
|
|
||||||
Examples []testFunc
|
|
||||||
TestMain *testFunc
|
|
||||||
TestPackage *Package
|
|
||||||
XTestPackage *Package
|
|
||||||
ImportTest bool
|
|
||||||
NeedTest bool
|
|
||||||
ImportXtest bool
|
|
||||||
NeedXtest bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tested returns the name of the package being tested.
|
|
||||||
func (t *testFuncs) Tested() string {
|
|
||||||
return t.TestPackage.Name
|
|
||||||
}
|
|
||||||
|
|
||||||
type testFunc struct {
|
|
||||||
Package string // imported package name (_test or _xtest)
|
|
||||||
Name string // function name
|
|
||||||
Output string // output, for examples
|
|
||||||
Unordered bool // output is allowed to be unordered.
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *testFuncs) load(filename, pkg string, doImport, seen *bool) error {
|
|
||||||
var fset = token.NewFileSet()
|
|
||||||
|
|
||||||
f, err := parser.ParseFile(fset, filename, nil, parser.ParseComments)
|
|
||||||
if err != nil {
|
|
||||||
return errors.New("failed to parse test file " + filename)
|
|
||||||
}
|
|
||||||
for _, d := range f.Decls {
|
|
||||||
n, ok := d.(*ast.FuncDecl)
|
|
||||||
if !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if n.Recv != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
name := n.Name.String()
|
|
||||||
switch {
|
|
||||||
case name == "TestMain":
|
|
||||||
if isTestFunc(n, "T") {
|
|
||||||
t.Tests = append(t.Tests, testFunc{pkg, name, "", false})
|
|
||||||
*doImport, *seen = true, true
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
err := checkTestFunc(fset, n, "M")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if t.TestMain != nil {
|
|
||||||
return errors.New("multiple definitions of TestMain")
|
|
||||||
}
|
|
||||||
t.TestMain = &testFunc{pkg, name, "", false}
|
|
||||||
*doImport, *seen = true, true
|
|
||||||
case isTest(name, "Test"):
|
|
||||||
err := checkTestFunc(fset, n, "T")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
t.Tests = append(t.Tests, testFunc{pkg, name, "", false})
|
|
||||||
*doImport, *seen = true, true
|
|
||||||
case isTest(name, "Benchmark"):
|
|
||||||
err := checkTestFunc(fset, n, "B")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
t.Benchmarks = append(t.Benchmarks, testFunc{pkg, name, "", false})
|
|
||||||
*doImport, *seen = true, true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ex := doc.Examples(f)
|
|
||||||
sort.Slice(ex, func(i, j int) bool { return ex[i].Order < ex[j].Order })
|
|
||||||
for _, e := range ex {
|
|
||||||
*doImport = true // import test file whether executed or not
|
|
||||||
if e.Output == "" && !e.EmptyOutput {
|
|
||||||
// Don't run examples with no output.
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
t.Examples = append(t.Examples, testFunc{pkg, "Example" + e.Name, e.Output, e.Unordered})
|
|
||||||
*seen = true
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkTestFunc(fset *token.FileSet, fn *ast.FuncDecl, arg string) error {
|
|
||||||
if !isTestFunc(fn, arg) {
|
|
||||||
name := fn.Name.String()
|
|
||||||
pos := fset.Position(fn.Pos())
|
|
||||||
return fmt.Errorf("%s: wrong signature for %s, must be: func %s(%s *testing.%s)", pos, name, name, strings.ToLower(arg), arg)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var testmainTmpl = template.Must(template.New("main").Parse(`
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
{{if not .TestMain}}
|
|
||||||
"os"
|
|
||||||
{{end}}
|
|
||||||
"testing"
|
|
||||||
"testing/internal/testdeps"
|
|
||||||
|
|
||||||
{{if .ImportTest}}
|
|
||||||
{{if .NeedTest}}_test{{else}}_{{end}} {{.TestPackage.PkgPath | printf "%q"}}
|
|
||||||
{{end}}
|
|
||||||
{{if .ImportXtest}}
|
|
||||||
{{if .NeedXtest}}_xtest{{else}}_{{end}} {{.XTestPackage.PkgPath | printf "%q"}}
|
|
||||||
{{end}}
|
|
||||||
)
|
|
||||||
|
|
||||||
var tests = []testing.InternalTest{
|
|
||||||
{{range .Tests}}
|
|
||||||
{"{{.Name}}", {{.Package}}.{{.Name}}},
|
|
||||||
{{end}}
|
|
||||||
}
|
|
||||||
|
|
||||||
var benchmarks = []testing.InternalBenchmark{
|
|
||||||
{{range .Benchmarks}}
|
|
||||||
{"{{.Name}}", {{.Package}}.{{.Name}}},
|
|
||||||
{{end}}
|
|
||||||
}
|
|
||||||
|
|
||||||
var examples = []testing.InternalExample{
|
|
||||||
{{range .Examples}}
|
|
||||||
{"{{.Name}}", {{.Package}}.{{.Name}}, {{.Output | printf "%q"}}, {{.Unordered}}},
|
|
||||||
{{end}}
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
testdeps.ImportPath = {{.TestPackage.PkgPath | printf "%q"}}
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
m := testing.MainStart(testdeps.TestDeps{}, tests, benchmarks, examples)
|
|
||||||
{{with .TestMain}}
|
|
||||||
{{.Package}}.{{.Name}}(m)
|
|
||||||
{{else}}
|
|
||||||
os.Exit(m.Run())
|
|
||||||
{{end}}
|
|
||||||
}
|
|
||||||
|
|
||||||
`))
|
|
31
vendor/golang.org/x/tools/go/packages/golist_overlay.go
generated
vendored
31
vendor/golang.org/x/tools/go/packages/golist_overlay.go
generated
vendored
@ -46,7 +46,9 @@ outer:
|
|||||||
fileExists = true
|
fileExists = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if dirContains {
|
// The overlay could have included an entirely new package.
|
||||||
|
isNewPackage := extractPackage(pkg, path, contents)
|
||||||
|
if dirContains || isNewPackage {
|
||||||
if !fileExists {
|
if !fileExists {
|
||||||
pkg.GoFiles = append(pkg.GoFiles, path) // TODO(matloob): should the file just be added to GoFiles?
|
pkg.GoFiles = append(pkg.GoFiles, path) // TODO(matloob): should the file just be added to GoFiles?
|
||||||
pkg.CompiledGoFiles = append(pkg.CompiledGoFiles, path)
|
pkg.CompiledGoFiles = append(pkg.CompiledGoFiles, path)
|
||||||
@ -102,3 +104,30 @@ func extractImports(filename string, contents []byte) ([]string, error) {
|
|||||||
}
|
}
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func extractPackage(pkg *Package, filename string, contents []byte) bool {
|
||||||
|
// TODO(rstambler): Check the message of the actual error?
|
||||||
|
// It differs between $GOPATH and module mode.
|
||||||
|
if len(pkg.Errors) != 1 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if pkg.Name != "" || pkg.ExportFile != "" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if len(pkg.GoFiles) > 0 || len(pkg.CompiledGoFiles) > 0 || len(pkg.OtherFiles) > 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if len(pkg.Imports) > 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
f, err := parser.ParseFile(token.NewFileSet(), filename, contents, parser.PackageClauseOnly) // TODO(matloob): reuse fileset?
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if filepath.Base(pkg.PkgPath) != f.Name.Name {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
pkg.Name = f.Name.Name
|
||||||
|
pkg.Errors = []Error{}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
155
vendor/golang.org/x/tools/go/packages/packages.go
generated
vendored
155
vendor/golang.org/x/tools/go/packages/packages.go
generated
vendored
@ -30,32 +30,78 @@ import (
|
|||||||
// but may be slower. Load may return more information than requested.
|
// but may be slower. Load may return more information than requested.
|
||||||
type LoadMode int
|
type LoadMode int
|
||||||
|
|
||||||
|
const (
|
||||||
|
// The following constants are used to specify which fields of the Package
|
||||||
|
// should be filled when loading is done. As a special case to provide
|
||||||
|
// backwards compatibility, a LoadMode of 0 is equivalent to LoadFiles.
|
||||||
|
// For all other LoadModes, the bits below specify which fields will be filled
|
||||||
|
// in the result packages.
|
||||||
|
// WARNING: This part of the go/packages API is EXPERIMENTAL. It might
|
||||||
|
// be changed or removed up until April 15 2019. After that date it will
|
||||||
|
// be frozen.
|
||||||
|
// TODO(matloob): Remove this comment on April 15.
|
||||||
|
|
||||||
|
// ID and Errors (if present) will always be filled.
|
||||||
|
|
||||||
|
// NeedName adds Name and PkgPath.
|
||||||
|
NeedName LoadMode = 1 << iota
|
||||||
|
|
||||||
|
// NeedFiles adds GoFiles and OtherFiles.
|
||||||
|
NeedFiles
|
||||||
|
|
||||||
|
// NeedCompiledGoFiles adds CompiledGoFiles.
|
||||||
|
NeedCompiledGoFiles
|
||||||
|
|
||||||
|
// NeedImports adds Imports. If NeedDeps is not set, the Imports field will contain
|
||||||
|
// "placeholder" Packages with only the ID set.
|
||||||
|
NeedImports
|
||||||
|
|
||||||
|
// NeedDeps adds the fields requested by the LoadMode in the packages in Imports. If NeedImports
|
||||||
|
// is not set NeedDeps has no effect.
|
||||||
|
NeedDeps
|
||||||
|
|
||||||
|
// NeedExportsFile adds ExportsFile.
|
||||||
|
NeedExportsFile
|
||||||
|
|
||||||
|
// NeedTypes adds Types, Fset, and IllTyped.
|
||||||
|
NeedTypes
|
||||||
|
|
||||||
|
// NeedSyntax adds Syntax.
|
||||||
|
NeedSyntax
|
||||||
|
|
||||||
|
// NeedTypesInfo adds TypesInfo.
|
||||||
|
NeedTypesInfo
|
||||||
|
|
||||||
|
// NeedTypesSizes adds TypesSizes.
|
||||||
|
NeedTypesSizes
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// LoadFiles finds the packages and computes their source file lists.
|
// LoadFiles finds the packages and computes their source file lists.
|
||||||
// Package fields: ID, Name, Errors, GoFiles, and OtherFiles.
|
// Package fields: ID, Name, Errors, GoFiles, CompiledGoFiles, and OtherFiles.
|
||||||
LoadFiles LoadMode = iota
|
LoadFiles = NeedName | NeedFiles | NeedCompiledGoFiles
|
||||||
|
|
||||||
// LoadImports adds import information for each package
|
// LoadImports adds import information for each package
|
||||||
// and its dependencies.
|
// and its dependencies.
|
||||||
// Package fields added: Imports.
|
// Package fields added: Imports.
|
||||||
LoadImports
|
LoadImports = LoadFiles | NeedImports | NeedDeps
|
||||||
|
|
||||||
// LoadTypes adds type information for package-level
|
// LoadTypes adds type information for package-level
|
||||||
// declarations in the packages matching the patterns.
|
// declarations in the packages matching the patterns.
|
||||||
// Package fields added: Types, Fset, and IllTyped.
|
// Package fields added: Types, TypesSizes, Fset, and IllTyped.
|
||||||
// This mode uses type information provided by the build system when
|
// This mode uses type information provided by the build system when
|
||||||
// possible, and may fill in the ExportFile field.
|
// possible, and may fill in the ExportFile field.
|
||||||
LoadTypes
|
LoadTypes = LoadImports | NeedTypes | NeedTypesSizes
|
||||||
|
|
||||||
// LoadSyntax adds typed syntax trees for the packages matching the patterns.
|
// LoadSyntax adds typed syntax trees for the packages matching the patterns.
|
||||||
// Package fields added: Syntax, and TypesInfo, for direct pattern matches only.
|
// Package fields added: Syntax, and TypesInfo, for direct pattern matches only.
|
||||||
LoadSyntax
|
LoadSyntax = LoadTypes | NeedSyntax | NeedTypesInfo
|
||||||
|
|
||||||
// LoadAllSyntax adds typed syntax trees for the packages matching the patterns
|
// LoadAllSyntax adds typed syntax trees for the packages matching the patterns
|
||||||
// and all dependencies.
|
// and all dependencies.
|
||||||
// Package fields added: Types, Fset, IllTyped, Syntax, and TypesInfo,
|
// Package fields added: Types, Fset, IllTyped, Syntax, and TypesInfo,
|
||||||
// for all packages in the import graph.
|
// for all packages in the import graph.
|
||||||
LoadAllSyntax
|
LoadAllSyntax = LoadSyntax
|
||||||
)
|
)
|
||||||
|
|
||||||
// A Config specifies details about how packages should be loaded.
|
// A Config specifies details about how packages should be loaded.
|
||||||
@ -91,7 +137,7 @@ type Config struct {
|
|||||||
BuildFlags []string
|
BuildFlags []string
|
||||||
|
|
||||||
// Fset provides source position information for syntax trees and types.
|
// Fset provides source position information for syntax trees and types.
|
||||||
// If Fset is nil, the loader will create a new FileSet.
|
// If Fset is nil, Load will use a new fileset, but preserve Fset's value.
|
||||||
Fset *token.FileSet
|
Fset *token.FileSet
|
||||||
|
|
||||||
// ParseFile is called to read and parse each file
|
// ParseFile is called to read and parse each file
|
||||||
@ -374,6 +420,12 @@ type loader struct {
|
|||||||
Config
|
Config
|
||||||
sizes types.Sizes
|
sizes types.Sizes
|
||||||
exportMu sync.Mutex // enforces mutual exclusion of exportdata operations
|
exportMu sync.Mutex // enforces mutual exclusion of exportdata operations
|
||||||
|
|
||||||
|
// TODO(matloob): Add an implied mode here and use that instead of mode.
|
||||||
|
// Implied mode would contain all the fields we need the data for so we can
|
||||||
|
// get the actually requested fields. We'll zero them out before returning
|
||||||
|
// packages to the user. This will make it easier for us to get the conditions
|
||||||
|
// where we need certain modes right.
|
||||||
}
|
}
|
||||||
|
|
||||||
func newLoader(cfg *Config) *loader {
|
func newLoader(cfg *Config) *loader {
|
||||||
@ -381,6 +433,9 @@ func newLoader(cfg *Config) *loader {
|
|||||||
if cfg != nil {
|
if cfg != nil {
|
||||||
ld.Config = *cfg
|
ld.Config = *cfg
|
||||||
}
|
}
|
||||||
|
if ld.Config.Mode == 0 {
|
||||||
|
ld.Config.Mode = LoadFiles // Preserve zero behavior of Mode for backwards compatibility.
|
||||||
|
}
|
||||||
if ld.Config.Env == nil {
|
if ld.Config.Env == nil {
|
||||||
ld.Config.Env = os.Environ()
|
ld.Config.Env = os.Environ()
|
||||||
}
|
}
|
||||||
@ -393,7 +448,7 @@ func newLoader(cfg *Config) *loader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ld.Mode >= LoadTypes {
|
if ld.Mode&NeedTypes != 0 {
|
||||||
if ld.Fset == nil {
|
if ld.Fset == nil {
|
||||||
ld.Fset = token.NewFileSet()
|
ld.Fset = token.NewFileSet()
|
||||||
}
|
}
|
||||||
@ -430,11 +485,9 @@ func (ld *loader) refine(roots []string, list ...*Package) ([]*Package, error) {
|
|||||||
rootIndex = i
|
rootIndex = i
|
||||||
}
|
}
|
||||||
lpkg := &loaderPackage{
|
lpkg := &loaderPackage{
|
||||||
Package: pkg,
|
Package: pkg,
|
||||||
needtypes: ld.Mode >= LoadAllSyntax ||
|
needtypes: (ld.Mode&(NeedTypes|NeedTypesInfo) != 0 && rootIndex < 0) || rootIndex >= 0,
|
||||||
ld.Mode >= LoadTypes && rootIndex >= 0,
|
needsrc: (ld.Mode&(NeedSyntax|NeedTypesInfo) != 0 && rootIndex < 0) || rootIndex >= 0 ||
|
||||||
needsrc: ld.Mode >= LoadAllSyntax ||
|
|
||||||
ld.Mode >= LoadSyntax && rootIndex >= 0 ||
|
|
||||||
len(ld.Overlay) > 0 || // Overlays can invalidate export data. TODO(matloob): make this check fine-grained based on dependencies on overlaid files
|
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",
|
pkg.ExportFile == "" && pkg.PkgPath != "unsafe",
|
||||||
}
|
}
|
||||||
@ -507,14 +560,17 @@ func (ld *loader) refine(roots []string, list ...*Package) ([]*Package, error) {
|
|||||||
if lpkg.needsrc {
|
if lpkg.needsrc {
|
||||||
srcPkgs = append(srcPkgs, lpkg)
|
srcPkgs = append(srcPkgs, lpkg)
|
||||||
}
|
}
|
||||||
|
if ld.Mode&NeedTypesSizes != 0 {
|
||||||
|
lpkg.TypesSizes = ld.sizes
|
||||||
|
}
|
||||||
stack = stack[:len(stack)-1] // pop
|
stack = stack[:len(stack)-1] // pop
|
||||||
lpkg.color = black
|
lpkg.color = black
|
||||||
|
|
||||||
return lpkg.needsrc
|
return lpkg.needsrc
|
||||||
}
|
}
|
||||||
|
|
||||||
if ld.Mode < LoadImports {
|
if ld.Mode&(NeedImports|NeedDeps) == 0 {
|
||||||
//we do this to drop the stub import packages that we are not even going to try to resolve
|
// We do this to drop the stub import packages that we are not even going to try to resolve.
|
||||||
for _, lpkg := range initial {
|
for _, lpkg := range initial {
|
||||||
lpkg.Imports = nil
|
lpkg.Imports = nil
|
||||||
}
|
}
|
||||||
@ -524,17 +580,19 @@ func (ld *loader) refine(roots []string, list ...*Package) ([]*Package, error) {
|
|||||||
visit(lpkg)
|
visit(lpkg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, lpkg := range srcPkgs {
|
if ld.Mode&NeedDeps != 0 { // TODO(matloob): This is only the case if NeedTypes is also set, right?
|
||||||
// Complete type information is required for the
|
for _, lpkg := range srcPkgs {
|
||||||
// immediate dependencies of each source package.
|
// Complete type information is required for the
|
||||||
for _, ipkg := range lpkg.Imports {
|
// immediate dependencies of each source package.
|
||||||
imp := ld.pkgs[ipkg.ID]
|
for _, ipkg := range lpkg.Imports {
|
||||||
imp.needtypes = true
|
imp := ld.pkgs[ipkg.ID]
|
||||||
|
imp.needtypes = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Load type data if needed, starting at
|
// Load type data if needed, starting at
|
||||||
// the initial packages (roots of the import DAG).
|
// the initial packages (roots of the import DAG).
|
||||||
if ld.Mode >= LoadTypes {
|
if ld.Mode&NeedTypes != 0 {
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
for _, lpkg := range initial {
|
for _, lpkg := range initial {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
@ -547,16 +605,61 @@ func (ld *loader) refine(roots []string, list ...*Package) ([]*Package, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
result := make([]*Package, len(initial))
|
result := make([]*Package, len(initial))
|
||||||
|
importPlaceholders := make(map[string]*Package)
|
||||||
for i, lpkg := range initial {
|
for i, lpkg := range initial {
|
||||||
result[i] = lpkg.Package
|
result[i] = lpkg.Package
|
||||||
}
|
}
|
||||||
|
for i := range ld.pkgs {
|
||||||
|
// Clear all unrequested fields, for extra de-Hyrum-ization.
|
||||||
|
if ld.Mode&NeedName == 0 {
|
||||||
|
ld.pkgs[i].Name = ""
|
||||||
|
ld.pkgs[i].PkgPath = ""
|
||||||
|
}
|
||||||
|
if ld.Mode&NeedFiles == 0 {
|
||||||
|
ld.pkgs[i].GoFiles = nil
|
||||||
|
ld.pkgs[i].OtherFiles = nil
|
||||||
|
}
|
||||||
|
if ld.Mode&NeedCompiledGoFiles == 0 {
|
||||||
|
ld.pkgs[i].CompiledGoFiles = nil
|
||||||
|
}
|
||||||
|
if ld.Mode&NeedImports == 0 {
|
||||||
|
ld.pkgs[i].Imports = nil
|
||||||
|
}
|
||||||
|
if ld.Mode&NeedExportsFile == 0 {
|
||||||
|
ld.pkgs[i].ExportFile = ""
|
||||||
|
}
|
||||||
|
if ld.Mode&NeedTypes == 0 {
|
||||||
|
ld.pkgs[i].Types = nil
|
||||||
|
ld.pkgs[i].Fset = nil
|
||||||
|
ld.pkgs[i].IllTyped = false
|
||||||
|
}
|
||||||
|
if ld.Mode&NeedSyntax == 0 {
|
||||||
|
ld.pkgs[i].Syntax = nil
|
||||||
|
}
|
||||||
|
if ld.Mode&NeedTypesInfo == 0 {
|
||||||
|
ld.pkgs[i].TypesInfo = nil
|
||||||
|
}
|
||||||
|
if ld.Mode&NeedTypesSizes == 0 {
|
||||||
|
ld.pkgs[i].TypesSizes = nil
|
||||||
|
}
|
||||||
|
if ld.Mode&NeedDeps == 0 {
|
||||||
|
for j, pkg := range ld.pkgs[i].Imports {
|
||||||
|
ph, ok := importPlaceholders[pkg.ID]
|
||||||
|
if !ok {
|
||||||
|
ph = &Package{ID: pkg.ID}
|
||||||
|
importPlaceholders[pkg.ID] = ph
|
||||||
|
}
|
||||||
|
ld.pkgs[i].Imports[j] = ph
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// loadRecursive loads the specified package and its dependencies,
|
// loadRecursive loads the specified package and its dependencies,
|
||||||
// recursively, in parallel, in topological order.
|
// recursively, in parallel, in topological order.
|
||||||
// It is atomic and idempotent.
|
// It is atomic and idempotent.
|
||||||
// Precondition: ld.Mode >= LoadTypes.
|
// Precondition: ld.Mode&NeedTypes.
|
||||||
func (ld *loader) loadRecursive(lpkg *loaderPackage) {
|
func (ld *loader) loadRecursive(lpkg *loaderPackage) {
|
||||||
lpkg.loadOnce.Do(func() {
|
lpkg.loadOnce.Do(func() {
|
||||||
// Load the direct dependencies, in parallel.
|
// Load the direct dependencies, in parallel.
|
||||||
@ -708,7 +811,7 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) {
|
|||||||
// Type-check bodies of functions only in non-initial packages.
|
// Type-check bodies of functions only in non-initial packages.
|
||||||
// Example: for import graph A->B->C and initial packages {A,C},
|
// Example: for import graph A->B->C and initial packages {A,C},
|
||||||
// we can ignore function bodies in B.
|
// we can ignore function bodies in B.
|
||||||
IgnoreFuncBodies: ld.Mode < LoadAllSyntax && !lpkg.initial,
|
IgnoreFuncBodies: (ld.Mode&(NeedDeps|NeedTypesInfo) == 0) && !lpkg.initial,
|
||||||
|
|
||||||
Error: appendError,
|
Error: appendError,
|
||||||
Sizes: ld.sizes,
|
Sizes: ld.sizes,
|
||||||
@ -952,5 +1055,5 @@ func (ld *loader) loadFromExportData(lpkg *loaderPackage) (*types.Package, error
|
|||||||
}
|
}
|
||||||
|
|
||||||
func usesExportData(cfg *Config) bool {
|
func usesExportData(cfg *Config) bool {
|
||||||
return LoadTypes <= cfg.Mode && cfg.Mode < LoadAllSyntax
|
return cfg.Mode&NeedExportsFile != 0 || cfg.Mode&NeedTypes != 0 && cfg.Mode&NeedTypesInfo == 0
|
||||||
}
|
}
|
||||||
|
2
vendor/golang.org/x/tools/imports/fix.go
generated
vendored
2
vendor/golang.org/x/tools/imports/fix.go
generated
vendored
@ -1043,7 +1043,7 @@ func findImport(ctx context.Context, env *fixEnv, dirScan []*pkg, pkgName string
|
|||||||
// Find candidate packages, looking only at their directory names first.
|
// Find candidate packages, looking only at their directory names first.
|
||||||
var candidates []pkgDistance
|
var candidates []pkgDistance
|
||||||
for _, pkg := range dirScan {
|
for _, pkg := range dirScan {
|
||||||
if pkgIsCandidate(filename, pkgName, pkg) {
|
if pkg.dir != pkgDir && pkgIsCandidate(filename, pkgName, pkg) {
|
||||||
candidates = append(candidates, pkgDistance{
|
candidates = append(candidates, pkgDistance{
|
||||||
pkg: pkg,
|
pkg: pkg,
|
||||||
distance: distance(pkgDir, pkg.dir),
|
distance: distance(pkgDir, pkg.dir),
|
||||||
|
20
vendor/golang.org/x/tools/imports/mkstdlib.go
generated
vendored
20
vendor/golang.org/x/tools/imports/mkstdlib.go
generated
vendored
@ -14,6 +14,7 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
"runtime"
|
"runtime"
|
||||||
@ -59,6 +60,10 @@ func main() {
|
|||||||
mustOpen(api("go1.10.txt")),
|
mustOpen(api("go1.10.txt")),
|
||||||
mustOpen(api("go1.11.txt")),
|
mustOpen(api("go1.11.txt")),
|
||||||
mustOpen(api("go1.12.txt")),
|
mustOpen(api("go1.12.txt")),
|
||||||
|
|
||||||
|
// The API of the syscall/js package needs to be computed explicitly,
|
||||||
|
// because it's not included in the GOROOT/api/go1.*.txt files at this time.
|
||||||
|
syscallJSAPI(),
|
||||||
)
|
)
|
||||||
sc := bufio.NewScanner(f)
|
sc := bufio.NewScanner(f)
|
||||||
|
|
||||||
@ -110,3 +115,18 @@ func main() {
|
|||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// syscallJSAPI returns the API of the syscall/js package.
|
||||||
|
// It's computed from the contents of $(go env GOROOT)/src/syscall/js.
|
||||||
|
func syscallJSAPI() io.Reader {
|
||||||
|
var exeSuffix string
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
exeSuffix = ".exe"
|
||||||
|
}
|
||||||
|
cmd := exec.Command("go"+exeSuffix, "run", "cmd/api", "-contexts", "js-wasm", "syscall/js")
|
||||||
|
out, err := cmd.Output()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
return bytes.NewReader(out)
|
||||||
|
}
|
||||||
|
23
vendor/golang.org/x/tools/imports/zstdlib.go
generated
vendored
23
vendor/golang.org/x/tools/imports/zstdlib.go
generated
vendored
@ -9783,6 +9783,29 @@ var stdlib = map[string]map[string]bool{
|
|||||||
"XP1_UNI_RECV": true,
|
"XP1_UNI_RECV": true,
|
||||||
"XP1_UNI_SEND": true,
|
"XP1_UNI_SEND": true,
|
||||||
},
|
},
|
||||||
|
"syscall/js": map[string]bool{
|
||||||
|
"Error": true,
|
||||||
|
"Func": true,
|
||||||
|
"FuncOf": true,
|
||||||
|
"Global": true,
|
||||||
|
"Null": true,
|
||||||
|
"Type": true,
|
||||||
|
"TypeBoolean": true,
|
||||||
|
"TypeFunction": true,
|
||||||
|
"TypeNull": true,
|
||||||
|
"TypeNumber": true,
|
||||||
|
"TypeObject": true,
|
||||||
|
"TypeString": true,
|
||||||
|
"TypeSymbol": true,
|
||||||
|
"TypeUndefined": true,
|
||||||
|
"TypedArray": true,
|
||||||
|
"TypedArrayOf": true,
|
||||||
|
"Undefined": true,
|
||||||
|
"Value": true,
|
||||||
|
"ValueError": true,
|
||||||
|
"ValueOf": true,
|
||||||
|
"Wrapper": true,
|
||||||
|
},
|
||||||
"testing": map[string]bool{
|
"testing": map[string]bool{
|
||||||
"AllocsPerRun": true,
|
"AllocsPerRun": true,
|
||||||
"B": true,
|
"B": true,
|
||||||
|
2
vendor/modules.txt
vendored
2
vendor/modules.txt
vendored
@ -190,7 +190,7 @@ golang.org/x/sys/windows
|
|||||||
golang.org/x/text/width
|
golang.org/x/text/width
|
||||||
golang.org/x/text/transform
|
golang.org/x/text/transform
|
||||||
golang.org/x/text/unicode/norm
|
golang.org/x/text/unicode/norm
|
||||||
# golang.org/x/tools v0.0.0-20190314010720-f0bfdbff1f9c
|
# golang.org/x/tools v0.0.0-20190420000508-685fecacd0a0
|
||||||
golang.org/x/tools/go/analysis
|
golang.org/x/tools/go/analysis
|
||||||
golang.org/x/tools/go/analysis/passes/asmdecl
|
golang.org/x/tools/go/analysis/passes/asmdecl
|
||||||
golang.org/x/tools/go/analysis/passes/assign
|
golang.org/x/tools/go/analysis/passes/assign
|
||||||
|
Loading…
x
Reference in New Issue
Block a user