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/net v0.0.0-20190313220215-9f648a60d977 // 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/gemnasium/logrus-airbrake-hook.v2 v2.1.2 // indirect
|
||||
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-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-20190314010720-f0bfdbff1f9c h1:nE2ID2IbO0sUUG/3vWMz0LStAvkaW9wpnFp/65bxJw8=
|
||||
golang.org/x/tools v0.0.0-20190314010720-f0bfdbff1f9c/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190420000508-685fecacd0a0 h1:pa1CyBALPFjblgkNQp7T7gEcFcG/GOG5Ck8IcnSVWGs=
|
||||
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/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
|
||||
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 (
|
||||
"go/ast"
|
||||
"go/token"
|
||||
"go/types"
|
||||
"strings"
|
||||
|
||||
@ -163,7 +162,7 @@ func matchParams(pass *analysis.Pass, expect []string, actual *types.Tuple, pref
|
||||
if i >= actual.Len() {
|
||||
return false
|
||||
}
|
||||
if !matchParamType(pass.Fset, pass.Pkg, x, actual.At(i).Type()) {
|
||||
if !matchParamType(x, actual.At(i).Type()) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
@ -174,13 +173,8 @@ func matchParams(pass *analysis.Pass, expect []string, actual *types.Tuple, pref
|
||||
}
|
||||
|
||||
// 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, "=")
|
||||
// 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.
|
||||
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
|
||||
}
|
||||
|
||||
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 {
|
||||
return o
|
||||
return []types.Object{o}
|
||||
}
|
||||
|
||||
// If this package is ".../foo_test" and it imports a package
|
||||
// ".../foo", try looking in the latter package.
|
||||
// This heuristic should work even on build systems that do not
|
||||
// record any special link between the packages.
|
||||
if basePath := strings.TrimSuffix(pkg.Path(), "_test"); basePath != pkg.Path() {
|
||||
for _, imp := range pkg.Imports() {
|
||||
if imp.Path() == basePath {
|
||||
return imp.Scope().Lookup(name)
|
||||
}
|
||||
var ret []types.Object
|
||||
// Search through the imports to see if any of them define name.
|
||||
// It's hard to tell in general which package is being tested, so
|
||||
// for the purposes of the analysis, allow the object to appear
|
||||
// in any of the imports. This guarantees there are no false positives
|
||||
// because the example needs to use the object so it must be defined
|
||||
// in the package or one if its imports. On the other hand, false
|
||||
// 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) {
|
||||
@ -121,9 +123,9 @@ func checkExample(pass *analysis.Pass, fn *ast.FuncDecl) {
|
||||
exName = strings.TrimPrefix(fnName, "Example")
|
||||
elems = strings.SplitN(exName, "_", 3)
|
||||
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.
|
||||
pass.Reportf(fn.Pos(), "%s refers to unknown identifier: %s", fnName, ident)
|
||||
// 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]
|
||||
if !isExampleSuffix(mmbr) {
|
||||
// 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)
|
||||
}
|
||||
}
|
||||
|
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
|
||||
type driverRequest struct {
|
||||
Command string `json "command"`
|
||||
Command string `json:"command"`
|
||||
Mode LoadMode `json:"mode"`
|
||||
Env []string `json:"env"`
|
||||
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 sizeserr error
|
||||
var sizeswg sync.WaitGroup
|
||||
if cfg.Mode >= LoadTypes {
|
||||
if cfg.Mode&NeedTypesSizes != 0 || cfg.Mode&NeedTypes != 0 {
|
||||
sizeswg.Add(1)
|
||||
go func() {
|
||||
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{}
|
||||
var err error
|
||||
|
||||
@ -142,7 +128,7 @@ extractQueries:
|
||||
// patterns also requires a go list call, since it's the equivalent of
|
||||
// ".".
|
||||
if len(restPatterns) > 0 || len(patterns) == 0 {
|
||||
dr, err := listfunc(cfg, restPatterns...)
|
||||
dr, err := golistDriver(cfg, restPatterns...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -161,13 +147,13 @@ extractQueries:
|
||||
var containsCandidates []string
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
@ -180,12 +166,8 @@ extractQueries:
|
||||
containsCandidates = append(containsCandidates, modifiedPkgs...)
|
||||
containsCandidates = append(containsCandidates, needPkgs...)
|
||||
}
|
||||
|
||||
if len(needPkgs) > 0 {
|
||||
addNeededOverlayPackages(cfg, listfunc, response, needPkgs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := addNeededOverlayPackages(cfg, golistDriver, response, needPkgs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Check candidate packages for containFiles.
|
||||
if len(containFiles) > 0 {
|
||||
@ -205,6 +187,9 @@ extractQueries:
|
||||
}
|
||||
|
||||
func addNeededOverlayPackages(cfg *Config, driver driver, response *responseDeduper, pkgs []string) error {
|
||||
if len(pkgs) == 0 {
|
||||
return nil
|
||||
}
|
||||
dr, err := driver(cfg, pkgs...)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -212,10 +197,15 @@ func addNeededOverlayPackages(cfg *Config, driver driver, response *responseDedu
|
||||
for _, pkg := range dr.Packages {
|
||||
response.addPackage(pkg)
|
||||
}
|
||||
_, needPkgs, err := processGolistOverlay(cfg, response.dr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
addNeededOverlayPackages(cfg, driver, response, needPkgs)
|
||||
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 {
|
||||
// TODO(matloob): Do only one query per directory.
|
||||
fdir := filepath.Dir(query)
|
||||
@ -225,11 +215,6 @@ func runContainsQueries(cfg *Config, driver driver, isFallback bool, response *r
|
||||
if err != nil {
|
||||
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)
|
||||
if err != nil {
|
||||
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}
|
||||
}
|
||||
|
||||
// golistDriverCurrent 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 golistDriverCurrent(cfg *Config, words ...string) (*driverResponse, error) {
|
||||
// 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) {
|
||||
// go list uses the following identifiers in ImportPath and Imports:
|
||||
//
|
||||
// "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 !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
|
||||
continue
|
||||
@ -720,14 +705,16 @@ func absJoin(dir string, fileses ...[]string) (res []string) {
|
||||
}
|
||||
|
||||
func golistargs(cfg *Config, words []string) []string {
|
||||
const findFlags = NeedImports | NeedTypes | NeedSyntax | NeedTypesInfo
|
||||
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("-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,
|
||||
// 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, "--")
|
||||
@ -757,10 +744,14 @@ func invokeGo(cfg *Config, args ...string) (*bytes.Buffer, error) {
|
||||
}
|
||||
|
||||
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)
|
||||
if !ok {
|
||||
// Catastrophic error:
|
||||
// - executable not found
|
||||
// - context cancellation
|
||||
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)}
|
||||
}
|
||||
|
||||
// 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.
|
||||
// If that build fails, errors appear on stderr
|
||||
// (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
|
||||
}
|
||||
}
|
||||
if dirContains {
|
||||
// The overlay could have included an entirely new package.
|
||||
isNewPackage := extractPackage(pkg, path, contents)
|
||||
if dirContains || isNewPackage {
|
||||
if !fileExists {
|
||||
pkg.GoFiles = append(pkg.GoFiles, path) // TODO(matloob): should the file just be added to GoFiles?
|
||||
pkg.CompiledGoFiles = append(pkg.CompiledGoFiles, path)
|
||||
@ -102,3 +104,30 @@ func extractImports(filename string, contents []byte) ([]string, error) {
|
||||
}
|
||||
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.
|
||||
type LoadMode int
|
||||
|
||||
const (
|
||||
// The following constants are used to specify which fields of the Package
|
||||
// should be filled when loading is done. As a special case to provide
|
||||
// backwards compatibility, a LoadMode of 0 is equivalent to LoadFiles.
|
||||
// For all other LoadModes, the bits below specify which fields will be filled
|
||||
// in the result packages.
|
||||
// WARNING: This part of the go/packages API is EXPERIMENTAL. It might
|
||||
// be changed or removed up until April 15 2019. After that date it will
|
||||
// be frozen.
|
||||
// TODO(matloob): Remove this comment on April 15.
|
||||
|
||||
// ID and Errors (if present) will always be filled.
|
||||
|
||||
// NeedName adds Name and PkgPath.
|
||||
NeedName LoadMode = 1 << iota
|
||||
|
||||
// NeedFiles adds GoFiles and OtherFiles.
|
||||
NeedFiles
|
||||
|
||||
// NeedCompiledGoFiles adds CompiledGoFiles.
|
||||
NeedCompiledGoFiles
|
||||
|
||||
// NeedImports adds Imports. If NeedDeps is not set, the Imports field will contain
|
||||
// "placeholder" Packages with only the ID set.
|
||||
NeedImports
|
||||
|
||||
// NeedDeps adds the fields requested by the LoadMode in the packages in Imports. If NeedImports
|
||||
// is not set NeedDeps has no effect.
|
||||
NeedDeps
|
||||
|
||||
// NeedExportsFile adds ExportsFile.
|
||||
NeedExportsFile
|
||||
|
||||
// NeedTypes adds Types, Fset, and IllTyped.
|
||||
NeedTypes
|
||||
|
||||
// NeedSyntax adds Syntax.
|
||||
NeedSyntax
|
||||
|
||||
// NeedTypesInfo adds TypesInfo.
|
||||
NeedTypesInfo
|
||||
|
||||
// NeedTypesSizes adds TypesSizes.
|
||||
NeedTypesSizes
|
||||
)
|
||||
|
||||
const (
|
||||
// LoadFiles finds the packages and computes their source file lists.
|
||||
// Package fields: ID, Name, Errors, GoFiles, and OtherFiles.
|
||||
LoadFiles LoadMode = iota
|
||||
// Package fields: ID, Name, Errors, GoFiles, CompiledGoFiles, and OtherFiles.
|
||||
LoadFiles = NeedName | NeedFiles | NeedCompiledGoFiles
|
||||
|
||||
// LoadImports adds import information for each package
|
||||
// and its dependencies.
|
||||
// Package fields added: Imports.
|
||||
LoadImports
|
||||
LoadImports = LoadFiles | NeedImports | NeedDeps
|
||||
|
||||
// LoadTypes adds type information for package-level
|
||||
// declarations in the packages matching the patterns.
|
||||
// Package fields added: Types, Fset, and IllTyped.
|
||||
// Package fields added: Types, TypesSizes, Fset, and IllTyped.
|
||||
// This mode uses type information provided by the build system when
|
||||
// possible, and may fill in the ExportFile field.
|
||||
LoadTypes
|
||||
LoadTypes = LoadImports | NeedTypes | NeedTypesSizes
|
||||
|
||||
// LoadSyntax adds typed syntax trees for the packages matching the patterns.
|
||||
// Package fields added: Syntax, and TypesInfo, for direct pattern matches only.
|
||||
LoadSyntax
|
||||
LoadSyntax = LoadTypes | NeedSyntax | NeedTypesInfo
|
||||
|
||||
// LoadAllSyntax adds typed syntax trees for the packages matching the patterns
|
||||
// and all dependencies.
|
||||
// Package fields added: Types, Fset, IllTyped, Syntax, and TypesInfo,
|
||||
// for all packages in the import graph.
|
||||
LoadAllSyntax
|
||||
LoadAllSyntax = LoadSyntax
|
||||
)
|
||||
|
||||
// A Config specifies details about how packages should be loaded.
|
||||
@ -91,7 +137,7 @@ type Config struct {
|
||||
BuildFlags []string
|
||||
|
||||
// Fset provides source position information for syntax trees and types.
|
||||
// If Fset is nil, the loader will create a new FileSet.
|
||||
// If Fset is nil, Load will use a new fileset, but preserve Fset's value.
|
||||
Fset *token.FileSet
|
||||
|
||||
// ParseFile is called to read and parse each file
|
||||
@ -374,6 +420,12 @@ type loader struct {
|
||||
Config
|
||||
sizes types.Sizes
|
||||
exportMu sync.Mutex // enforces mutual exclusion of exportdata operations
|
||||
|
||||
// TODO(matloob): Add an implied mode here and use that instead of mode.
|
||||
// Implied mode would contain all the fields we need the data for so we can
|
||||
// get the actually requested fields. We'll zero them out before returning
|
||||
// packages to the user. This will make it easier for us to get the conditions
|
||||
// where we need certain modes right.
|
||||
}
|
||||
|
||||
func newLoader(cfg *Config) *loader {
|
||||
@ -381,6 +433,9 @@ func newLoader(cfg *Config) *loader {
|
||||
if cfg != nil {
|
||||
ld.Config = *cfg
|
||||
}
|
||||
if ld.Config.Mode == 0 {
|
||||
ld.Config.Mode = LoadFiles // Preserve zero behavior of Mode for backwards compatibility.
|
||||
}
|
||||
if ld.Config.Env == nil {
|
||||
ld.Config.Env = os.Environ()
|
||||
}
|
||||
@ -393,7 +448,7 @@ func newLoader(cfg *Config) *loader {
|
||||
}
|
||||
}
|
||||
|
||||
if ld.Mode >= LoadTypes {
|
||||
if ld.Mode&NeedTypes != 0 {
|
||||
if ld.Fset == nil {
|
||||
ld.Fset = token.NewFileSet()
|
||||
}
|
||||
@ -430,11 +485,9 @@ func (ld *loader) refine(roots []string, list ...*Package) ([]*Package, error) {
|
||||
rootIndex = i
|
||||
}
|
||||
lpkg := &loaderPackage{
|
||||
Package: pkg,
|
||||
needtypes: ld.Mode >= LoadAllSyntax ||
|
||||
ld.Mode >= LoadTypes && rootIndex >= 0,
|
||||
needsrc: ld.Mode >= LoadAllSyntax ||
|
||||
ld.Mode >= LoadSyntax && rootIndex >= 0 ||
|
||||
Package: pkg,
|
||||
needtypes: (ld.Mode&(NeedTypes|NeedTypesInfo) != 0 && rootIndex < 0) || rootIndex >= 0,
|
||||
needsrc: (ld.Mode&(NeedSyntax|NeedTypesInfo) != 0 && rootIndex < 0) || rootIndex >= 0 ||
|
||||
len(ld.Overlay) > 0 || // Overlays can invalidate export data. TODO(matloob): make this check fine-grained based on dependencies on overlaid files
|
||||
pkg.ExportFile == "" && pkg.PkgPath != "unsafe",
|
||||
}
|
||||
@ -507,14 +560,17 @@ func (ld *loader) refine(roots []string, list ...*Package) ([]*Package, error) {
|
||||
if lpkg.needsrc {
|
||||
srcPkgs = append(srcPkgs, lpkg)
|
||||
}
|
||||
if ld.Mode&NeedTypesSizes != 0 {
|
||||
lpkg.TypesSizes = ld.sizes
|
||||
}
|
||||
stack = stack[:len(stack)-1] // pop
|
||||
lpkg.color = black
|
||||
|
||||
return lpkg.needsrc
|
||||
}
|
||||
|
||||
if ld.Mode < LoadImports {
|
||||
//we do this to drop the stub import packages that we are not even going to try to resolve
|
||||
if ld.Mode&(NeedImports|NeedDeps) == 0 {
|
||||
// We do this to drop the stub import packages that we are not even going to try to resolve.
|
||||
for _, lpkg := range initial {
|
||||
lpkg.Imports = nil
|
||||
}
|
||||
@ -524,17 +580,19 @@ func (ld *loader) refine(roots []string, list ...*Package) ([]*Package, error) {
|
||||
visit(lpkg)
|
||||
}
|
||||
}
|
||||
for _, lpkg := range srcPkgs {
|
||||
// Complete type information is required for the
|
||||
// immediate dependencies of each source package.
|
||||
for _, ipkg := range lpkg.Imports {
|
||||
imp := ld.pkgs[ipkg.ID]
|
||||
imp.needtypes = true
|
||||
if ld.Mode&NeedDeps != 0 { // TODO(matloob): This is only the case if NeedTypes is also set, right?
|
||||
for _, lpkg := range srcPkgs {
|
||||
// Complete type information is required for the
|
||||
// immediate dependencies of each source package.
|
||||
for _, ipkg := range lpkg.Imports {
|
||||
imp := ld.pkgs[ipkg.ID]
|
||||
imp.needtypes = true
|
||||
}
|
||||
}
|
||||
}
|
||||
// Load type data if needed, starting at
|
||||
// the initial packages (roots of the import DAG).
|
||||
if ld.Mode >= LoadTypes {
|
||||
if ld.Mode&NeedTypes != 0 {
|
||||
var wg sync.WaitGroup
|
||||
for _, lpkg := range initial {
|
||||
wg.Add(1)
|
||||
@ -547,16 +605,61 @@ func (ld *loader) refine(roots []string, list ...*Package) ([]*Package, error) {
|
||||
}
|
||||
|
||||
result := make([]*Package, len(initial))
|
||||
importPlaceholders := make(map[string]*Package)
|
||||
for i, lpkg := range initial {
|
||||
result[i] = lpkg.Package
|
||||
}
|
||||
for i := range ld.pkgs {
|
||||
// Clear all unrequested fields, for extra de-Hyrum-ization.
|
||||
if ld.Mode&NeedName == 0 {
|
||||
ld.pkgs[i].Name = ""
|
||||
ld.pkgs[i].PkgPath = ""
|
||||
}
|
||||
if ld.Mode&NeedFiles == 0 {
|
||||
ld.pkgs[i].GoFiles = nil
|
||||
ld.pkgs[i].OtherFiles = nil
|
||||
}
|
||||
if ld.Mode&NeedCompiledGoFiles == 0 {
|
||||
ld.pkgs[i].CompiledGoFiles = nil
|
||||
}
|
||||
if ld.Mode&NeedImports == 0 {
|
||||
ld.pkgs[i].Imports = nil
|
||||
}
|
||||
if ld.Mode&NeedExportsFile == 0 {
|
||||
ld.pkgs[i].ExportFile = ""
|
||||
}
|
||||
if ld.Mode&NeedTypes == 0 {
|
||||
ld.pkgs[i].Types = nil
|
||||
ld.pkgs[i].Fset = nil
|
||||
ld.pkgs[i].IllTyped = false
|
||||
}
|
||||
if ld.Mode&NeedSyntax == 0 {
|
||||
ld.pkgs[i].Syntax = nil
|
||||
}
|
||||
if ld.Mode&NeedTypesInfo == 0 {
|
||||
ld.pkgs[i].TypesInfo = nil
|
||||
}
|
||||
if ld.Mode&NeedTypesSizes == 0 {
|
||||
ld.pkgs[i].TypesSizes = nil
|
||||
}
|
||||
if ld.Mode&NeedDeps == 0 {
|
||||
for j, pkg := range ld.pkgs[i].Imports {
|
||||
ph, ok := importPlaceholders[pkg.ID]
|
||||
if !ok {
|
||||
ph = &Package{ID: pkg.ID}
|
||||
importPlaceholders[pkg.ID] = ph
|
||||
}
|
||||
ld.pkgs[i].Imports[j] = ph
|
||||
}
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// loadRecursive loads the specified package and its dependencies,
|
||||
// recursively, in parallel, in topological order.
|
||||
// It is atomic and idempotent.
|
||||
// Precondition: ld.Mode >= LoadTypes.
|
||||
// Precondition: ld.Mode&NeedTypes.
|
||||
func (ld *loader) loadRecursive(lpkg *loaderPackage) {
|
||||
lpkg.loadOnce.Do(func() {
|
||||
// Load the direct dependencies, in parallel.
|
||||
@ -708,7 +811,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 < LoadAllSyntax && !lpkg.initial,
|
||||
IgnoreFuncBodies: (ld.Mode&(NeedDeps|NeedTypesInfo) == 0) && !lpkg.initial,
|
||||
|
||||
Error: appendError,
|
||||
Sizes: ld.sizes,
|
||||
@ -952,5 +1055,5 @@ func (ld *loader) loadFromExportData(lpkg *loaderPackage) (*types.Package, error
|
||||
}
|
||||
|
||||
func usesExportData(cfg *Config) bool {
|
||||
return LoadTypes <= cfg.Mode && cfg.Mode < LoadAllSyntax
|
||||
return cfg.Mode&NeedExportsFile != 0 || cfg.Mode&NeedTypes != 0 && cfg.Mode&NeedTypesInfo == 0
|
||||
}
|
||||
|
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.
|
||||
var candidates []pkgDistance
|
||||
for _, pkg := range dirScan {
|
||||
if pkgIsCandidate(filename, pkgName, pkg) {
|
||||
if pkg.dir != pkgDir && pkgIsCandidate(filename, pkgName, pkg) {
|
||||
candidates = append(candidates, pkgDistance{
|
||||
pkg: pkg,
|
||||
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"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime"
|
||||
@ -59,6 +60,10 @@ func main() {
|
||||
mustOpen(api("go1.10.txt")),
|
||||
mustOpen(api("go1.11.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)
|
||||
|
||||
@ -110,3 +115,18 @@ func main() {
|
||||
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_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{
|
||||
"AllocsPerRun": 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/transform
|
||||
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/passes/asmdecl
|
||||
golang.org/x/tools/go/analysis/passes/assign
|
||||
|
Loading…
x
Reference in New Issue
Block a user