doc.go 9.3 KB

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