From ce354a6afbf1813c9a5565a00f6937c1b6fd1e42 Mon Sep 17 00:00:00 2001 From: "Kali Kaneko (leap communications)" Date: Fri, 18 Jan 2019 16:45:30 +0100 Subject: [pkg] remove vendoring of golang/x/* I think there's no need of vendoring this. The debian package builds fine without them - at least with the text-dev package in testing. --- vendor/golang.org/x/tools/go/loader/cgo.go | 207 ---- .../golang.org/x/tools/go/loader/cgo_pkgconfig.go | 39 - vendor/golang.org/x/tools/go/loader/doc.go | 205 ---- .../golang.org/x/tools/go/loader/example_test.go | 179 ---- vendor/golang.org/x/tools/go/loader/loader.go | 1077 -------------------- vendor/golang.org/x/tools/go/loader/loader_test.go | 816 --------------- vendor/golang.org/x/tools/go/loader/stdlib_test.go | 201 ---- vendor/golang.org/x/tools/go/loader/testdata/a.go | 1 - vendor/golang.org/x/tools/go/loader/testdata/b.go | 1 - .../x/tools/go/loader/testdata/badpkgdecl.go | 1 - vendor/golang.org/x/tools/go/loader/util.go | 124 --- 11 files changed, 2851 deletions(-) delete mode 100644 vendor/golang.org/x/tools/go/loader/cgo.go delete mode 100644 vendor/golang.org/x/tools/go/loader/cgo_pkgconfig.go delete mode 100644 vendor/golang.org/x/tools/go/loader/doc.go delete mode 100644 vendor/golang.org/x/tools/go/loader/example_test.go delete mode 100644 vendor/golang.org/x/tools/go/loader/loader.go delete mode 100644 vendor/golang.org/x/tools/go/loader/loader_test.go delete mode 100644 vendor/golang.org/x/tools/go/loader/stdlib_test.go delete mode 100644 vendor/golang.org/x/tools/go/loader/testdata/a.go delete mode 100644 vendor/golang.org/x/tools/go/loader/testdata/b.go delete mode 100644 vendor/golang.org/x/tools/go/loader/testdata/badpkgdecl.go delete mode 100644 vendor/golang.org/x/tools/go/loader/util.go (limited to 'vendor/golang.org/x/tools/go/loader') diff --git a/vendor/golang.org/x/tools/go/loader/cgo.go b/vendor/golang.org/x/tools/go/loader/cgo.go deleted file mode 100644 index 72c6f50..0000000 --- a/vendor/golang.org/x/tools/go/loader/cgo.go +++ /dev/null @@ -1,207 +0,0 @@ -// Copyright 2013 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 loader - -// This file handles cgo preprocessing of files containing `import "C"`. -// -// DESIGN -// -// The approach taken is to run the cgo processor on the package's -// CgoFiles and parse the output, faking the filenames of the -// resulting ASTs so that the synthetic file containing the C types is -// called "C" (e.g. "~/go/src/net/C") and the preprocessed files -// have their original names (e.g. "~/go/src/net/cgo_unix.go"), -// not the names of the actual temporary files. -// -// The advantage of this approach is its fidelity to 'go build'. The -// downside is that the token.Position.Offset for each AST node is -// incorrect, being an offset within the temporary file. Line numbers -// should still be correct because of the //line comments. -// -// The logic of this file is mostly plundered from the 'go build' -// tool, which also invokes the cgo preprocessor. -// -// -// REJECTED ALTERNATIVE -// -// An alternative approach that we explored is to extend go/types' -// Importer mechanism to provide the identity of the importing package -// so that each time `import "C"` appears it resolves to a different -// synthetic package containing just the objects needed in that case. -// The loader would invoke cgo but parse only the cgo_types.go file -// defining the package-level objects, discarding the other files -// resulting from preprocessing. -// -// The benefit of this approach would have been that source-level -// syntax information would correspond exactly to the original cgo -// file, with no preprocessing involved, making source tools like -// godoc, guru, and eg happy. However, the approach was rejected -// due to the additional complexity it would impose on go/types. (It -// made for a beautiful demo, though.) -// -// cgo files, despite their *.go extension, are not legal Go source -// files per the specification since they may refer to unexported -// members of package "C" such as C.int. Also, a function such as -// C.getpwent has in effect two types, one matching its C type and one -// which additionally returns (errno C.int). The cgo preprocessor -// uses name mangling to distinguish these two functions in the -// processed code, but go/types would need to duplicate this logic in -// its handling of function calls, analogous to the treatment of map -// lookups in which y=m[k] and y,ok=m[k] are both legal. - -import ( - "fmt" - "go/ast" - "go/build" - "go/parser" - "go/token" - "io/ioutil" - "log" - "os" - "os/exec" - "path/filepath" - "regexp" - "strings" -) - -// processCgoFiles invokes the cgo preprocessor on bp.CgoFiles, parses -// the output and returns the resulting ASTs. -// -func processCgoFiles(bp *build.Package, fset *token.FileSet, DisplayPath func(path string) string, mode parser.Mode) ([]*ast.File, error) { - tmpdir, err := ioutil.TempDir("", strings.Replace(bp.ImportPath, "/", "_", -1)+"_C") - if err != nil { - return nil, err - } - defer os.RemoveAll(tmpdir) - - pkgdir := bp.Dir - if DisplayPath != nil { - pkgdir = DisplayPath(pkgdir) - } - - cgoFiles, cgoDisplayFiles, err := runCgo(bp, pkgdir, tmpdir) - if err != nil { - return nil, err - } - var files []*ast.File - for i := range cgoFiles { - rd, err := os.Open(cgoFiles[i]) - if err != nil { - return nil, err - } - display := filepath.Join(bp.Dir, cgoDisplayFiles[i]) - f, err := parser.ParseFile(fset, display, rd, mode) - rd.Close() - if err != nil { - return nil, err - } - files = append(files, f) - } - return files, nil -} - -var cgoRe = regexp.MustCompile(`[/\\:]`) - -// runCgo invokes the cgo preprocessor on bp.CgoFiles and returns two -// lists of files: the resulting processed files (in temporary -// directory tmpdir) and the corresponding names of the unprocessed files. -// -// runCgo is adapted from (*builder).cgo in -// $GOROOT/src/cmd/go/build.go, but these features are unsupported: -// Objective C, CGOPKGPATH, CGO_FLAGS. -// -func runCgo(bp *build.Package, pkgdir, tmpdir string) (files, displayFiles []string, err error) { - cgoCPPFLAGS, _, _, _ := cflags(bp, true) - _, cgoexeCFLAGS, _, _ := cflags(bp, false) - - if len(bp.CgoPkgConfig) > 0 { - pcCFLAGS, err := pkgConfigFlags(bp) - if err != nil { - return nil, nil, err - } - cgoCPPFLAGS = append(cgoCPPFLAGS, pcCFLAGS...) - } - - // Allows including _cgo_export.h from .[ch] files in the package. - cgoCPPFLAGS = append(cgoCPPFLAGS, "-I", tmpdir) - - // _cgo_gotypes.go (displayed "C") contains the type definitions. - files = append(files, filepath.Join(tmpdir, "_cgo_gotypes.go")) - displayFiles = append(displayFiles, "C") - for _, fn := range bp.CgoFiles { - // "foo.cgo1.go" (displayed "foo.go") is the processed Go source. - f := cgoRe.ReplaceAllString(fn[:len(fn)-len("go")], "_") - files = append(files, filepath.Join(tmpdir, f+"cgo1.go")) - displayFiles = append(displayFiles, fn) - } - - var cgoflags []string - if bp.Goroot && bp.ImportPath == "runtime/cgo" { - cgoflags = append(cgoflags, "-import_runtime_cgo=false") - } - if bp.Goroot && bp.ImportPath == "runtime/race" || bp.ImportPath == "runtime/cgo" { - cgoflags = append(cgoflags, "-import_syscall=false") - } - - args := stringList( - "go", "tool", "cgo", "-objdir", tmpdir, cgoflags, "--", - cgoCPPFLAGS, cgoexeCFLAGS, bp.CgoFiles, - ) - if false { - log.Printf("Running cgo for package %q: %s (dir=%s)", bp.ImportPath, args, pkgdir) - } - cmd := exec.Command(args[0], args[1:]...) - cmd.Dir = pkgdir - cmd.Stdout = os.Stderr - cmd.Stderr = os.Stderr - if err := cmd.Run(); err != nil { - return nil, nil, fmt.Errorf("cgo failed: %s: %s", args, err) - } - - return files, displayFiles, nil -} - -// -- unmodified from 'go build' --------------------------------------- - -// Return the flags to use when invoking the C or C++ compilers, or cgo. -func cflags(p *build.Package, def bool) (cppflags, cflags, cxxflags, ldflags []string) { - var defaults string - if def { - defaults = "-g -O2" - } - - cppflags = stringList(envList("CGO_CPPFLAGS", ""), p.CgoCPPFLAGS) - cflags = stringList(envList("CGO_CFLAGS", defaults), p.CgoCFLAGS) - cxxflags = stringList(envList("CGO_CXXFLAGS", defaults), p.CgoCXXFLAGS) - ldflags = stringList(envList("CGO_LDFLAGS", defaults), p.CgoLDFLAGS) - return -} - -// envList returns the value of the given environment variable broken -// into fields, using the default value when the variable is empty. -func envList(key, def string) []string { - v := os.Getenv(key) - if v == "" { - v = def - } - return strings.Fields(v) -} - -// stringList's arguments should be a sequence of string or []string values. -// stringList flattens them into a single []string. -func stringList(args ...interface{}) []string { - var x []string - for _, arg := range args { - switch arg := arg.(type) { - case []string: - x = append(x, arg...) - case string: - x = append(x, arg) - default: - panic("stringList: invalid argument") - } - } - return x -} diff --git a/vendor/golang.org/x/tools/go/loader/cgo_pkgconfig.go b/vendor/golang.org/x/tools/go/loader/cgo_pkgconfig.go deleted file mode 100644 index de57422..0000000 --- a/vendor/golang.org/x/tools/go/loader/cgo_pkgconfig.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2013 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 loader - -import ( - "errors" - "fmt" - "go/build" - "os/exec" - "strings" -) - -// pkgConfig runs pkg-config with the specified arguments and returns the flags it prints. -func pkgConfig(mode string, pkgs []string) (flags []string, err error) { - cmd := exec.Command("pkg-config", append([]string{mode}, pkgs...)...) - out, err := cmd.CombinedOutput() - if err != nil { - s := fmt.Sprintf("%s failed: %v", strings.Join(cmd.Args, " "), err) - if len(out) > 0 { - s = fmt.Sprintf("%s: %s", s, out) - } - return nil, errors.New(s) - } - if len(out) > 0 { - flags = strings.Fields(string(out)) - } - return -} - -// pkgConfigFlags calls pkg-config if needed and returns the cflags -// needed to build the package. -func pkgConfigFlags(p *build.Package) (cflags []string, err error) { - if len(p.CgoPkgConfig) == 0 { - return nil, nil - } - return pkgConfig("--cflags", p.CgoPkgConfig) -} diff --git a/vendor/golang.org/x/tools/go/loader/doc.go b/vendor/golang.org/x/tools/go/loader/doc.go deleted file mode 100644 index 9b51c9e..0000000 --- a/vendor/golang.org/x/tools/go/loader/doc.go +++ /dev/null @@ -1,205 +0,0 @@ -// Copyright 2015 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 loader loads a complete Go program from source code, parsing -// and type-checking the initial packages plus their transitive closure -// of dependencies. The ASTs and the derived facts are retained for -// later use. -// -// THIS INTERFACE IS EXPERIMENTAL AND IS LIKELY TO CHANGE. -// -// The package defines two primary types: Config, which specifies a -// set of initial packages to load and various other options; and -// Program, which is the result of successfully loading the packages -// specified by a configuration. -// -// The configuration can be set directly, but *Config provides various -// convenience methods to simplify the common cases, each of which can -// be called any number of times. Finally, these are followed by a -// call to Load() to actually load and type-check the program. -// -// var conf loader.Config -// -// // Use the command-line arguments to specify -// // a set of initial packages to load from source. -// // See FromArgsUsage for help. -// rest, err := conf.FromArgs(os.Args[1:], wantTests) -// -// // Parse the specified files and create an ad hoc package with path "foo". -// // All files must have the same 'package' declaration. -// conf.CreateFromFilenames("foo", "foo.go", "bar.go") -// -// // Create an ad hoc package with path "foo" from -// // the specified already-parsed files. -// // All ASTs must have the same 'package' declaration. -// conf.CreateFromFiles("foo", parsedFiles) -// -// // Add "runtime" to the set of packages to be loaded. -// conf.Import("runtime") -// -// // Adds "fmt" and "fmt_test" to the set of packages -// // to be loaded. "fmt" will include *_test.go files. -// conf.ImportWithTests("fmt") -// -// // Finally, load all the packages specified by the configuration. -// prog, err := conf.Load() -// -// See examples_test.go for examples of API usage. -// -// -// CONCEPTS AND TERMINOLOGY -// -// The WORKSPACE is the set of packages accessible to the loader. The -// workspace is defined by Config.Build, a *build.Context. The -// default context treats subdirectories of $GOROOT and $GOPATH as -// packages, but this behavior may be overridden. -// -// An AD HOC package is one specified as a set of source files on the -// command line. In the simplest case, it may consist of a single file -// such as $GOROOT/src/net/http/triv.go. -// -// EXTERNAL TEST packages are those comprised of a set of *_test.go -// files all with the same 'package foo_test' declaration, all in the -// same directory. (go/build.Package calls these files XTestFiles.) -// -// An IMPORTABLE package is one that can be referred to by some import -// spec. Every importable package is uniquely identified by its -// PACKAGE PATH or just PATH, a string such as "fmt", "encoding/json", -// or "cmd/vendor/golang.org/x/arch/x86/x86asm". A package path -// typically denotes a subdirectory of the workspace. -// -// An import declaration uses an IMPORT PATH to refer to a package. -// Most import declarations use the package path as the import path. -// -// Due to VENDORING (https://golang.org/s/go15vendor), the -// interpretation of an import path may depend on the directory in which -// it appears. To resolve an import path to a package path, go/build -// must search the enclosing directories for a subdirectory named -// "vendor". -// -// ad hoc packages and external test packages are NON-IMPORTABLE. The -// path of an ad hoc package is inferred from the package -// declarations of its files and is therefore not a unique package key. -// For example, Config.CreatePkgs may specify two initial ad hoc -// packages, both with path "main". -// -// An AUGMENTED package is an importable package P plus all the -// *_test.go files with same 'package foo' declaration as P. -// (go/build.Package calls these files TestFiles.) -// -// The INITIAL packages are those specified in the configuration. A -// DEPENDENCY is a package loaded to satisfy an import in an initial -// package or another dependency. -// -package loader - -// IMPLEMENTATION NOTES -// -// 'go test', in-package test files, and import cycles -// --------------------------------------------------- -// -// An external test package may depend upon members of the augmented -// package that are not in the unaugmented package, such as functions -// that expose internals. (See bufio/export_test.go for an example.) -// So, the loader must ensure that for each external test package -// it loads, it also augments the corresponding non-test package. -// -// The import graph over n unaugmented packages must be acyclic; the -// import graph over n-1 unaugmented packages plus one augmented -// package must also be acyclic. ('go test' relies on this.) But the -// import graph over n augmented packages may contain cycles. -// -// First, all the (unaugmented) non-test packages and their -// dependencies are imported in the usual way; the loader reports an -// error if it detects an import cycle. -// -// Then, each package P for which testing is desired is augmented by -// the list P' of its in-package test files, by calling -// (*types.Checker).Files. This arrangement ensures that P' may -// reference definitions within P, but P may not reference definitions -// within P'. Furthermore, P' may import any other package, including -// ones that depend upon P, without an import cycle error. -// -// Consider two packages A and B, both of which have lists of -// in-package test files we'll call A' and B', and which have the -// following import graph edges: -// B imports A -// B' imports A -// A' imports B -// This last edge would be expected to create an error were it not -// for the special type-checking discipline above. -// Cycles of size greater than two are possible. For example: -// compress/bzip2/bzip2_test.go (package bzip2) imports "io/ioutil" -// io/ioutil/tempfile_test.go (package ioutil) imports "regexp" -// regexp/exec_test.go (package regexp) imports "compress/bzip2" -// -// -// Concurrency -// ----------- -// -// Let us define the import dependency graph as follows. Each node is a -// list of files passed to (Checker).Files at once. Many of these lists -// are the production code of an importable Go package, so those nodes -// are labelled by the package's path. The remaining nodes are -// ad hoc packages and lists of in-package *_test.go files that augment -// an importable package; those nodes have no label. -// -// The edges of the graph represent import statements appearing within a -// file. An edge connects a node (a list of files) to the node it -// imports, which is importable and thus always labelled. -// -// Loading is controlled by this dependency graph. -// -// To reduce I/O latency, we start loading a package's dependencies -// asynchronously as soon as we've parsed its files and enumerated its -// imports (scanImports). This performs a preorder traversal of the -// import dependency graph. -// -// To exploit hardware parallelism, we type-check unrelated packages in -// parallel, where "unrelated" means not ordered by the partial order of -// the import dependency graph. -// -// We use a concurrency-safe non-blocking cache (importer.imported) to -// record the results of type-checking, whether success or failure. An -// entry is created in this cache by startLoad the first time the -// package is imported. The first goroutine to request an entry becomes -// responsible for completing the task and broadcasting completion to -// subsequent requestors, which block until then. -// -// Type checking occurs in (parallel) postorder: we cannot type-check a -// set of files until we have loaded and type-checked all of their -// immediate dependencies (and thus all of their transitive -// dependencies). If the input were guaranteed free of import cycles, -// this would be trivial: we could simply wait for completion of the -// dependencies and then invoke the typechecker. -// -// But as we saw in the 'go test' section above, some cycles in the -// import graph over packages are actually legal, so long as the -// cycle-forming edge originates in the in-package test files that -// augment the package. This explains why the nodes of the import -// dependency graph are not packages, but lists of files: the unlabelled -// nodes avoid the cycles. Consider packages A and B where B imports A -// and A's in-package tests AT import B. The naively constructed import -// graph over packages would contain a cycle (A+AT) --> B --> (A+AT) but -// the graph over lists of files is AT --> B --> A, where AT is an -// unlabelled node. -// -// Awaiting completion of the dependencies in a cyclic graph would -// deadlock, so we must materialize the import dependency graph (as -// importer.graph) and check whether each import edge forms a cycle. If -// x imports y, and the graph already contains a path from y to x, then -// there is an import cycle, in which case the processing of x must not -// wait for the completion of processing of y. -// -// When the type-checker makes a callback (doImport) to the loader for a -// given import edge, there are two possible cases. In the normal case, -// the dependency has already been completely type-checked; doImport -// does a cache lookup and returns it. In the cyclic case, the entry in -// the cache is still necessarily incomplete, indicating a cycle. We -// perform the cycle check again to obtain the error message, and return -// the error. -// -// The result of using concurrency is about a 2.5x speedup for stdlib_test. - -// TODO(adonovan): overhaul the package documentation. diff --git a/vendor/golang.org/x/tools/go/loader/example_test.go b/vendor/golang.org/x/tools/go/loader/example_test.go deleted file mode 100644 index 88adde3..0000000 --- a/vendor/golang.org/x/tools/go/loader/example_test.go +++ /dev/null @@ -1,179 +0,0 @@ -// Copyright 2015 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. - -// +build go1.8,!go1.9 // TODO(adonovan) determine which versions we need to test here -// +build !windows - -package loader_test - -import ( - "fmt" - "go/token" - "log" - "path/filepath" - "runtime" - "sort" - "strings" - - "golang.org/x/tools/go/loader" -) - -func printProgram(prog *loader.Program) { - // Created packages are the initial packages specified by a call - // to CreateFromFilenames or CreateFromFiles. - var names []string - for _, info := range prog.Created { - names = append(names, info.Pkg.Path()) - } - fmt.Printf("created: %s\n", names) - - // Imported packages are the initial packages specified by a - // call to Import or ImportWithTests. - names = nil - for _, info := range prog.Imported { - if strings.Contains(info.Pkg.Path(), "internal") { - continue // skip, to reduce fragility - } - names = append(names, info.Pkg.Path()) - } - sort.Strings(names) - fmt.Printf("imported: %s\n", names) - - // InitialPackages contains the union of created and imported. - names = nil - for _, info := range prog.InitialPackages() { - names = append(names, info.Pkg.Path()) - } - sort.Strings(names) - fmt.Printf("initial: %s\n", names) - - // AllPackages contains all initial packages and their dependencies. - names = nil - for pkg := range prog.AllPackages { - names = append(names, pkg.Path()) - } - sort.Strings(names) - fmt.Printf("all: %s\n", names) -} - -func printFilenames(fset *token.FileSet, info *loader.PackageInfo) { - var names []string - for _, f := range info.Files { - names = append(names, filepath.Base(fset.File(f.Pos()).Name())) - } - fmt.Printf("%s.Files: %s\n", info.Pkg.Path(), names) -} - -// This example loads a set of packages and all of their dependencies -// from a typical command-line. FromArgs parses a command line and -// makes calls to the other methods of Config shown in the examples that -// follow. -func ExampleConfig_FromArgs() { - args := []string{"mytool", "unicode/utf8", "errors", "runtime", "--", "foo", "bar"} - const wantTests = false - - var conf loader.Config - rest, err := conf.FromArgs(args[1:], wantTests) - prog, err := conf.Load() - if err != nil { - log.Fatal(err) - } - - fmt.Printf("rest: %s\n", rest) - printProgram(prog) - // Output: - // rest: [foo bar] - // created: [] - // imported: [errors runtime unicode/utf8] - // initial: [errors runtime unicode/utf8] - // all: [errors runtime runtime/internal/atomic runtime/internal/sys unicode/utf8 unsafe] -} - -// This example creates and type-checks a single package (without tests) -// from a list of filenames, and loads all of its dependencies. -// (The input files are actually only a small part of the math/cmplx package.) -func ExampleConfig_CreateFromFilenames() { - var conf loader.Config - conf.CreateFromFilenames("math/cmplx", - filepath.Join(runtime.GOROOT(), "src/math/cmplx/abs.go"), - filepath.Join(runtime.GOROOT(), "src/math/cmplx/sin.go")) - prog, err := conf.Load() - if err != nil { - log.Fatal(err) - } - - printProgram(prog) - // Output: - // created: [math/cmplx] - // imported: [] - // initial: [math/cmplx] - // all: [math math/cmplx unsafe] -} - -// In the examples below, for stability, the chosen packages are -// relatively small, platform-independent, and low-level (and thus -// infrequently changing). -// The strconv package has internal and external tests. - -const hello = `package main - -import "fmt" - -func main() { - fmt.Println("Hello, world.") -} -` - -// This example creates and type-checks a package from a list of -// already-parsed files, and loads all its dependencies. -func ExampleConfig_CreateFromFiles() { - var conf loader.Config - f, err := conf.ParseFile("hello.go", hello) - if err != nil { - log.Fatal(err) - } - conf.CreateFromFiles("hello", f) - prog, err := conf.Load() - if err != nil { - log.Fatal(err) - } - - printProgram(prog) - printFilenames(prog.Fset, prog.Package("strconv")) - // Output: - // created: [hello] - // imported: [] - // initial: [hello] - // all: [errors fmt hello internal/race io math os reflect runtime runtime/internal/atomic runtime/internal/sys strconv sync sync/atomic syscall time unicode/utf8 unsafe] - // strconv.Files: [atob.go atof.go atoi.go decimal.go doc.go extfloat.go ftoa.go isprint.go itoa.go quote.go] -} - -// This example imports three packages, including the tests for one of -// them, and loads all their dependencies. -func ExampleConfig_Import() { - // ImportWithTest("strconv") causes strconv to include - // internal_test.go, and creates an external test package, - // strconv_test. - // (Compare with the example of CreateFromFiles.) - - var conf loader.Config - conf.Import("unicode/utf8") - conf.Import("errors") - conf.ImportWithTests("strconv") - prog, err := conf.Load() - if err != nil { - log.Fatal(err) - } - - printProgram(prog) - printFilenames(prog.Fset, prog.Package("strconv")) - printFilenames(prog.Fset, prog.Package("strconv_test")) - // Output: - // created: [strconv_test] - // imported: [errors strconv unicode/utf8] - // initial: [errors strconv strconv_test unicode/utf8] - // all: [bufio bytes errors flag fmt internal/race io log math math/rand os reflect runtime runtime/debug runtime/internal/atomic runtime/internal/sys runtime/trace sort strconv strconv_test strings sync sync/atomic syscall testing time unicode unicode/utf8 unsafe] - // strconv.Files: [atob.go atof.go atoi.go decimal.go doc.go extfloat.go ftoa.go isprint.go itoa.go quote.go internal_test.go] - // strconv_test.Files: [atob_test.go atof_test.go atoi_test.go decimal_test.go example_test.go fp_test.go ftoa_test.go itoa_test.go quote_test.go strconv_test.go] -} diff --git a/vendor/golang.org/x/tools/go/loader/loader.go b/vendor/golang.org/x/tools/go/loader/loader.go deleted file mode 100644 index de756f7..0000000 --- a/vendor/golang.org/x/tools/go/loader/loader.go +++ /dev/null @@ -1,1077 +0,0 @@ -// Copyright 2013 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 loader - -// See doc.go for package documentation and implementation notes. - -import ( - "errors" - "fmt" - "go/ast" - "go/build" - "go/parser" - "go/token" - "go/types" - "os" - "path/filepath" - "sort" - "strings" - "sync" - "time" - - "golang.org/x/tools/go/ast/astutil" -) - -var ignoreVendor build.ImportMode - -const trace = false // show timing info for type-checking - -// Config specifies the configuration for loading a whole program from -// Go source code. -// The zero value for Config is a ready-to-use default configuration. -type Config struct { - // Fset is the file set for the parser to use when loading the - // program. If nil, it may be lazily initialized by any - // method of Config. - Fset *token.FileSet - - // ParserMode specifies the mode to be used by the parser when - // loading source packages. - ParserMode parser.Mode - - // TypeChecker contains options relating to the type checker. - // - // The supplied IgnoreFuncBodies is not used; the effective - // value comes from the TypeCheckFuncBodies func below. - // The supplied Import function is not used either. - TypeChecker types.Config - - // TypeCheckFuncBodies is a predicate over package paths. - // A package for which the predicate is false will - // have its package-level declarations type checked, but not - // its function bodies; this can be used to quickly load - // dependencies from source. If nil, all func bodies are type - // checked. - TypeCheckFuncBodies func(path string) bool - - // If Build is non-nil, it is used to locate source packages. - // Otherwise &build.Default is used. - // - // By default, cgo is invoked to preprocess Go files that - // import the fake package "C". This behaviour can be - // disabled by setting CGO_ENABLED=0 in the environment prior - // to startup, or by setting Build.CgoEnabled=false. - Build *build.Context - - // The current directory, used for resolving relative package - // references such as "./go/loader". If empty, os.Getwd will be - // used instead. - Cwd string - - // If DisplayPath is non-nil, it is used to transform each - // file name obtained from Build.Import(). This can be used - // to prevent a virtualized build.Config's file names from - // leaking into the user interface. - DisplayPath func(path string) string - - // If AllowErrors is true, Load will return a Program even - // if some of the its packages contained I/O, parser or type - // errors; such errors are accessible via PackageInfo.Errors. If - // false, Load will fail if any package had an error. - AllowErrors bool - - // CreatePkgs specifies a list of non-importable initial - // packages to create. The resulting packages will appear in - // the corresponding elements of the Program.Created slice. - CreatePkgs []PkgSpec - - // ImportPkgs specifies a set of initial packages to load. - // The map keys are package paths. - // - // The map value indicates whether to load tests. If true, Load - // will add and type-check two lists of files to the package: - // non-test files followed by in-package *_test.go files. In - // addition, it will append the external test package (if any) - // to Program.Created. - ImportPkgs map[string]bool - - // FindPackage is called during Load to create the build.Package - // for a given import path from a given directory. - // If FindPackage is nil, (*build.Context).Import is used. - // A client may use this hook to adapt to a proprietary build - // system that does not follow the "go build" layout - // conventions, for example. - // - // It must be safe to call concurrently from multiple goroutines. - FindPackage func(ctxt *build.Context, importPath, fromDir string, mode build.ImportMode) (*build.Package, error) - - // AfterTypeCheck is called immediately after a list of files - // has been type-checked and appended to info.Files. - // - // This optional hook function is the earliest opportunity for - // the client to observe the output of the type checker, - // which may be useful to reduce analysis latency when loading - // a large program. - // - // The function is permitted to modify info.Info, for instance - // to clear data structures that are no longer needed, which can - // dramatically reduce peak memory consumption. - // - // The function may be called twice for the same PackageInfo: - // once for the files of the package and again for the - // in-package test files. - // - // It must be safe to call concurrently from multiple goroutines. - AfterTypeCheck func(info *PackageInfo, files []*ast.File) -} - -// A PkgSpec specifies a non-importable package to be created by Load. -// Files are processed first, but typically only one of Files and -// Filenames is provided. The path needn't be globally unique. -// -// For vendoring purposes, the package's directory is the one that -// contains the first file. -type PkgSpec struct { - Path string // package path ("" => use package declaration) - Files []*ast.File // ASTs of already-parsed files - Filenames []string // names of files to be parsed -} - -// A Program is a Go program loaded from source as specified by a Config. -type Program struct { - Fset *token.FileSet // the file set for this program - - // Created[i] contains the initial package whose ASTs or - // filenames were supplied by Config.CreatePkgs[i], followed by - // the external test package, if any, of each package in - // Config.ImportPkgs ordered by ImportPath. - // - // NOTE: these files must not import "C". Cgo preprocessing is - // only performed on imported packages, not ad hoc packages. - // - // TODO(adonovan): we need to copy and adapt the logic of - // goFilesPackage (from $GOROOT/src/cmd/go/build.go) and make - // Config.Import and Config.Create methods return the same kind - // of entity, essentially a build.Package. - // Perhaps we can even reuse that type directly. - Created []*PackageInfo - - // Imported contains the initially imported packages, - // as specified by Config.ImportPkgs. - Imported map[string]*PackageInfo - - // AllPackages contains the PackageInfo of every package - // encountered by Load: all initial packages and all - // dependencies, including incomplete ones. - AllPackages map[*types.Package]*PackageInfo - - // importMap is the canonical mapping of package paths to - // packages. It contains all Imported initial packages, but not - // Created ones, and all imported dependencies. - importMap map[string]*types.Package -} - -// PackageInfo holds the ASTs and facts derived by the type-checker -// for a single package. -// -// Not mutated once exposed via the API. -// -type PackageInfo struct { - Pkg *types.Package - Importable bool // true if 'import "Pkg.Path()"' would resolve to this - TransitivelyErrorFree bool // true if Pkg and all its dependencies are free of errors - Files []*ast.File // syntax trees for the package's files - Errors []error // non-nil if the package had errors - types.Info // type-checker deductions. - dir string // package directory - - checker *types.Checker // transient type-checker state - errorFunc func(error) -} - -func (info *PackageInfo) String() string { return info.Pkg.Path() } - -func (info *PackageInfo) appendError(err error) { - if info.errorFunc != nil { - info.errorFunc(err) - } else { - fmt.Fprintln(os.Stderr, err) - } - info.Errors = append(info.Errors, err) -} - -func (conf *Config) fset() *token.FileSet { - if conf.Fset == nil { - conf.Fset = token.NewFileSet() - } - return conf.Fset -} - -// ParseFile is a convenience function (intended for testing) that invokes -// the parser using the Config's FileSet, which is initialized if nil. -// -// src specifies the parser input as a string, []byte, or io.Reader, and -// filename is its apparent name. If src is nil, the contents of -// filename are read from the file system. -// -func (conf *Config) ParseFile(filename string, src interface{}) (*ast.File, error) { - // TODO(adonovan): use conf.build() etc like parseFiles does. - return parser.ParseFile(conf.fset(), filename, src, conf.ParserMode) -} - -// FromArgsUsage is a partial usage message that applications calling -// FromArgs may wish to include in their -help output. -const FromArgsUsage = ` - is a list of arguments denoting a set of initial packages. -It may take one of two forms: - -1. A list of *.go source files. - - All of the specified files are loaded, parsed and type-checked - as a single package. All the files must belong to the same directory. - -2. A list of import paths, each denoting a package. - - The package's directory is found relative to the $GOROOT and - $GOPATH using similar logic to 'go build', and the *.go files in - that directory are loaded, parsed and type-checked as a single - package. - - In addition, all *_test.go files in the directory are then loaded - and parsed. Those files whose package declaration equals that of - the non-*_test.go files are included in the primary package. Test - files whose package declaration ends with "_test" are type-checked - as another package, the 'external' test package, so that a single - import path may denote two packages. (Whether this behaviour is - enabled is tool-specific, and may depend on additional flags.) - -A '--' argument terminates the list of packages. -` - -// FromArgs interprets args as a set of initial packages to load from -// source and updates the configuration. It returns the list of -// unconsumed arguments. -// -// It is intended for use in command-line interfaces that require a -// set of initial packages to be specified; see FromArgsUsage message -// for details. -// -// Only superficial errors are reported at this stage; errors dependent -// on I/O are detected during Load. -// -func (conf *Config) FromArgs(args []string, xtest bool) ([]string, error) { - var rest []string - for i, arg := range args { - if arg == "--" { - rest = args[i+1:] - args = args[:i] - break // consume "--" and return the remaining args - } - } - - if len(args) > 0 && strings.HasSuffix(args[0], ".go") { - // Assume args is a list of a *.go files - // denoting a single ad hoc package. - for _, arg := range args { - if !strings.HasSuffix(arg, ".go") { - return nil, fmt.Errorf("named files must be .go files: %s", arg) - } - } - conf.CreateFromFilenames("", args...) - } else { - // Assume args are directories each denoting a - // package and (perhaps) an external test, iff xtest. - for _, arg := range args { - if xtest { - conf.ImportWithTests(arg) - } else { - conf.Import(arg) - } - } - } - - return rest, nil -} - -// CreateFromFilenames is a convenience function that adds -// a conf.CreatePkgs entry to create a package of the specified *.go -// files. -// -func (conf *Config) CreateFromFilenames(path string, filenames ...string) { - conf.CreatePkgs = append(conf.CreatePkgs, PkgSpec{Path: path, Filenames: filenames}) -} - -// CreateFromFiles is a convenience function that adds a conf.CreatePkgs -// entry to create package of the specified path and parsed files. -// -func (conf *Config) CreateFromFiles(path string, files ...*ast.File) { - conf.CreatePkgs = append(conf.CreatePkgs, PkgSpec{Path: path, Files: files}) -} - -// ImportWithTests is a convenience function that adds path to -// ImportPkgs, the set of initial source packages located relative to -// $GOPATH. The package will be augmented by any *_test.go files in -// its directory that contain a "package x" (not "package x_test") -// declaration. -// -// In addition, if any *_test.go files contain a "package x_test" -// declaration, an additional package comprising just those files will -// be added to CreatePkgs. -// -func (conf *Config) ImportWithTests(path string) { conf.addImport(path, true) } - -// Import is a convenience function that adds path to ImportPkgs, the -// set of initial packages that will be imported from source. -// -func (conf *Config) Import(path string) { conf.addImport(path, false) } - -func (conf *Config) addImport(path string, tests bool) { - if path == "C" { - return // ignore; not a real package - } - if conf.ImportPkgs == nil { - conf.ImportPkgs = make(map[string]bool) - } - conf.ImportPkgs[path] = conf.ImportPkgs[path] || tests -} - -// PathEnclosingInterval returns the PackageInfo and ast.Node that -// contain source interval [start, end), and all the node's ancestors -// up to the AST root. It searches all ast.Files of all packages in prog. -// exact is defined as for astutil.PathEnclosingInterval. -// -// The zero value is returned if not found. -// -func (prog *Program) PathEnclosingInterval(start, end token.Pos) (pkg *PackageInfo, path []ast.Node, exact bool) { - for _, info := range prog.AllPackages { - for _, f := range info.Files { - if f.Pos() == token.NoPos { - // This can happen if the parser saw - // too many errors and bailed out. - // (Use parser.AllErrors to prevent that.) - continue - } - if !tokenFileContainsPos(prog.Fset.File(f.Pos()), start) { - continue - } - if path, exact := astutil.PathEnclosingInterval(f, start, end); path != nil { - return info, path, exact - } - } - } - return nil, nil, false -} - -// InitialPackages returns a new slice containing the set of initial -// packages (Created + Imported) in unspecified order. -// -func (prog *Program) InitialPackages() []*PackageInfo { - infos := make([]*PackageInfo, 0, len(prog.Created)+len(prog.Imported)) - infos = append(infos, prog.Created...) - for _, info := range prog.Imported { - infos = append(infos, info) - } - return infos -} - -// Package returns the ASTs and results of type checking for the -// specified package. -func (prog *Program) Package(path string) *PackageInfo { - if info, ok := prog.AllPackages[prog.importMap[path]]; ok { - return info - } - for _, info := range prog.Created { - if path == info.Pkg.Path() { - return info - } - } - return nil -} - -// ---------- Implementation ---------- - -// importer holds the working state of the algorithm. -type importer struct { - conf *Config // the client configuration - start time.Time // for logging - - progMu sync.Mutex // guards prog - prog *Program // the resulting program - - // findpkg is a memoization of FindPackage. - findpkgMu sync.Mutex // guards findpkg - findpkg map[findpkgKey]*findpkgValue - - importedMu sync.Mutex // guards imported - imported map[string]*importInfo // all imported packages (incl. failures) by import path - - // import dependency graph: graph[x][y] => x imports y - // - // Since non-importable packages cannot be cyclic, we ignore - // their imports, thus we only need the subgraph over importable - // packages. Nodes are identified by their import paths. - graphMu sync.Mutex - graph map[string]map[string]bool -} - -type findpkgKey struct { - importPath string - fromDir string - mode build.ImportMode -} - -type findpkgValue struct { - ready chan struct{} // closed to broadcast readiness - bp *build.Package - err error -} - -// importInfo tracks the success or failure of a single import. -// -// Upon completion, exactly one of info and err is non-nil: -// info on successful creation of a package, err otherwise. -// A successful package may still contain type errors. -// -type importInfo struct { - path string // import path - info *PackageInfo // results of typechecking (including errors) - complete chan struct{} // closed to broadcast that info is set. -} - -// awaitCompletion blocks until ii is complete, -// i.e. the info field is safe to inspect. -func (ii *importInfo) awaitCompletion() { - <-ii.complete // wait for close -} - -// Complete marks ii as complete. -// Its info and err fields will not be subsequently updated. -func (ii *importInfo) Complete(info *PackageInfo) { - if info == nil { - panic("info == nil") - } - ii.info = info - close(ii.complete) -} - -type importError struct { - path string // import path - err error // reason for failure to create a package -} - -// Load creates the initial packages specified by conf.{Create,Import}Pkgs, -// loading their dependencies packages as needed. -// -// On success, Load returns a Program containing a PackageInfo for -// each package. On failure, it returns an error. -// -// If AllowErrors is true, Load will return a Program even if some -// packages contained I/O, parser or type errors, or if dependencies -// were missing. (Such errors are accessible via PackageInfo.Errors. If -// false, Load will fail if any package had an error. -// -// It is an error if no packages were loaded. -// -func (conf *Config) Load() (*Program, error) { - // Create a simple default error handler for parse/type errors. - if conf.TypeChecker.Error == nil { - conf.TypeChecker.Error = func(e error) { fmt.Fprintln(os.Stderr, e) } - } - - // Set default working directory for relative package references. - if conf.Cwd == "" { - var err error - conf.Cwd, err = os.Getwd() - if err != nil { - return nil, err - } - } - - // Install default FindPackage hook using go/build logic. - if conf.FindPackage == nil { - conf.FindPackage = (*build.Context).Import - } - - prog := &Program{ - Fset: conf.fset(), - Imported: make(map[string]*PackageInfo), - importMap: make(map[string]*types.Package), - AllPackages: make(map[*types.Package]*PackageInfo), - } - - imp := importer{ - conf: conf, - prog: prog, - findpkg: make(map[findpkgKey]*findpkgValue), - imported: make(map[string]*importInfo), - start: time.Now(), - graph: make(map[string]map[string]bool), - } - - // -- loading proper (concurrent phase) -------------------------------- - - var errpkgs []string // packages that contained errors - - // Load the initially imported packages and their dependencies, - // in parallel. - // No vendor check on packages imported from the command line. - infos, importErrors := imp.importAll("", conf.Cwd, conf.ImportPkgs, ignoreVendor) - for _, ie := range importErrors { - conf.TypeChecker.Error(ie.err) // failed to create package - errpkgs = append(errpkgs, ie.path) - } - for _, info := range infos { - prog.Imported[info.Pkg.Path()] = info - } - - // Augment the designated initial packages by their tests. - // Dependencies are loaded in parallel. - var xtestPkgs []*build.Package - for importPath, augment := range conf.ImportPkgs { - if !augment { - continue - } - - // No vendor check on packages imported from command line. - bp, err := imp.findPackage(importPath, conf.Cwd, ignoreVendor) - if err != nil { - // Package not found, or can't even parse package declaration. - // Already reported by previous loop; ignore it. - continue - } - - // Needs external test package? - if len(bp.XTestGoFiles) > 0 { - xtestPkgs = append(xtestPkgs, bp) - } - - // Consult the cache using the canonical package path. - path := bp.ImportPath - imp.importedMu.Lock() // (unnecessary, we're sequential here) - ii, ok := imp.imported[path] - // Paranoid checks added due to issue #11012. - if !ok { - // Unreachable. - // The previous loop called importAll and thus - // startLoad for each path in ImportPkgs, which - // populates imp.imported[path] with a non-zero value. - panic(fmt.Sprintf("imported[%q] not found", path)) - } - if ii == nil { - // Unreachable. - // The ii values in this loop are the same as in - // the previous loop, which enforced the invariant - // that at least one of ii.err and ii.info is non-nil. - panic(fmt.Sprintf("imported[%q] == nil", path)) - } - if ii.info == nil { - // Unreachable. - // awaitCompletion has the postcondition - // ii.info != nil. - panic(fmt.Sprintf("imported[%q].info = nil", path)) - } - info := ii.info - imp.importedMu.Unlock() - - // Parse the in-package test files. - files, errs := imp.conf.parsePackageFiles(bp, 't') - for _, err := range errs { - info.appendError(err) - } - - // The test files augmenting package P cannot be imported, - // but may import packages that import P, - // so we must disable the cycle check. - imp.addFiles(info, files, false) - } - - createPkg := func(path, dir string, files []*ast.File, errs []error) { - info := imp.newPackageInfo(path, dir) - for _, err := range errs { - info.appendError(err) - } - - // Ad hoc packages are non-importable, - // so no cycle check is needed. - // addFiles loads dependencies in parallel. - imp.addFiles(info, files, false) - prog.Created = append(prog.Created, info) - } - - // Create packages specified by conf.CreatePkgs. - for _, cp := range conf.CreatePkgs { - files, errs := parseFiles(conf.fset(), conf.build(), nil, conf.Cwd, cp.Filenames, conf.ParserMode) - files = append(files, cp.Files...) - - path := cp.Path - if path == "" { - if len(files) > 0 { - path = files[0].Name.Name - } else { - path = "(unnamed)" - } - } - - dir := conf.Cwd - if len(files) > 0 && files[0].Pos().IsValid() { - dir = filepath.Dir(conf.fset().File(files[0].Pos()).Name()) - } - createPkg(path, dir, files, errs) - } - - // Create external test packages. - sort.Sort(byImportPath(xtestPkgs)) - for _, bp := range xtestPkgs { - files, errs := imp.conf.parsePackageFiles(bp, 'x') - createPkg(bp.ImportPath+"_test", bp.Dir, files, errs) - } - - // -- finishing up (sequential) ---------------------------------------- - - if len(prog.Imported)+len(prog.Created) == 0 { - return nil, errors.New("no initial packages were loaded") - } - - // Create infos for indirectly imported packages. - // e.g. incomplete packages without syntax, loaded from export data. - for _, obj := range prog.importMap { - info := prog.AllPackages[obj] - if info == nil { - prog.AllPackages[obj] = &PackageInfo{Pkg: obj, Importable: true} - } else { - // finished - info.checker = nil - info.errorFunc = nil - } - } - - if !conf.AllowErrors { - // Report errors in indirectly imported packages. - for _, info := range prog.AllPackages { - if len(info.Errors) > 0 { - errpkgs = append(errpkgs, info.Pkg.Path()) - } - } - if errpkgs != nil { - var more string - if len(errpkgs) > 3 { - more = fmt.Sprintf(" and %d more", len(errpkgs)-3) - errpkgs = errpkgs[:3] - } - return nil, fmt.Errorf("couldn't load packages due to errors: %s%s", - strings.Join(errpkgs, ", "), more) - } - } - - markErrorFreePackages(prog.AllPackages) - - return prog, nil -} - -type byImportPath []*build.Package - -func (b byImportPath) Len() int { return len(b) } -func (b byImportPath) Less(i, j int) bool { return b[i].ImportPath < b[j].ImportPath } -func (b byImportPath) Swap(i, j int) { b[i], b[j] = b[j], b[i] } - -// markErrorFreePackages sets the TransitivelyErrorFree flag on all -// applicable packages. -func markErrorFreePackages(allPackages map[*types.Package]*PackageInfo) { - // Build the transpose of the import graph. - importedBy := make(map[*types.Package]map[*types.Package]bool) - for P := range allPackages { - for _, Q := range P.Imports() { - clients, ok := importedBy[Q] - if !ok { - clients = make(map[*types.Package]bool) - importedBy[Q] = clients - } - clients[P] = true - } - } - - // Find all packages reachable from some error package. - reachable := make(map[*types.Package]bool) - var visit func(*types.Package) - visit = func(p *types.Package) { - if !reachable[p] { - reachable[p] = true - for q := range importedBy[p] { - visit(q) - } - } - } - for _, info := range allPackages { - if len(info.Errors) > 0 { - visit(info.Pkg) - } - } - - // Mark the others as "transitively error-free". - for _, info := range allPackages { - if !reachable[info.Pkg] { - info.TransitivelyErrorFree = true - } - } -} - -// build returns the effective build context. -func (conf *Config) build() *build.Context { - if conf.Build != nil { - return conf.Build - } - return &build.Default -} - -// parsePackageFiles enumerates the files belonging to package path, -// then loads, parses and returns them, plus a list of I/O or parse -// errors that were encountered. -// -// 'which' indicates which files to include: -// 'g': include non-test *.go source files (GoFiles + processed CgoFiles) -// 't': include in-package *_test.go source files (TestGoFiles) -// 'x': include external *_test.go source files. (XTestGoFiles) -// -func (conf *Config) parsePackageFiles(bp *build.Package, which rune) ([]*ast.File, []error) { - if bp.ImportPath == "unsafe" { - return nil, nil - } - var filenames []string - switch which { - case 'g': - filenames = bp.GoFiles - case 't': - filenames = bp.TestGoFiles - case 'x': - filenames = bp.XTestGoFiles - default: - panic(which) - } - - files, errs := parseFiles(conf.fset(), conf.build(), conf.DisplayPath, bp.Dir, filenames, conf.ParserMode) - - // Preprocess CgoFiles and parse the outputs (sequentially). - if which == 'g' && bp.CgoFiles != nil { - cgofiles, err := processCgoFiles(bp, conf.fset(), conf.DisplayPath, conf.ParserMode) - if err != nil { - errs = append(errs, err) - } else { - files = append(files, cgofiles...) - } - } - - return files, errs -} - -// doImport imports the package denoted by path. -// It implements the types.Importer signature. -// -// It returns an error if a package could not be created -// (e.g. go/build or parse error), but type errors are reported via -// the types.Config.Error callback (the first of which is also saved -// in the package's PackageInfo). -// -// Idempotent. -// -func (imp *importer) doImport(from *PackageInfo, to string) (*types.Package, error) { - if to == "C" { - // This should be unreachable, but ad hoc packages are - // not currently subject to cgo preprocessing. - // See https://github.com/golang/go/issues/11627. - return nil, fmt.Errorf(`the loader doesn't cgo-process ad hoc packages like %q; see Go issue 11627`, - from.Pkg.Path()) - } - - bp, err := imp.findPackage(to, from.dir, 0) - if err != nil { - return nil, err - } - - // The standard unsafe package is handled specially, - // and has no PackageInfo. - if bp.ImportPath == "unsafe" { - return types.Unsafe, nil - } - - // Look for the package in the cache using its canonical path. - path := bp.ImportPath - imp.importedMu.Lock() - ii := imp.imported[path] - imp.importedMu.Unlock() - if ii == nil { - panic("internal error: unexpected import: " + path) - } - if ii.info != nil { - return ii.info.Pkg, nil - } - - // Import of incomplete package: this indicates a cycle. - fromPath := from.Pkg.Path() - if cycle := imp.findPath(path, fromPath); cycle != nil { - cycle = append([]string{fromPath}, cycle...) - return nil, fmt.Errorf("import cycle: %s", strings.Join(cycle, " -> ")) - } - - panic("internal error: import of incomplete (yet acyclic) package: " + fromPath) -} - -// findPackage locates the package denoted by the importPath in the -// specified directory. -func (imp *importer) findPackage(importPath, fromDir string, mode build.ImportMode) (*build.Package, error) { - // We use a non-blocking duplicate-suppressing cache (gopl.io ยง9.7) - // to avoid holding the lock around FindPackage. - key := findpkgKey{importPath, fromDir, mode} - imp.findpkgMu.Lock() - v, ok := imp.findpkg[key] - if ok { - // cache hit - imp.findpkgMu.Unlock() - - <-v.ready // wait for entry to become ready - } else { - // Cache miss: this goroutine becomes responsible for - // populating the map entry and broadcasting its readiness. - v = &findpkgValue{ready: make(chan struct{})} - imp.findpkg[key] = v - imp.findpkgMu.Unlock() - - ioLimit <- true - v.bp, v.err = imp.conf.FindPackage(imp.conf.build(), importPath, fromDir, mode) - <-ioLimit - - if _, ok := v.err.(*build.NoGoError); ok { - v.err = nil // empty directory is not an error - } - - close(v.ready) // broadcast ready condition - } - return v.bp, v.err -} - -// importAll loads, parses, and type-checks the specified packages in -// parallel and returns their completed importInfos in unspecified order. -// -// fromPath is the package path of the importing package, if it is -// importable, "" otherwise. It is used for cycle detection. -// -// fromDir is the directory containing the import declaration that -// caused these imports. -// -func (imp *importer) importAll(fromPath, fromDir string, imports map[string]bool, mode build.ImportMode) (infos []*PackageInfo, errors []importError) { - // TODO(adonovan): opt: do the loop in parallel once - // findPackage is non-blocking. - var pending []*importInfo - for importPath := range imports { - bp, err := imp.findPackage(importPath, fromDir, mode) - if err != nil { - errors = append(errors, importError{ - path: importPath, - err: err, - }) - continue - } - pending = append(pending, imp.startLoad(bp)) - } - - if fromPath != "" { - // We're loading a set of imports. - // - // We must record graph edges from the importing package - // to its dependencies, and check for cycles. - imp.graphMu.Lock() - deps, ok := imp.graph[fromPath] - if !ok { - deps = make(map[string]bool) - imp.graph[fromPath] = deps - } - for _, ii := range pending { - deps[ii.path] = true - } - imp.graphMu.Unlock() - } - - for _, ii := range pending { - if fromPath != "" { - if cycle := imp.findPath(ii.path, fromPath); cycle != nil { - // Cycle-forming import: we must not await its - // completion since it would deadlock. - // - // We don't record the error in ii since - // the error is really associated with the - // cycle-forming edge, not the package itself. - // (Also it would complicate the - // invariants of importPath completion.) - if trace { - fmt.Fprintf(os.Stderr, "import cycle: %q\n", cycle) - } - continue - } - } - ii.awaitCompletion() - infos = append(infos, ii.info) - } - - return infos, errors -} - -// findPath returns an arbitrary path from 'from' to 'to' in the import -// graph, or nil if there was none. -func (imp *importer) findPath(from, to string) []string { - imp.graphMu.Lock() - defer imp.graphMu.Unlock() - - seen := make(map[string]bool) - var search func(stack []string, importPath string) []string - search = func(stack []string, importPath string) []string { - if !seen[importPath] { - seen[importPath] = true - stack = append(stack, importPath) - if importPath == to { - return stack - } - for x := range imp.graph[importPath] { - if p := search(stack, x); p != nil { - return p - } - } - } - return nil - } - return search(make([]string, 0, 20), from) -} - -// startLoad initiates the loading, parsing and type-checking of the -// specified package and its dependencies, if it has not already begun. -// -// It returns an importInfo, not necessarily in a completed state. The -// caller must call awaitCompletion() before accessing its info field. -// -// startLoad is concurrency-safe and idempotent. -// -func (imp *importer) startLoad(bp *build.Package) *importInfo { - path := bp.ImportPath - imp.importedMu.Lock() - ii, ok := imp.imported[path] - if !ok { - ii = &importInfo{path: path, complete: make(chan struct{})} - imp.imported[path] = ii - go func() { - info := imp.load(bp) - ii.Complete(info) - }() - } - imp.importedMu.Unlock() - - return ii -} - -// load implements package loading by parsing Go source files -// located by go/build. -func (imp *importer) load(bp *build.Package) *PackageInfo { - info := imp.newPackageInfo(bp.ImportPath, bp.Dir) - info.Importable = true - files, errs := imp.conf.parsePackageFiles(bp, 'g') - for _, err := range errs { - info.appendError(err) - } - - imp.addFiles(info, files, true) - - imp.progMu.Lock() - imp.prog.importMap[bp.ImportPath] = info.Pkg - imp.progMu.Unlock() - - return info -} - -// addFiles adds and type-checks the specified files to info, loading -// their dependencies if needed. The order of files determines the -// package initialization order. It may be called multiple times on the -// same package. Errors are appended to the info.Errors field. -// -// cycleCheck determines whether the imports within files create -// dependency edges that should be checked for potential cycles. -// -func (imp *importer) addFiles(info *PackageInfo, files []*ast.File, cycleCheck bool) { - // Ensure the dependencies are loaded, in parallel. - var fromPath string - if cycleCheck { - fromPath = info.Pkg.Path() - } - // TODO(adonovan): opt: make the caller do scanImports. - // Callers with a build.Package can skip it. - imp.importAll(fromPath, info.dir, scanImports(files), 0) - - if trace { - fmt.Fprintf(os.Stderr, "%s: start %q (%d)\n", - time.Since(imp.start), info.Pkg.Path(), len(files)) - } - - // Don't call checker.Files on Unsafe, even with zero files, - // because it would mutate the package, which is a global. - if info.Pkg == types.Unsafe { - if len(files) > 0 { - panic(`"unsafe" package contains unexpected files`) - } - } else { - // Ignore the returned (first) error since we - // already collect them all in the PackageInfo. - info.checker.Files(files) - info.Files = append(info.Files, files...) - } - - if imp.conf.AfterTypeCheck != nil { - imp.conf.AfterTypeCheck(info, files) - } - - if trace { - fmt.Fprintf(os.Stderr, "%s: stop %q\n", - time.Since(imp.start), info.Pkg.Path()) - } -} - -func (imp *importer) newPackageInfo(path, dir string) *PackageInfo { - var pkg *types.Package - if path == "unsafe" { - pkg = types.Unsafe - } else { - pkg = types.NewPackage(path, "") - } - info := &PackageInfo{ - Pkg: pkg, - Info: types.Info{ - Types: make(map[ast.Expr]types.TypeAndValue), - Defs: make(map[*ast.Ident]types.Object), - Uses: make(map[*ast.Ident]types.Object), - Implicits: make(map[ast.Node]types.Object), - Scopes: make(map[ast.Node]*types.Scope), - Selections: make(map[*ast.SelectorExpr]*types.Selection), - }, - errorFunc: imp.conf.TypeChecker.Error, - dir: dir, - } - - // Copy the types.Config so we can vary it across PackageInfos. - tc := imp.conf.TypeChecker - tc.IgnoreFuncBodies = false - if f := imp.conf.TypeCheckFuncBodies; f != nil { - tc.IgnoreFuncBodies = !f(path) - } - tc.Importer = closure{imp, info} - tc.Error = info.appendError // appendError wraps the user's Error function - - info.checker = types.NewChecker(&tc, imp.conf.fset(), pkg, &info.Info) - imp.progMu.Lock() - imp.prog.AllPackages[pkg] = info - imp.progMu.Unlock() - return info -} - -type closure struct { - imp *importer - info *PackageInfo -} - -func (c closure) Import(to string) (*types.Package, error) { return c.imp.doImport(c.info, to) } diff --git a/vendor/golang.org/x/tools/go/loader/loader_test.go b/vendor/golang.org/x/tools/go/loader/loader_test.go deleted file mode 100644 index 02630eb..0000000 --- a/vendor/golang.org/x/tools/go/loader/loader_test.go +++ /dev/null @@ -1,816 +0,0 @@ -// Copyright 2013 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. - -// No testdata on Android. - -// +build !android - -package loader_test - -import ( - "fmt" - "go/build" - "go/constant" - "go/types" - "path/filepath" - "reflect" - "sort" - "strings" - "sync" - "testing" - - "golang.org/x/tools/go/buildutil" - "golang.org/x/tools/go/loader" -) - -// TestFromArgs checks that conf.FromArgs populates conf correctly. -// It does no I/O. -func TestFromArgs(t *testing.T) { - type result struct { - Err string - Rest []string - ImportPkgs map[string]bool - CreatePkgs []loader.PkgSpec - } - for _, test := range []struct { - args []string - tests bool - want result - }{ - // Mix of existing and non-existent packages. - { - args: []string{"nosuchpkg", "errors"}, - want: result{ - ImportPkgs: map[string]bool{"errors": false, "nosuchpkg": false}, - }, - }, - // Same, with -test flag. - { - args: []string{"nosuchpkg", "errors"}, - tests: true, - want: result{ - ImportPkgs: map[string]bool{"errors": true, "nosuchpkg": true}, - }, - }, - // Surplus arguments. - { - args: []string{"fmt", "errors", "--", "surplus"}, - want: result{ - Rest: []string{"surplus"}, - ImportPkgs: map[string]bool{"errors": false, "fmt": false}, - }, - }, - // Ad hoc package specified as *.go files. - { - args: []string{"foo.go", "bar.go"}, - want: result{CreatePkgs: []loader.PkgSpec{{ - Filenames: []string{"foo.go", "bar.go"}, - }}}, - }, - // Mixture of *.go and import paths. - { - args: []string{"foo.go", "fmt"}, - want: result{ - Err: "named files must be .go files: fmt", - }, - }, - } { - var conf loader.Config - rest, err := conf.FromArgs(test.args, test.tests) - got := result{ - Rest: rest, - ImportPkgs: conf.ImportPkgs, - CreatePkgs: conf.CreatePkgs, - } - if err != nil { - got.Err = err.Error() - } - if !reflect.DeepEqual(got, test.want) { - t.Errorf("FromArgs(%q) = %+v, want %+v", test.args, got, test.want) - } - } -} - -func TestLoad_NoInitialPackages(t *testing.T) { - var conf loader.Config - - const wantErr = "no initial packages were loaded" - - prog, err := conf.Load() - if err == nil { - t.Errorf("Load succeeded unexpectedly, want %q", wantErr) - } else if err.Error() != wantErr { - t.Errorf("Load failed with wrong error %q, want %q", err, wantErr) - } - if prog != nil { - t.Errorf("Load unexpectedly returned a Program") - } -} - -func TestLoad_MissingInitialPackage(t *testing.T) { - var conf loader.Config - conf.Import("nosuchpkg") - conf.Import("errors") - - const wantErr = "couldn't load packages due to errors: nosuchpkg" - - prog, err := conf.Load() - if err == nil { - t.Errorf("Load succeeded unexpectedly, want %q", wantErr) - } else if err.Error() != wantErr { - t.Errorf("Load failed with wrong error %q, want %q", err, wantErr) - } - if prog != nil { - t.Errorf("Load unexpectedly returned a Program") - } -} - -func TestLoad_MissingInitialPackage_AllowErrors(t *testing.T) { - var conf loader.Config - conf.AllowErrors = true - conf.Import("nosuchpkg") - conf.ImportWithTests("errors") - - prog, err := conf.Load() - if err != nil { - t.Errorf("Load failed unexpectedly: %v", err) - } - if prog == nil { - t.Fatalf("Load returned a nil Program") - } - if got, want := created(prog), "errors_test"; got != want { - t.Errorf("Created = %s, want %s", got, want) - } - if got, want := imported(prog), "errors"; got != want { - t.Errorf("Imported = %s, want %s", got, want) - } -} - -func TestCreateUnnamedPackage(t *testing.T) { - var conf loader.Config - conf.CreateFromFilenames("") - prog, err := conf.Load() - if err != nil { - t.Fatalf("Load failed: %v", err) - } - if got, want := fmt.Sprint(prog.InitialPackages()), "[(unnamed)]"; got != want { - t.Errorf("InitialPackages = %s, want %s", got, want) - } -} - -func TestLoad_MissingFileInCreatedPackage(t *testing.T) { - var conf loader.Config - conf.CreateFromFilenames("", "missing.go") - - const wantErr = "couldn't load packages due to errors: (unnamed)" - - prog, err := conf.Load() - if prog != nil { - t.Errorf("Load unexpectedly returned a Program") - } - if err == nil { - t.Fatalf("Load succeeded unexpectedly, want %q", wantErr) - } - if err.Error() != wantErr { - t.Fatalf("Load failed with wrong error %q, want %q", err, wantErr) - } -} - -func TestLoad_MissingFileInCreatedPackage_AllowErrors(t *testing.T) { - conf := loader.Config{AllowErrors: true} - conf.CreateFromFilenames("", "missing.go") - - prog, err := conf.Load() - if err != nil { - t.Errorf("Load failed: %v", err) - } - if got, want := fmt.Sprint(prog.InitialPackages()), "[(unnamed)]"; got != want { - t.Fatalf("InitialPackages = %s, want %s", got, want) - } -} - -func TestLoad_ParseError(t *testing.T) { - var conf loader.Config - conf.CreateFromFilenames("badpkg", "testdata/badpkgdecl.go") - - const wantErr = "couldn't load packages due to errors: badpkg" - - prog, err := conf.Load() - if prog != nil { - t.Errorf("Load unexpectedly returned a Program") - } - if err == nil { - t.Fatalf("Load succeeded unexpectedly, want %q", wantErr) - } - if err.Error() != wantErr { - t.Fatalf("Load failed with wrong error %q, want %q", err, wantErr) - } -} - -func TestLoad_ParseError_AllowErrors(t *testing.T) { - var conf loader.Config - conf.AllowErrors = true - conf.CreateFromFilenames("badpkg", "testdata/badpkgdecl.go") - - prog, err := conf.Load() - if err != nil { - t.Errorf("Load failed unexpectedly: %v", err) - } - if prog == nil { - t.Fatalf("Load returned a nil Program") - } - if got, want := created(prog), "badpkg"; got != want { - t.Errorf("Created = %s, want %s", got, want) - } - - badpkg := prog.Created[0] - if len(badpkg.Files) != 1 { - t.Errorf("badpkg has %d files, want 1", len(badpkg.Files)) - } - wantErr := filepath.Join("testdata", "badpkgdecl.go") + ":1:34: expected 'package', found 'EOF'" - if !hasError(badpkg.Errors, wantErr) { - t.Errorf("badpkg.Errors = %v, want %s", badpkg.Errors, wantErr) - } -} - -func TestLoad_FromSource_Success(t *testing.T) { - var conf loader.Config - conf.CreateFromFilenames("P", "testdata/a.go", "testdata/b.go") - - prog, err := conf.Load() - if err != nil { - t.Errorf("Load failed unexpectedly: %v", err) - } - if prog == nil { - t.Fatalf("Load returned a nil Program") - } - if got, want := created(prog), "P"; got != want { - t.Errorf("Created = %s, want %s", got, want) - } -} - -func TestLoad_FromImports_Success(t *testing.T) { - var conf loader.Config - conf.ImportWithTests("fmt") - conf.ImportWithTests("errors") - - prog, err := conf.Load() - if err != nil { - t.Errorf("Load failed unexpectedly: %v", err) - } - if prog == nil { - t.Fatalf("Load returned a nil Program") - } - if got, want := created(prog), "errors_test fmt_test"; got != want { - t.Errorf("Created = %q, want %s", got, want) - } - if got, want := imported(prog), "errors fmt"; got != want { - t.Errorf("Imported = %s, want %s", got, want) - } - // Check set of transitive packages. - // There are >30 and the set may grow over time, so only check a few. - want := map[string]bool{ - "strings": true, - "time": true, - "runtime": true, - "testing": true, - "unicode": true, - } - for _, path := range all(prog) { - delete(want, path) - } - if len(want) > 0 { - t.Errorf("AllPackages is missing these keys: %q", keys(want)) - } -} - -func TestLoad_MissingIndirectImport(t *testing.T) { - pkgs := map[string]string{ - "a": `package a; import _ "b"`, - "b": `package b; import _ "c"`, - } - conf := loader.Config{Build: fakeContext(pkgs)} - conf.Import("a") - - const wantErr = "couldn't load packages due to errors: b" - - prog, err := conf.Load() - if err == nil { - t.Errorf("Load succeeded unexpectedly, want %q", wantErr) - } else if err.Error() != wantErr { - t.Errorf("Load failed with wrong error %q, want %q", err, wantErr) - } - if prog != nil { - t.Errorf("Load unexpectedly returned a Program") - } -} - -func TestLoad_BadDependency_AllowErrors(t *testing.T) { - for _, test := range []struct { - descr string - pkgs map[string]string - wantPkgs string - }{ - - { - descr: "missing dependency", - pkgs: map[string]string{ - "a": `package a; import _ "b"`, - "b": `package b; import _ "c"`, - }, - wantPkgs: "a b", - }, - { - descr: "bad package decl in dependency", - pkgs: map[string]string{ - "a": `package a; import _ "b"`, - "b": `package b; import _ "c"`, - "c": `package`, - }, - wantPkgs: "a b", - }, - { - descr: "parse error in dependency", - pkgs: map[string]string{ - "a": `package a; import _ "b"`, - "b": `package b; import _ "c"`, - "c": `package c; var x = `, - }, - wantPkgs: "a b c", - }, - } { - conf := loader.Config{ - AllowErrors: true, - Build: fakeContext(test.pkgs), - } - conf.Import("a") - - prog, err := conf.Load() - if err != nil { - t.Errorf("%s: Load failed unexpectedly: %v", test.descr, err) - } - if prog == nil { - t.Fatalf("%s: Load returned a nil Program", test.descr) - } - - if got, want := imported(prog), "a"; got != want { - t.Errorf("%s: Imported = %s, want %s", test.descr, got, want) - } - if got := all(prog); strings.Join(got, " ") != test.wantPkgs { - t.Errorf("%s: AllPackages = %s, want %s", test.descr, got, test.wantPkgs) - } - } -} - -func TestCwd(t *testing.T) { - ctxt := fakeContext(map[string]string{"one/two/three": `package three`}) - for _, test := range []struct { - cwd, arg, want string - }{ - {cwd: "/go/src/one", arg: "./two/three", want: "one/two/three"}, - {cwd: "/go/src/one", arg: "../one/two/three", want: "one/two/three"}, - {cwd: "/go/src/one", arg: "one/two/three", want: "one/two/three"}, - {cwd: "/go/src/one/two/three", arg: ".", want: "one/two/three"}, - {cwd: "/go/src/one", arg: "two/three", want: ""}, - } { - conf := loader.Config{ - Cwd: test.cwd, - Build: ctxt, - } - conf.Import(test.arg) - - var got string - prog, err := conf.Load() - if prog != nil { - got = imported(prog) - } - if got != test.want { - t.Errorf("Load(%s) from %s: Imported = %s, want %s", - test.arg, test.cwd, got, test.want) - if err != nil { - t.Errorf("Load failed: %v", err) - } - } - } -} - -func TestLoad_vendor(t *testing.T) { - pkgs := map[string]string{ - "a": `package a; import _ "x"`, - "a/vendor": ``, // mkdir a/vendor - "a/vendor/x": `package xa`, - "b": `package b; import _ "x"`, - "b/vendor": ``, // mkdir b/vendor - "b/vendor/x": `package xb`, - "c": `package c; import _ "x"`, - "x": `package xc`, - } - conf := loader.Config{Build: fakeContext(pkgs)} - conf.Import("a") - conf.Import("b") - conf.Import("c") - - prog, err := conf.Load() - if err != nil { - t.Fatal(err) - } - - // Check that a, b, and c see different versions of x. - for _, r := range "abc" { - name := string(r) - got := prog.Package(name).Pkg.Imports()[0] - want := "x" + name - if got.Name() != want { - t.Errorf("package %s import %q = %s, want %s", - name, "x", got.Name(), want) - } - } -} - -func TestVendorCwd(t *testing.T) { - // Test the interaction of cwd and vendor directories. - ctxt := fakeContext(map[string]string{ - "net": ``, // mkdir net - "net/http": `package http; import _ "hpack"`, - "vendor": ``, // mkdir vendor - "vendor/hpack": `package vendorhpack`, - "hpack": `package hpack`, - }) - for i, test := range []struct { - cwd, arg, want string - }{ - {cwd: "/go/src/net", arg: "http"}, // not found - {cwd: "/go/src/net", arg: "./http", want: "net/http vendor/hpack"}, - {cwd: "/go/src/net", arg: "hpack", want: "vendor/hpack"}, - {cwd: "/go/src/vendor", arg: "hpack", want: "vendor/hpack"}, - {cwd: "/go/src/vendor", arg: "./hpack", want: "vendor/hpack"}, - } { - conf := loader.Config{ - Cwd: test.cwd, - Build: ctxt, - } - conf.Import(test.arg) - - var got string - prog, err := conf.Load() - if prog != nil { - got = strings.Join(all(prog), " ") - } - if got != test.want { - t.Errorf("#%d: Load(%s) from %s: got %s, want %s", - i, test.arg, test.cwd, got, test.want) - if err != nil { - t.Errorf("Load failed: %v", err) - } - } - } -} - -func TestVendorCwdIssue16580(t *testing.T) { - // Regression test for Go issue 16580. - // Import decls in "created" packages were vendor-resolved - // w.r.t. cwd, not the parent directory of the package's files. - ctxt := fakeContext(map[string]string{ - "a": ``, // mkdir a - "a/vendor": ``, // mkdir a/vendor - "a/vendor/b": `package b; const X = true`, - "b": `package b; const X = false`, - }) - for _, test := range []struct { - filename, cwd string - want bool // expected value of b.X; depends on filename, not on cwd - }{ - {filename: "c.go", cwd: "/go/src", want: false}, - {filename: "c.go", cwd: "/go/src/a", want: false}, - {filename: "c.go", cwd: "/go/src/a/b", want: false}, - {filename: "c.go", cwd: "/go/src/a/vendor/b", want: false}, - - {filename: "/go/src/a/c.go", cwd: "/go/src", want: true}, - {filename: "/go/src/a/c.go", cwd: "/go/src/a", want: true}, - {filename: "/go/src/a/c.go", cwd: "/go/src/a/b", want: true}, - {filename: "/go/src/a/c.go", cwd: "/go/src/a/vendor/b", want: true}, - - {filename: "/go/src/c/c.go", cwd: "/go/src", want: false}, - {filename: "/go/src/c/c.go", cwd: "/go/src/a", want: false}, - {filename: "/go/src/c/c.go", cwd: "/go/src/a/b", want: false}, - {filename: "/go/src/c/c.go", cwd: "/go/src/a/vendor/b", want: false}, - } { - conf := loader.Config{ - Cwd: test.cwd, - Build: ctxt, - } - f, err := conf.ParseFile(test.filename, `package dummy; import "b"; const X = b.X`) - if err != nil { - t.Fatal(f) - } - conf.CreateFromFiles("dummy", f) - - prog, err := conf.Load() - if err != nil { - t.Errorf("%+v: Load failed: %v", test, err) - continue - } - - x := constant.BoolVal(prog.Created[0].Pkg.Scope().Lookup("X").(*types.Const).Val()) - if x != test.want { - t.Errorf("%+v: b.X = %t", test, x) - } - } - - // TODO(adonovan): also test imports within XTestGoFiles. -} - -// TODO(adonovan): more Load tests: -// -// failures: -// - to parse package decl of *_test.go files -// - to parse package decl of external *_test.go files -// - to parse whole of *_test.go files -// - to parse whole of external *_test.go files -// - to open a *.go file during import scanning -// - to import from binary - -// features: -// - InitialPackages -// - PackageCreated hook -// - TypeCheckFuncBodies hook - -func TestTransitivelyErrorFreeFlag(t *testing.T) { - // Create an minimal custom build.Context - // that fakes the following packages: - // - // a --> b --> c! c has an error - // \ d and e are transitively error-free. - // e --> d - // - // Each package [a-e] consists of one file, x.go. - pkgs := map[string]string{ - "a": `package a; import (_ "b"; _ "e")`, - "b": `package b; import _ "c"`, - "c": `package c; func f() { _ = int(false) }`, // type error within function body - "d": `package d;`, - "e": `package e; import _ "d"`, - } - conf := loader.Config{ - AllowErrors: true, - Build: fakeContext(pkgs), - } - conf.Import("a") - - prog, err := conf.Load() - if err != nil { - t.Errorf("Load failed: %s", err) - } - if prog == nil { - t.Fatalf("Load returned nil *Program") - } - - for pkg, info := range prog.AllPackages { - var wantErr, wantTEF bool - switch pkg.Path() { - case "a", "b": - case "c": - wantErr = true - case "d", "e": - wantTEF = true - default: - t.Errorf("unexpected package: %q", pkg.Path()) - continue - } - - if (info.Errors != nil) != wantErr { - if wantErr { - t.Errorf("Package %q.Error = nil, want error", pkg.Path()) - } else { - t.Errorf("Package %q has unexpected Errors: %v", - pkg.Path(), info.Errors) - } - } - - if info.TransitivelyErrorFree != wantTEF { - t.Errorf("Package %q.TransitivelyErrorFree=%t, want %t", - pkg.Path(), info.TransitivelyErrorFree, wantTEF) - } - } -} - -// Test that syntax (scan/parse), type, and loader errors are recorded -// (in PackageInfo.Errors) and reported (via Config.TypeChecker.Error). -func TestErrorReporting(t *testing.T) { - pkgs := map[string]string{ - "a": `package a; import (_ "b"; _ "c"); var x int = false`, - "b": `package b; 'syntax error!`, - } - conf := loader.Config{ - AllowErrors: true, - Build: fakeContext(pkgs), - } - var mu sync.Mutex - var allErrors []error - conf.TypeChecker.Error = func(err error) { - mu.Lock() - allErrors = append(allErrors, err) - mu.Unlock() - } - conf.Import("a") - - prog, err := conf.Load() - if err != nil { - t.Errorf("Load failed: %s", err) - } - if prog == nil { - t.Fatalf("Load returned nil *Program") - } - - // TODO(adonovan): test keys of ImportMap. - - // Check errors recorded in each PackageInfo. - for pkg, info := range prog.AllPackages { - switch pkg.Path() { - case "a": - if !hasError(info.Errors, "cannot convert false") { - t.Errorf("a.Errors = %v, want bool conversion (type) error", info.Errors) - } - if !hasError(info.Errors, "could not import c") { - t.Errorf("a.Errors = %v, want import (loader) error", info.Errors) - } - case "b": - if !hasError(info.Errors, "rune literal not terminated") { - t.Errorf("b.Errors = %v, want unterminated literal (syntax) error", info.Errors) - } - } - } - - // Check errors reported via error handler. - if !hasError(allErrors, "cannot convert false") || - !hasError(allErrors, "rune literal not terminated") || - !hasError(allErrors, "could not import c") { - t.Errorf("allErrors = %v, want syntax, type and loader errors", allErrors) - } -} - -func TestCycles(t *testing.T) { - for _, test := range []struct { - descr string - ctxt *build.Context - wantErr string - }{ - { - "self-cycle", - fakeContext(map[string]string{ - "main": `package main; import _ "selfcycle"`, - "selfcycle": `package selfcycle; import _ "selfcycle"`, - }), - `import cycle: selfcycle -> selfcycle`, - }, - { - "three-package cycle", - fakeContext(map[string]string{ - "main": `package main; import _ "a"`, - "a": `package a; import _ "b"`, - "b": `package b; import _ "c"`, - "c": `package c; import _ "a"`, - }), - `import cycle: c -> a -> b -> c`, - }, - { - "self-cycle in dependency of test file", - buildutil.FakeContext(map[string]map[string]string{ - "main": { - "main.go": `package main`, - "main_test.go": `package main; import _ "a"`, - }, - "a": { - "a.go": `package a; import _ "a"`, - }, - }), - `import cycle: a -> a`, - }, - // TODO(adonovan): fix: these fail - // { - // "two-package cycle in dependency of test file", - // buildutil.FakeContext(map[string]map[string]string{ - // "main": { - // "main.go": `package main`, - // "main_test.go": `package main; import _ "a"`, - // }, - // "a": { - // "a.go": `package a; import _ "main"`, - // }, - // }), - // `import cycle: main -> a -> main`, - // }, - // { - // "self-cycle in augmented package", - // buildutil.FakeContext(map[string]map[string]string{ - // "main": { - // "main.go": `package main`, - // "main_test.go": `package main; import _ "main"`, - // }, - // }), - // `import cycle: main -> main`, - // }, - } { - conf := loader.Config{ - AllowErrors: true, - Build: test.ctxt, - } - var mu sync.Mutex - var allErrors []error - conf.TypeChecker.Error = func(err error) { - mu.Lock() - allErrors = append(allErrors, err) - mu.Unlock() - } - conf.ImportWithTests("main") - - prog, err := conf.Load() - if err != nil { - t.Errorf("%s: Load failed: %s", test.descr, err) - } - if prog == nil { - t.Fatalf("%s: Load returned nil *Program", test.descr) - } - - if !hasError(allErrors, test.wantErr) { - t.Errorf("%s: Load() errors = %q, want %q", - test.descr, allErrors, test.wantErr) - } - } - - // TODO(adonovan): - // - Test that in a legal test cycle, none of the symbols - // defined by augmentation are visible via import. -} - -// ---- utilities ---- - -// Simplifying wrapper around buildutil.FakeContext for single-file packages. -func fakeContext(pkgs map[string]string) *build.Context { - pkgs2 := make(map[string]map[string]string) - for path, content := range pkgs { - pkgs2[path] = map[string]string{"x.go": content} - } - return buildutil.FakeContext(pkgs2) -} - -func hasError(errors []error, substr string) bool { - for _, err := range errors { - if strings.Contains(err.Error(), substr) { - return true - } - } - return false -} - -func keys(m map[string]bool) (keys []string) { - for key := range m { - keys = append(keys, key) - } - sort.Strings(keys) - return -} - -// Returns all loaded packages. -func all(prog *loader.Program) []string { - var pkgs []string - for _, info := range prog.AllPackages { - pkgs = append(pkgs, info.Pkg.Path()) - } - sort.Strings(pkgs) - return pkgs -} - -// Returns initially imported packages, as a string. -func imported(prog *loader.Program) string { - var pkgs []string - for _, info := range prog.Imported { - pkgs = append(pkgs, info.Pkg.Path()) - } - sort.Strings(pkgs) - return strings.Join(pkgs, " ") -} - -// Returns initially created packages, as a string. -func created(prog *loader.Program) string { - var pkgs []string - for _, info := range prog.Created { - pkgs = append(pkgs, info.Pkg.Path()) - } - return strings.Join(pkgs, " ") -} - -// Load package "io" twice in parallel. -// When run with -race, this is a regression test for Go issue 20718, in -// which the global "unsafe" package was modified concurrently. -func TestLoad1(t *testing.T) { loadIO(t) } -func TestLoad2(t *testing.T) { loadIO(t) } - -func loadIO(t *testing.T) { - t.Parallel() - conf := &loader.Config{ImportPkgs: map[string]bool{"io": false}} - if _, err := conf.Load(); err != nil { - t.Fatal(err) - } -} diff --git a/vendor/golang.org/x/tools/go/loader/stdlib_test.go b/vendor/golang.org/x/tools/go/loader/stdlib_test.go deleted file mode 100644 index 2cd066f..0000000 --- a/vendor/golang.org/x/tools/go/loader/stdlib_test.go +++ /dev/null @@ -1,201 +0,0 @@ -// Copyright 2013 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 loader_test - -// This file enumerates all packages beneath $GOROOT, loads them, plus -// their external tests if any, runs the type checker on them, and -// prints some summary information. - -import ( - "bytes" - "fmt" - "go/ast" - "go/build" - "go/token" - "go/types" - "io/ioutil" - "path/filepath" - "runtime" - "strings" - "testing" - "time" - - "golang.org/x/tools/go/buildutil" - "golang.org/x/tools/go/loader" -) - -func TestStdlib(t *testing.T) { - if runtime.GOOS == "android" { - t.Skipf("incomplete std lib on %s", runtime.GOOS) - } - if testing.Short() { - t.Skip("skipping in short mode; uses tons of memory (golang.org/issue/14113)") - } - - runtime.GC() - t0 := time.Now() - var memstats runtime.MemStats - runtime.ReadMemStats(&memstats) - alloc := memstats.Alloc - - // Load, parse and type-check the program. - ctxt := build.Default // copy - ctxt.GOPATH = "" // disable GOPATH - conf := loader.Config{Build: &ctxt} - for _, path := range buildutil.AllPackages(conf.Build) { - conf.ImportWithTests(path) - } - - prog, err := conf.Load() - if err != nil { - t.Fatalf("Load failed: %v", err) - } - - t1 := time.Now() - runtime.GC() - runtime.ReadMemStats(&memstats) - - numPkgs := len(prog.AllPackages) - if want := 205; numPkgs < want { - t.Errorf("Loaded only %d packages, want at least %d", numPkgs, want) - } - - // Dump package members. - if false { - for pkg := range prog.AllPackages { - fmt.Printf("Package %s:\n", pkg.Path()) - scope := pkg.Scope() - qualifier := types.RelativeTo(pkg) - for _, name := range scope.Names() { - if ast.IsExported(name) { - fmt.Printf("\t%s\n", types.ObjectString(scope.Lookup(name), qualifier)) - } - } - fmt.Println() - } - } - - // Check that Test functions for io/ioutil, regexp and - // compress/bzip2 are all simultaneously present. - // (The apparent cycle formed when augmenting all three of - // these packages by their tests was the original motivation - // for reporting b/7114.) - // - // compress/bzip2.TestBitReader in bzip2_test.go imports io/ioutil - // io/ioutil.TestTempFile in tempfile_test.go imports regexp - // regexp.TestRE2Search in exec_test.go imports compress/bzip2 - for _, test := range []struct{ pkg, fn string }{ - {"io/ioutil", "TestTempFile"}, - {"regexp", "TestRE2Search"}, - {"compress/bzip2", "TestBitReader"}, - } { - info := prog.Imported[test.pkg] - if info == nil { - t.Errorf("failed to load package %q", test.pkg) - continue - } - obj, _ := info.Pkg.Scope().Lookup(test.fn).(*types.Func) - if obj == nil { - t.Errorf("package %q has no func %q", test.pkg, test.fn) - continue - } - } - - // Dump some statistics. - - // determine line count - var lineCount int - prog.Fset.Iterate(func(f *token.File) bool { - lineCount += f.LineCount() - return true - }) - - t.Log("GOMAXPROCS: ", runtime.GOMAXPROCS(0)) - t.Log("#Source lines: ", lineCount) - t.Log("Load/parse/typecheck: ", t1.Sub(t0)) - t.Log("#MB: ", int64(memstats.Alloc-alloc)/1000000) -} - -func TestCgoOption(t *testing.T) { - if testing.Short() { - t.Skip("skipping in short mode; uses tons of memory (golang.org/issue/14113)") - } - switch runtime.GOOS { - // On these systems, the net and os/user packages don't use cgo - // or the std library is incomplete (Android). - case "android", "plan9", "solaris", "windows": - t.Skipf("no cgo or incomplete std lib on %s", runtime.GOOS) - } - // In nocgo builds (e.g. linux-amd64-nocgo), - // there is no "runtime/cgo" package, - // so cgo-generated Go files will have a failing import. - if !build.Default.CgoEnabled { - return - } - // Test that we can load cgo-using packages with - // CGO_ENABLED=[01], which causes go/build to select pure - // Go/native implementations, respectively, based on build - // tags. - // - // Each entry specifies a package-level object and the generic - // file expected to define it when cgo is disabled. - // When cgo is enabled, the exact file is not specified (since - // it varies by platform), but must differ from the generic one. - // - // The test also loads the actual file to verify that the - // object is indeed defined at that location. - for _, test := range []struct { - pkg, name, genericFile string - }{ - {"net", "cgoLookupHost", "cgo_stub.go"}, - {"os/user", "current", "lookup_stubs.go"}, - } { - ctxt := build.Default - for _, ctxt.CgoEnabled = range []bool{false, true} { - conf := loader.Config{Build: &ctxt} - conf.Import(test.pkg) - prog, err := conf.Load() - if err != nil { - t.Errorf("Load failed: %v", err) - continue - } - info := prog.Imported[test.pkg] - if info == nil { - t.Errorf("package %s not found", test.pkg) - continue - } - obj := info.Pkg.Scope().Lookup(test.name) - if obj == nil { - t.Errorf("no object %s.%s", test.pkg, test.name) - continue - } - posn := prog.Fset.Position(obj.Pos()) - t.Logf("%s: %s (CgoEnabled=%t)", posn, obj, ctxt.CgoEnabled) - - gotFile := filepath.Base(posn.Filename) - filesMatch := gotFile == test.genericFile - - if ctxt.CgoEnabled && filesMatch { - t.Errorf("CGO_ENABLED=1: %s found in %s, want native file", - obj, gotFile) - } else if !ctxt.CgoEnabled && !filesMatch { - t.Errorf("CGO_ENABLED=0: %s found in %s, want %s", - obj, gotFile, test.genericFile) - } - - // Load the file and check the object is declared at the right place. - b, err := ioutil.ReadFile(posn.Filename) - if err != nil { - t.Errorf("can't read %s: %s", posn.Filename, err) - continue - } - line := string(bytes.Split(b, []byte("\n"))[posn.Line-1]) - ident := line[posn.Column-1:] - if !strings.HasPrefix(ident, test.name) { - t.Errorf("%s: %s not declared here (looking at %q)", posn, obj, ident) - } - } - } -} diff --git a/vendor/golang.org/x/tools/go/loader/testdata/a.go b/vendor/golang.org/x/tools/go/loader/testdata/a.go deleted file mode 100644 index bae3955..0000000 --- a/vendor/golang.org/x/tools/go/loader/testdata/a.go +++ /dev/null @@ -1 +0,0 @@ -package P diff --git a/vendor/golang.org/x/tools/go/loader/testdata/b.go b/vendor/golang.org/x/tools/go/loader/testdata/b.go deleted file mode 100644 index bae3955..0000000 --- a/vendor/golang.org/x/tools/go/loader/testdata/b.go +++ /dev/null @@ -1 +0,0 @@ -package P diff --git a/vendor/golang.org/x/tools/go/loader/testdata/badpkgdecl.go b/vendor/golang.org/x/tools/go/loader/testdata/badpkgdecl.go deleted file mode 100644 index 1e39359..0000000 --- a/vendor/golang.org/x/tools/go/loader/testdata/badpkgdecl.go +++ /dev/null @@ -1 +0,0 @@ -// this file has no package decl diff --git a/vendor/golang.org/x/tools/go/loader/util.go b/vendor/golang.org/x/tools/go/loader/util.go deleted file mode 100644 index 7f38dd7..0000000 --- a/vendor/golang.org/x/tools/go/loader/util.go +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright 2013 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 loader - -import ( - "go/ast" - "go/build" - "go/parser" - "go/token" - "io" - "os" - "strconv" - "sync" - - "golang.org/x/tools/go/buildutil" -) - -// We use a counting semaphore to limit -// the number of parallel I/O calls per process. -var ioLimit = make(chan bool, 10) - -// parseFiles parses the Go source files within directory dir and -// returns the ASTs of the ones that could be at least partially parsed, -// along with a list of I/O and parse errors encountered. -// -// I/O is done via ctxt, which may specify a virtual file system. -// displayPath is used to transform the filenames attached to the ASTs. -// -func parseFiles(fset *token.FileSet, ctxt *build.Context, displayPath func(string) string, dir string, files []string, mode parser.Mode) ([]*ast.File, []error) { - if displayPath == nil { - displayPath = func(path string) string { return path } - } - var wg sync.WaitGroup - n := len(files) - parsed := make([]*ast.File, n) - errors := make([]error, n) - for i, file := range files { - if !buildutil.IsAbsPath(ctxt, file) { - file = buildutil.JoinPath(ctxt, dir, file) - } - wg.Add(1) - go func(i int, file string) { - ioLimit <- true // wait - defer func() { - wg.Done() - <-ioLimit // signal - }() - var rd io.ReadCloser - var err error - if ctxt.OpenFile != nil { - rd, err = ctxt.OpenFile(file) - } else { - rd, err = os.Open(file) - } - if err != nil { - errors[i] = err // open failed - return - } - - // ParseFile may return both an AST and an error. - parsed[i], errors[i] = parser.ParseFile(fset, displayPath(file), rd, mode) - rd.Close() - }(i, file) - } - wg.Wait() - - // Eliminate nils, preserving order. - var o int - for _, f := range parsed { - if f != nil { - parsed[o] = f - o++ - } - } - parsed = parsed[:o] - - o = 0 - for _, err := range errors { - if err != nil { - errors[o] = err - o++ - } - } - errors = errors[:o] - - return parsed, errors -} - -// scanImports returns the set of all import paths from all -// import specs in the specified files. -func scanImports(files []*ast.File) map[string]bool { - imports := make(map[string]bool) - for _, f := range files { - for _, decl := range f.Decls { - if decl, ok := decl.(*ast.GenDecl); ok && decl.Tok == token.IMPORT { - for _, spec := range decl.Specs { - spec := spec.(*ast.ImportSpec) - - // NB: do not assume the program is well-formed! - path, err := strconv.Unquote(spec.Path.Value) - if err != nil { - continue // quietly ignore the error - } - if path == "C" { - continue // skip pseudopackage - } - imports[path] = true - } - } - } - } - return imports -} - -// ---------- Internal helpers ---------- - -// TODO(adonovan): make this a method: func (*token.File) Contains(token.Pos) -func tokenFileContainsPos(f *token.File, pos token.Pos) bool { - p := int(pos) - base := f.Base() - return base <= p && p < base+f.Size() -} -- cgit v1.2.3