diff options
Diffstat (limited to 'vendor/golang.org/x/tools/go/loader')
| -rw-r--r-- | vendor/golang.org/x/tools/go/loader/doc.go | 202 | ||||
| -rw-r--r-- | vendor/golang.org/x/tools/go/loader/loader.go | 1066 | ||||
| -rw-r--r-- | vendor/golang.org/x/tools/go/loader/util.go | 123 | 
3 files changed, 0 insertions, 1391 deletions
| 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 e35b1fd..0000000 --- a/vendor/golang.org/x/tools/go/loader/doc.go +++ /dev/null @@ -1,202 +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. -// -// Deprecated: This is an older API and does not have support -// for modules. Use golang.org/x/tools/go/packages instead. -// -// 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. 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 013c0f5..0000000 --- a/vendor/golang.org/x/tools/go/loader/loader.go +++ /dev/null @@ -1,1066 +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" -	"golang.org/x/tools/go/internal/cgo" -	"golang.org/x/tools/internal/versions" -) - -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 = ` -<args> 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 := cgo.ProcessFiles(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://golang.org/issue/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 { -		// Normalize cycle: start from alphabetically largest node. -		pos, start := -1, "" -		for i, s := range cycle { -			if pos < 0 || s > start { -				pos, start = i, s -			} -		} -		cycle = append(cycle, cycle[:pos]...)[pos:] // rotate cycle to start from largest -		cycle = append(cycle, cycle[0])             // add start node to end to show cycliness -		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) { -	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 importPath := range imports { -			deps[importPath] = true -		} -		imp.graphMu.Unlock() -	} - -	var pending []*importInfo -	for importPath := range imports { -		if fromPath != "" { -			if cycle := imp.findPath(importPath, fromPath); cycle != nil { -				// Cycle-forming import: we must not check it -				// since it would deadlock. -				if trace { -					fmt.Fprintf(os.Stderr, "import cycle: %q\n", cycle) -				} -				continue -			} -		} -		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)) -	} - -	for _, ii := range pending { -		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), -			Instances:  make(map[*ast.Ident]types.Instance), -			Scopes:     make(map[ast.Node]*types.Scope), -			Selections: make(map[*ast.SelectorExpr]*types.Selection), -		}, -		errorFunc: imp.conf.TypeChecker.Error, -		dir:       dir, -	} -	versions.InitFileVersions(&info.Info) - -	// 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/util.go b/vendor/golang.org/x/tools/go/loader/util.go deleted file mode 100644 index 3a80aca..0000000 --- a/vendor/golang.org/x/tools/go/loader/util.go +++ /dev/null @@ -1,123 +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() -} |