blob: e35b1fd7d93dada1579abb81f8d342b52ac63366 [file] [log] [blame]
Alan Donovan1b6275a2015-04-16 15:42:28 -04001// Copyright 2015 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
Alan Donovan9c57c192015-04-14 16:56:02 -04005// Package loader loads a complete Go program from source code, parsing
6// and type-checking the initial packages plus their transitive closure
7// of dependencies. The ASTs and the derived facts are retained for
8// later use.
Alan Donovan1b6275a2015-04-16 15:42:28 -04009//
Dmitri Shuralyov7f221872019-06-21 21:59:57 -040010// Deprecated: This is an older API and does not have support
11// for modules. Use golang.org/x/tools/go/packages instead.
Alan Donovan1b6275a2015-04-16 15:42:28 -040012//
13// The package defines two primary types: Config, which specifies a
14// set of initial packages to load and various other options; and
15// Program, which is the result of successfully loading the packages
16// specified by a configuration.
17//
18// The configuration can be set directly, but *Config provides various
19// convenience methods to simplify the common cases, each of which can
20// be called any number of times. Finally, these are followed by a
21// call to Load() to actually load and type-check the program.
22//
Russ Coxd5f48fc2022-04-11 23:03:04 -040023// var conf loader.Config
Alan Donovan1b6275a2015-04-16 15:42:28 -040024//
Russ Coxd5f48fc2022-04-11 23:03:04 -040025// // Use the command-line arguments to specify
26// // a set of initial packages to load from source.
27// // See FromArgsUsage for help.
28// rest, err := conf.FromArgs(os.Args[1:], wantTests)
Alan Donovan1b6275a2015-04-16 15:42:28 -040029//
Russ Coxd5f48fc2022-04-11 23:03:04 -040030// // Parse the specified files and create an ad hoc package with path "foo".
31// // All files must have the same 'package' declaration.
32// conf.CreateFromFilenames("foo", "foo.go", "bar.go")
Alan Donovan1b6275a2015-04-16 15:42:28 -040033//
Russ Coxd5f48fc2022-04-11 23:03:04 -040034// // Create an ad hoc package with path "foo" from
35// // the specified already-parsed files.
36// // All ASTs must have the same 'package' declaration.
37// conf.CreateFromFiles("foo", parsedFiles)
Alan Donovan1b6275a2015-04-16 15:42:28 -040038//
Russ Coxd5f48fc2022-04-11 23:03:04 -040039// // Add "runtime" to the set of packages to be loaded.
40// conf.Import("runtime")
Alan Donovan1b6275a2015-04-16 15:42:28 -040041//
Russ Coxd5f48fc2022-04-11 23:03:04 -040042// // Adds "fmt" and "fmt_test" to the set of packages
43// // to be loaded. "fmt" will include *_test.go files.
44// conf.ImportWithTests("fmt")
Alan Donovan1b6275a2015-04-16 15:42:28 -040045//
Russ Coxd5f48fc2022-04-11 23:03:04 -040046// // Finally, load all the packages specified by the configuration.
47// prog, err := conf.Load()
Alan Donovan1b6275a2015-04-16 15:42:28 -040048//
49// See examples_test.go for examples of API usage.
50//
Russ Coxd5f48fc2022-04-11 23:03:04 -040051// # CONCEPTS AND TERMINOLOGY
Alan Donovan1b6275a2015-04-16 15:42:28 -040052//
Alan Donovand6e83e52015-12-18 21:02:28 -050053// The WORKSPACE is the set of packages accessible to the loader. The
54// workspace is defined by Config.Build, a *build.Context. The
55// default context treats subdirectories of $GOROOT and $GOPATH as
56// packages, but this behavior may be overridden.
57//
Alan Donovan9c57c192015-04-14 16:56:02 -040058// An AD HOC package is one specified as a set of source files on the
Alan Donovan1b6275a2015-04-16 15:42:28 -040059// command line. In the simplest case, it may consist of a single file
60// such as $GOROOT/src/net/http/triv.go.
61//
62// EXTERNAL TEST packages are those comprised of a set of *_test.go
63// files all with the same 'package foo_test' declaration, all in the
64// same directory. (go/build.Package calls these files XTestFiles.)
65//
66// An IMPORTABLE package is one that can be referred to by some import
Alan Donovand6e83e52015-12-18 21:02:28 -050067// spec. Every importable package is uniquely identified by its
68// PACKAGE PATH or just PATH, a string such as "fmt", "encoding/json",
69// or "cmd/vendor/golang.org/x/arch/x86/x86asm". A package path
70// typically denotes a subdirectory of the workspace.
71//
72// An import declaration uses an IMPORT PATH to refer to a package.
73// Most import declarations use the package path as the import path.
74//
75// Due to VENDORING (https://golang.org/s/go15vendor), the
76// interpretation of an import path may depend on the directory in which
77// it appears. To resolve an import path to a package path, go/build
78// must search the enclosing directories for a subdirectory named
79// "vendor".
Alan Donovan1b6275a2015-04-16 15:42:28 -040080//
Alan Donovan9c57c192015-04-14 16:56:02 -040081// ad hoc packages and external test packages are NON-IMPORTABLE. The
Alan Donovand6e83e52015-12-18 21:02:28 -050082// path of an ad hoc package is inferred from the package
Alan Donovan1b6275a2015-04-16 15:42:28 -040083// declarations of its files and is therefore not a unique package key.
Alan Donovan9c57c192015-04-14 16:56:02 -040084// For example, Config.CreatePkgs may specify two initial ad hoc
Alan Donovand6e83e52015-12-18 21:02:28 -050085// packages, both with path "main".
Alan Donovan1b6275a2015-04-16 15:42:28 -040086//
87// An AUGMENTED package is an importable package P plus all the
88// *_test.go files with same 'package foo' declaration as P.
89// (go/build.Package calls these files TestFiles.)
90//
91// The INITIAL packages are those specified in the configuration. A
92// DEPENDENCY is a package loaded to satisfy an import in an initial
93// package or another dependency.
Alan Donovan1b6275a2015-04-16 15:42:28 -040094package loader
95
96// IMPLEMENTATION NOTES
97//
98// 'go test', in-package test files, and import cycles
99// ---------------------------------------------------
100//
101// An external test package may depend upon members of the augmented
102// package that are not in the unaugmented package, such as functions
103// that expose internals. (See bufio/export_test.go for an example.)
104// So, the loader must ensure that for each external test package
105// it loads, it also augments the corresponding non-test package.
106//
107// The import graph over n unaugmented packages must be acyclic; the
108// import graph over n-1 unaugmented packages plus one augmented
109// package must also be acyclic. ('go test' relies on this.) But the
110// import graph over n augmented packages may contain cycles.
111//
112// First, all the (unaugmented) non-test packages and their
113// dependencies are imported in the usual way; the loader reports an
114// error if it detects an import cycle.
115//
116// Then, each package P for which testing is desired is augmented by
117// the list P' of its in-package test files, by calling
118// (*types.Checker).Files. This arrangement ensures that P' may
119// reference definitions within P, but P may not reference definitions
120// within P'. Furthermore, P' may import any other package, including
121// ones that depend upon P, without an import cycle error.
122//
123// Consider two packages A and B, both of which have lists of
124// in-package test files we'll call A' and B', and which have the
125// following import graph edges:
126// B imports A
127// B' imports A
128// A' imports B
129// This last edge would be expected to create an error were it not
130// for the special type-checking discipline above.
131// Cycles of size greater than two are possible. For example:
132// compress/bzip2/bzip2_test.go (package bzip2) imports "io/ioutil"
133// io/ioutil/tempfile_test.go (package ioutil) imports "regexp"
134// regexp/exec_test.go (package regexp) imports "compress/bzip2"
135//
136//
137// Concurrency
138// -----------
139//
140// Let us define the import dependency graph as follows. Each node is a
141// list of files passed to (Checker).Files at once. Many of these lists
142// are the production code of an importable Go package, so those nodes
Alan Donovand6e83e52015-12-18 21:02:28 -0500143// are labelled by the package's path. The remaining nodes are
Alan Donovan9c57c192015-04-14 16:56:02 -0400144// ad hoc packages and lists of in-package *_test.go files that augment
Alan Donovan1b6275a2015-04-16 15:42:28 -0400145// an importable package; those nodes have no label.
146//
147// The edges of the graph represent import statements appearing within a
148// file. An edge connects a node (a list of files) to the node it
149// imports, which is importable and thus always labelled.
150//
151// Loading is controlled by this dependency graph.
152//
153// To reduce I/O latency, we start loading a package's dependencies
154// asynchronously as soon as we've parsed its files and enumerated its
155// imports (scanImports). This performs a preorder traversal of the
156// import dependency graph.
157//
158// To exploit hardware parallelism, we type-check unrelated packages in
159// parallel, where "unrelated" means not ordered by the partial order of
160// the import dependency graph.
161//
Alan Donovan9aae8f02016-02-22 15:21:13 -0500162// We use a concurrency-safe non-blocking cache (importer.imported) to
Alan Donovan1b6275a2015-04-16 15:42:28 -0400163// record the results of type-checking, whether success or failure. An
164// entry is created in this cache by startLoad the first time the
165// package is imported. The first goroutine to request an entry becomes
166// responsible for completing the task and broadcasting completion to
167// subsequent requestors, which block until then.
168//
169// Type checking occurs in (parallel) postorder: we cannot type-check a
170// set of files until we have loaded and type-checked all of their
171// immediate dependencies (and thus all of their transitive
172// dependencies). If the input were guaranteed free of import cycles,
173// this would be trivial: we could simply wait for completion of the
174// dependencies and then invoke the typechecker.
175//
176// But as we saw in the 'go test' section above, some cycles in the
177// import graph over packages are actually legal, so long as the
178// cycle-forming edge originates in the in-package test files that
179// augment the package. This explains why the nodes of the import
180// dependency graph are not packages, but lists of files: the unlabelled
181// nodes avoid the cycles. Consider packages A and B where B imports A
182// and A's in-package tests AT import B. The naively constructed import
183// graph over packages would contain a cycle (A+AT) --> B --> (A+AT) but
184// the graph over lists of files is AT --> B --> A, where AT is an
185// unlabelled node.
186//
187// Awaiting completion of the dependencies in a cyclic graph would
188// deadlock, so we must materialize the import dependency graph (as
189// importer.graph) and check whether each import edge forms a cycle. If
190// x imports y, and the graph already contains a path from y to x, then
191// there is an import cycle, in which case the processing of x must not
192// wait for the completion of processing of y.
193//
194// When the type-checker makes a callback (doImport) to the loader for a
195// given import edge, there are two possible cases. In the normal case,
196// the dependency has already been completely type-checked; doImport
197// does a cache lookup and returns it. In the cyclic case, the entry in
198// the cache is still necessarily incomplete, indicating a cycle. We
199// perform the cycle check again to obtain the error message, and return
200// the error.
201//
202// The result of using concurrency is about a 2.5x speedup for stdlib_test.