packages.go 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957
  1. // Copyright 2018 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 packages
  5. // See doc.go for package documentation and implementation notes.
  6. import (
  7. "context"
  8. "encoding/json"
  9. "fmt"
  10. "go/ast"
  11. "go/parser"
  12. "go/scanner"
  13. "go/token"
  14. "go/types"
  15. "io/ioutil"
  16. "log"
  17. "os"
  18. "path/filepath"
  19. "strings"
  20. "sync"
  21. "golang.org/x/tools/go/gcexportdata"
  22. )
  23. // A LoadMode specifies the amount of detail to return when loading.
  24. // Higher-numbered modes cause Load to return more information,
  25. // but may be slower. Load may return more information than requested.
  26. type LoadMode int
  27. const (
  28. // LoadFiles finds the packages and computes their source file lists.
  29. // Package fields: ID, Name, Errors, GoFiles, and OtherFiles.
  30. LoadFiles LoadMode = iota
  31. // LoadImports adds import information for each package
  32. // and its dependencies.
  33. // Package fields added: Imports.
  34. LoadImports
  35. // LoadTypes adds type information for package-level
  36. // declarations in the packages matching the patterns.
  37. // Package fields added: Types, Fset, and IllTyped.
  38. // This mode uses type information provided by the build system when
  39. // possible, and may fill in the ExportFile field.
  40. LoadTypes
  41. // LoadSyntax adds typed syntax trees for the packages matching the patterns.
  42. // Package fields added: Syntax, and TypesInfo, for direct pattern matches only.
  43. LoadSyntax
  44. // LoadAllSyntax adds typed syntax trees for the packages matching the patterns
  45. // and all dependencies.
  46. // Package fields added: Types, Fset, IllTyped, Syntax, and TypesInfo,
  47. // for all packages in the import graph.
  48. LoadAllSyntax
  49. )
  50. // A Config specifies details about how packages should be loaded.
  51. // The zero value is a valid configuration.
  52. // Calls to Load do not modify this struct.
  53. type Config struct {
  54. // Mode controls the level of information returned for each package.
  55. Mode LoadMode
  56. // Context specifies the context for the load operation.
  57. // If the context is cancelled, the loader may stop early
  58. // and return an ErrCancelled error.
  59. // If Context is nil, the load cannot be cancelled.
  60. Context context.Context
  61. // Dir is the directory in which to run the build system's query tool
  62. // that provides information about the packages.
  63. // If Dir is empty, the tool is run in the current directory.
  64. Dir string
  65. // Env is the environment to use when invoking the build system's query tool.
  66. // If Env is nil, the current environment is used.
  67. // As in os/exec's Cmd, only the last value in the slice for
  68. // each environment key is used. To specify the setting of only
  69. // a few variables, append to the current environment, as in:
  70. //
  71. // opt.Env = append(os.Environ(), "GOOS=plan9", "GOARCH=386")
  72. //
  73. Env []string
  74. // BuildFlags is a list of command-line flags to be passed through to
  75. // the build system's query tool.
  76. BuildFlags []string
  77. // Fset provides source position information for syntax trees and types.
  78. // If Fset is nil, the loader will create a new FileSet.
  79. Fset *token.FileSet
  80. // ParseFile is called to read and parse each file
  81. // when preparing a package's type-checked syntax tree.
  82. // It must be safe to call ParseFile simultaneously from multiple goroutines.
  83. // If ParseFile is nil, the loader will uses parser.ParseFile.
  84. //
  85. // ParseFile should parse the source from src and use filename only for
  86. // recording position information.
  87. //
  88. // An application may supply a custom implementation of ParseFile
  89. // to change the effective file contents or the behavior of the parser,
  90. // or to modify the syntax tree. For example, selectively eliminating
  91. // unwanted function bodies can significantly accelerate type checking.
  92. ParseFile func(fset *token.FileSet, filename string, src []byte) (*ast.File, error)
  93. // If Tests is set, the loader includes not just the packages
  94. // matching a particular pattern but also any related test packages,
  95. // including test-only variants of the package and the test executable.
  96. //
  97. // For example, when using the go command, loading "fmt" with Tests=true
  98. // returns four packages, with IDs "fmt" (the standard package),
  99. // "fmt [fmt.test]" (the package as compiled for the test),
  100. // "fmt_test" (the test functions from source files in package fmt_test),
  101. // and "fmt.test" (the test binary).
  102. //
  103. // In build systems with explicit names for tests,
  104. // setting Tests may have no effect.
  105. Tests bool
  106. // Overlay provides a mapping of absolute file paths to file contents.
  107. // If the file with the given path already exists, the parser will use the
  108. // alternative file contents provided by the map.
  109. //
  110. // Overlays provide incomplete support for when a given file doesn't
  111. // already exist on disk. See the package doc above for more details.
  112. Overlay map[string][]byte
  113. }
  114. // driver is the type for functions that query the build system for the
  115. // packages named by the patterns.
  116. type driver func(cfg *Config, patterns ...string) (*driverResponse, error)
  117. // driverResponse contains the results for a driver query.
  118. type driverResponse struct {
  119. // Sizes, if not nil, is the types.Sizes to use when type checking.
  120. Sizes *types.StdSizes
  121. // Roots is the set of package IDs that make up the root packages.
  122. // We have to encode this separately because when we encode a single package
  123. // we cannot know if it is one of the roots as that requires knowledge of the
  124. // graph it is part of.
  125. Roots []string `json:",omitempty"`
  126. // Packages is the full set of packages in the graph.
  127. // The packages are not connected into a graph.
  128. // The Imports if populated will be stubs that only have their ID set.
  129. // Imports will be connected and then type and syntax information added in a
  130. // later pass (see refine).
  131. Packages []*Package
  132. }
  133. // Load loads and returns the Go packages named by the given patterns.
  134. //
  135. // Config specifies loading options;
  136. // nil behaves the same as an empty Config.
  137. //
  138. // Load returns an error if any of the patterns was invalid
  139. // as defined by the underlying build system.
  140. // It may return an empty list of packages without an error,
  141. // for instance for an empty expansion of a valid wildcard.
  142. // Errors associated with a particular package are recorded in the
  143. // corresponding Package's Errors list, and do not cause Load to
  144. // return an error. Clients may need to handle such errors before
  145. // proceeding with further analysis. The PrintErrors function is
  146. // provided for convenient display of all errors.
  147. func Load(cfg *Config, patterns ...string) ([]*Package, error) {
  148. l := newLoader(cfg)
  149. response, err := defaultDriver(&l.Config, patterns...)
  150. if err != nil {
  151. return nil, err
  152. }
  153. l.sizes = response.Sizes
  154. return l.refine(response.Roots, response.Packages...)
  155. }
  156. // defaultDriver is a driver that looks for an external driver binary, and if
  157. // it does not find it falls back to the built in go list driver.
  158. func defaultDriver(cfg *Config, patterns ...string) (*driverResponse, error) {
  159. driver := findExternalDriver(cfg)
  160. if driver == nil {
  161. driver = goListDriver
  162. }
  163. return driver(cfg, patterns...)
  164. }
  165. // A Package describes a loaded Go package.
  166. type Package struct {
  167. // ID is a unique identifier for a package,
  168. // in a syntax provided by the underlying build system.
  169. //
  170. // Because the syntax varies based on the build system,
  171. // clients should treat IDs as opaque and not attempt to
  172. // interpret them.
  173. ID string
  174. // Name is the package name as it appears in the package source code.
  175. Name string
  176. // PkgPath is the package path as used by the go/types package.
  177. PkgPath string
  178. // Errors contains any errors encountered querying the metadata
  179. // of the package, or while parsing or type-checking its files.
  180. Errors []Error
  181. // GoFiles lists the absolute file paths of the package's Go source files.
  182. GoFiles []string
  183. // CompiledGoFiles lists the absolute file paths of the package's source
  184. // files that were presented to the compiler.
  185. // This may differ from GoFiles if files are processed before compilation.
  186. CompiledGoFiles []string
  187. // OtherFiles lists the absolute file paths of the package's non-Go source files,
  188. // including assembly, C, C++, Fortran, Objective-C, SWIG, and so on.
  189. OtherFiles []string
  190. // ExportFile is the absolute path to a file containing type
  191. // information for the package as provided by the build system.
  192. ExportFile string
  193. // Imports maps import paths appearing in the package's Go source files
  194. // to corresponding loaded Packages.
  195. Imports map[string]*Package
  196. // Types provides type information for the package.
  197. // Modes LoadTypes and above set this field for packages matching the
  198. // patterns; type information for dependencies may be missing or incomplete.
  199. // Mode LoadAllSyntax sets this field for all packages, including dependencies.
  200. Types *types.Package
  201. // Fset provides position information for Types, TypesInfo, and Syntax.
  202. // It is set only when Types is set.
  203. Fset *token.FileSet
  204. // IllTyped indicates whether the package or any dependency contains errors.
  205. // It is set only when Types is set.
  206. IllTyped bool
  207. // Syntax is the package's syntax trees, for the files listed in CompiledGoFiles.
  208. //
  209. // Mode LoadSyntax sets this field for packages matching the patterns.
  210. // Mode LoadAllSyntax sets this field for all packages, including dependencies.
  211. Syntax []*ast.File
  212. // TypesInfo provides type information about the package's syntax trees.
  213. // It is set only when Syntax is set.
  214. TypesInfo *types.Info
  215. // TypesSizes provides the effective size function for types in TypesInfo.
  216. TypesSizes types.Sizes
  217. }
  218. // An Error describes a problem with a package's metadata, syntax, or types.
  219. type Error struct {
  220. Pos string // "file:line:col" or "file:line" or "" or "-"
  221. Msg string
  222. Kind ErrorKind
  223. }
  224. // ErrorKind describes the source of the error, allowing the user to
  225. // differentiate between errors generated by the driver, the parser, or the
  226. // type-checker.
  227. type ErrorKind int
  228. const (
  229. UnknownError ErrorKind = iota
  230. ListError
  231. ParseError
  232. TypeError
  233. )
  234. func (err Error) Error() string {
  235. pos := err.Pos
  236. if pos == "" {
  237. pos = "-" // like token.Position{}.String()
  238. }
  239. return pos + ": " + err.Msg
  240. }
  241. // flatPackage is the JSON form of Package
  242. // It drops all the type and syntax fields, and transforms the Imports
  243. //
  244. // TODO(adonovan): identify this struct with Package, effectively
  245. // publishing the JSON protocol.
  246. type flatPackage struct {
  247. ID string
  248. Name string `json:",omitempty"`
  249. PkgPath string `json:",omitempty"`
  250. Errors []Error `json:",omitempty"`
  251. GoFiles []string `json:",omitempty"`
  252. CompiledGoFiles []string `json:",omitempty"`
  253. OtherFiles []string `json:",omitempty"`
  254. ExportFile string `json:",omitempty"`
  255. Imports map[string]string `json:",omitempty"`
  256. }
  257. // MarshalJSON returns the Package in its JSON form.
  258. // For the most part, the structure fields are written out unmodified, and
  259. // the type and syntax fields are skipped.
  260. // The imports are written out as just a map of path to package id.
  261. // The errors are written using a custom type that tries to preserve the
  262. // structure of error types we know about.
  263. //
  264. // This method exists to enable support for additional build systems. It is
  265. // not intended for use by clients of the API and we may change the format.
  266. func (p *Package) MarshalJSON() ([]byte, error) {
  267. flat := &flatPackage{
  268. ID: p.ID,
  269. Name: p.Name,
  270. PkgPath: p.PkgPath,
  271. Errors: p.Errors,
  272. GoFiles: p.GoFiles,
  273. CompiledGoFiles: p.CompiledGoFiles,
  274. OtherFiles: p.OtherFiles,
  275. ExportFile: p.ExportFile,
  276. }
  277. if len(p.Imports) > 0 {
  278. flat.Imports = make(map[string]string, len(p.Imports))
  279. for path, ipkg := range p.Imports {
  280. flat.Imports[path] = ipkg.ID
  281. }
  282. }
  283. return json.Marshal(flat)
  284. }
  285. // UnmarshalJSON reads in a Package from its JSON format.
  286. // See MarshalJSON for details about the format accepted.
  287. func (p *Package) UnmarshalJSON(b []byte) error {
  288. flat := &flatPackage{}
  289. if err := json.Unmarshal(b, &flat); err != nil {
  290. return err
  291. }
  292. *p = Package{
  293. ID: flat.ID,
  294. Name: flat.Name,
  295. PkgPath: flat.PkgPath,
  296. Errors: flat.Errors,
  297. GoFiles: flat.GoFiles,
  298. CompiledGoFiles: flat.CompiledGoFiles,
  299. OtherFiles: flat.OtherFiles,
  300. ExportFile: flat.ExportFile,
  301. }
  302. if len(flat.Imports) > 0 {
  303. p.Imports = make(map[string]*Package, len(flat.Imports))
  304. for path, id := range flat.Imports {
  305. p.Imports[path] = &Package{ID: id}
  306. }
  307. }
  308. return nil
  309. }
  310. func (p *Package) String() string { return p.ID }
  311. // loaderPackage augments Package with state used during the loading phase
  312. type loaderPackage struct {
  313. *Package
  314. importErrors map[string]error // maps each bad import to its error
  315. loadOnce sync.Once
  316. color uint8 // for cycle detection
  317. needsrc bool // load from source (Mode >= LoadTypes)
  318. needtypes bool // type information is either requested or depended on
  319. initial bool // package was matched by a pattern
  320. }
  321. // loader holds the working state of a single call to load.
  322. type loader struct {
  323. pkgs map[string]*loaderPackage
  324. Config
  325. sizes types.Sizes
  326. exportMu sync.Mutex // enforces mutual exclusion of exportdata operations
  327. }
  328. func newLoader(cfg *Config) *loader {
  329. ld := &loader{}
  330. if cfg != nil {
  331. ld.Config = *cfg
  332. }
  333. if ld.Config.Env == nil {
  334. ld.Config.Env = os.Environ()
  335. }
  336. if ld.Context == nil {
  337. ld.Context = context.Background()
  338. }
  339. if ld.Dir == "" {
  340. if dir, err := os.Getwd(); err == nil {
  341. ld.Dir = dir
  342. }
  343. }
  344. if ld.Mode >= LoadTypes {
  345. if ld.Fset == nil {
  346. ld.Fset = token.NewFileSet()
  347. }
  348. // ParseFile is required even in LoadTypes mode
  349. // because we load source if export data is missing.
  350. if ld.ParseFile == nil {
  351. ld.ParseFile = func(fset *token.FileSet, filename string, src []byte) (*ast.File, error) {
  352. var isrc interface{}
  353. if src != nil {
  354. isrc = src
  355. }
  356. const mode = parser.AllErrors | parser.ParseComments
  357. return parser.ParseFile(fset, filename, isrc, mode)
  358. }
  359. }
  360. }
  361. return ld
  362. }
  363. // refine connects the supplied packages into a graph and then adds type and
  364. // and syntax information as requested by the LoadMode.
  365. func (ld *loader) refine(roots []string, list ...*Package) ([]*Package, error) {
  366. rootMap := make(map[string]int, len(roots))
  367. for i, root := range roots {
  368. rootMap[root] = i
  369. }
  370. ld.pkgs = make(map[string]*loaderPackage)
  371. // first pass, fixup and build the map and roots
  372. var initial = make([]*loaderPackage, len(roots))
  373. for _, pkg := range list {
  374. rootIndex := -1
  375. if i, found := rootMap[pkg.ID]; found {
  376. rootIndex = i
  377. }
  378. lpkg := &loaderPackage{
  379. Package: pkg,
  380. needtypes: ld.Mode >= LoadAllSyntax ||
  381. ld.Mode >= LoadTypes && rootIndex >= 0,
  382. needsrc: ld.Mode >= LoadAllSyntax ||
  383. ld.Mode >= LoadSyntax && rootIndex >= 0 ||
  384. len(ld.Overlay) > 0 || // Overlays can invalidate export data. TODO(matloob): make this check fine-grained based on dependencies on overlaid files
  385. pkg.ExportFile == "" && pkg.PkgPath != "unsafe",
  386. }
  387. ld.pkgs[lpkg.ID] = lpkg
  388. if rootIndex >= 0 {
  389. initial[rootIndex] = lpkg
  390. lpkg.initial = true
  391. }
  392. }
  393. for i, root := range roots {
  394. if initial[i] == nil {
  395. return nil, fmt.Errorf("root package %v is missing", root)
  396. }
  397. }
  398. // Materialize the import graph.
  399. const (
  400. white = 0 // new
  401. grey = 1 // in progress
  402. black = 2 // complete
  403. )
  404. // visit traverses the import graph, depth-first,
  405. // and materializes the graph as Packages.Imports.
  406. //
  407. // Valid imports are saved in the Packages.Import map.
  408. // Invalid imports (cycles and missing nodes) are saved in the importErrors map.
  409. // Thus, even in the presence of both kinds of errors, the Import graph remains a DAG.
  410. //
  411. // visit returns whether the package needs src or has a transitive
  412. // dependency on a package that does. These are the only packages
  413. // for which we load source code.
  414. var stack []*loaderPackage
  415. var visit func(lpkg *loaderPackage) bool
  416. var srcPkgs []*loaderPackage
  417. visit = func(lpkg *loaderPackage) bool {
  418. switch lpkg.color {
  419. case black:
  420. return lpkg.needsrc
  421. case grey:
  422. panic("internal error: grey node")
  423. }
  424. lpkg.color = grey
  425. stack = append(stack, lpkg) // push
  426. stubs := lpkg.Imports // the structure form has only stubs with the ID in the Imports
  427. lpkg.Imports = make(map[string]*Package, len(stubs))
  428. for importPath, ipkg := range stubs {
  429. var importErr error
  430. imp := ld.pkgs[ipkg.ID]
  431. if imp == nil {
  432. // (includes package "C" when DisableCgo)
  433. importErr = fmt.Errorf("missing package: %q", ipkg.ID)
  434. } else if imp.color == grey {
  435. importErr = fmt.Errorf("import cycle: %s", stack)
  436. }
  437. if importErr != nil {
  438. if lpkg.importErrors == nil {
  439. lpkg.importErrors = make(map[string]error)
  440. }
  441. lpkg.importErrors[importPath] = importErr
  442. continue
  443. }
  444. if visit(imp) {
  445. lpkg.needsrc = true
  446. }
  447. lpkg.Imports[importPath] = imp.Package
  448. }
  449. if lpkg.needsrc {
  450. srcPkgs = append(srcPkgs, lpkg)
  451. }
  452. stack = stack[:len(stack)-1] // pop
  453. lpkg.color = black
  454. return lpkg.needsrc
  455. }
  456. if ld.Mode < LoadImports {
  457. //we do this to drop the stub import packages that we are not even going to try to resolve
  458. for _, lpkg := range initial {
  459. lpkg.Imports = nil
  460. }
  461. } else {
  462. // For each initial package, create its import DAG.
  463. for _, lpkg := range initial {
  464. visit(lpkg)
  465. }
  466. }
  467. for _, lpkg := range srcPkgs {
  468. // Complete type information is required for the
  469. // immediate dependencies of each source package.
  470. for _, ipkg := range lpkg.Imports {
  471. imp := ld.pkgs[ipkg.ID]
  472. imp.needtypes = true
  473. }
  474. }
  475. // Load type data if needed, starting at
  476. // the initial packages (roots of the import DAG).
  477. if ld.Mode >= LoadTypes {
  478. var wg sync.WaitGroup
  479. for _, lpkg := range initial {
  480. wg.Add(1)
  481. go func(lpkg *loaderPackage) {
  482. ld.loadRecursive(lpkg)
  483. wg.Done()
  484. }(lpkg)
  485. }
  486. wg.Wait()
  487. }
  488. result := make([]*Package, len(initial))
  489. for i, lpkg := range initial {
  490. result[i] = lpkg.Package
  491. }
  492. return result, nil
  493. }
  494. // loadRecursive loads the specified package and its dependencies,
  495. // recursively, in parallel, in topological order.
  496. // It is atomic and idempotent.
  497. // Precondition: ld.Mode >= LoadTypes.
  498. func (ld *loader) loadRecursive(lpkg *loaderPackage) {
  499. lpkg.loadOnce.Do(func() {
  500. // Load the direct dependencies, in parallel.
  501. var wg sync.WaitGroup
  502. for _, ipkg := range lpkg.Imports {
  503. imp := ld.pkgs[ipkg.ID]
  504. wg.Add(1)
  505. go func(imp *loaderPackage) {
  506. ld.loadRecursive(imp)
  507. wg.Done()
  508. }(imp)
  509. }
  510. wg.Wait()
  511. ld.loadPackage(lpkg)
  512. })
  513. }
  514. // loadPackage loads the specified package.
  515. // It must be called only once per Package,
  516. // after immediate dependencies are loaded.
  517. // Precondition: ld.Mode >= LoadTypes.
  518. func (ld *loader) loadPackage(lpkg *loaderPackage) {
  519. if lpkg.PkgPath == "unsafe" {
  520. // Fill in the blanks to avoid surprises.
  521. lpkg.Types = types.Unsafe
  522. lpkg.Fset = ld.Fset
  523. lpkg.Syntax = []*ast.File{}
  524. lpkg.TypesInfo = new(types.Info)
  525. lpkg.TypesSizes = ld.sizes
  526. return
  527. }
  528. // Call NewPackage directly with explicit name.
  529. // This avoids skew between golist and go/types when the files'
  530. // package declarations are inconsistent.
  531. lpkg.Types = types.NewPackage(lpkg.PkgPath, lpkg.Name)
  532. lpkg.Fset = ld.Fset
  533. // Subtle: we populate all Types fields with an empty Package
  534. // before loading export data so that export data processing
  535. // never has to create a types.Package for an indirect dependency,
  536. // which would then require that such created packages be explicitly
  537. // inserted back into the Import graph as a final step after export data loading.
  538. // The Diamond test exercises this case.
  539. if !lpkg.needtypes {
  540. return
  541. }
  542. if !lpkg.needsrc {
  543. ld.loadFromExportData(lpkg)
  544. return // not a source package, don't get syntax trees
  545. }
  546. appendError := func(err error) {
  547. // Convert various error types into the one true Error.
  548. var errs []Error
  549. switch err := err.(type) {
  550. case Error:
  551. // from driver
  552. errs = append(errs, err)
  553. case *os.PathError:
  554. // from parser
  555. errs = append(errs, Error{
  556. Pos: err.Path + ":1",
  557. Msg: err.Err.Error(),
  558. Kind: ParseError,
  559. })
  560. case scanner.ErrorList:
  561. // from parser
  562. for _, err := range err {
  563. errs = append(errs, Error{
  564. Pos: err.Pos.String(),
  565. Msg: err.Msg,
  566. Kind: ParseError,
  567. })
  568. }
  569. case types.Error:
  570. // from type checker
  571. errs = append(errs, Error{
  572. Pos: err.Fset.Position(err.Pos).String(),
  573. Msg: err.Msg,
  574. Kind: TypeError,
  575. })
  576. default:
  577. // unexpected impoverished error from parser?
  578. errs = append(errs, Error{
  579. Pos: "-",
  580. Msg: err.Error(),
  581. Kind: UnknownError,
  582. })
  583. // If you see this error message, please file a bug.
  584. log.Printf("internal error: error %q (%T) without position", err, err)
  585. }
  586. lpkg.Errors = append(lpkg.Errors, errs...)
  587. }
  588. files, errs := ld.parseFiles(lpkg.CompiledGoFiles)
  589. for _, err := range errs {
  590. appendError(err)
  591. }
  592. lpkg.Syntax = files
  593. lpkg.TypesInfo = &types.Info{
  594. Types: make(map[ast.Expr]types.TypeAndValue),
  595. Defs: make(map[*ast.Ident]types.Object),
  596. Uses: make(map[*ast.Ident]types.Object),
  597. Implicits: make(map[ast.Node]types.Object),
  598. Scopes: make(map[ast.Node]*types.Scope),
  599. Selections: make(map[*ast.SelectorExpr]*types.Selection),
  600. }
  601. lpkg.TypesSizes = ld.sizes
  602. importer := importerFunc(func(path string) (*types.Package, error) {
  603. if path == "unsafe" {
  604. return types.Unsafe, nil
  605. }
  606. // The imports map is keyed by import path.
  607. ipkg := lpkg.Imports[path]
  608. if ipkg == nil {
  609. if err := lpkg.importErrors[path]; err != nil {
  610. return nil, err
  611. }
  612. // There was skew between the metadata and the
  613. // import declarations, likely due to an edit
  614. // race, or because the ParseFile feature was
  615. // used to supply alternative file contents.
  616. return nil, fmt.Errorf("no metadata for %s", path)
  617. }
  618. if ipkg.Types != nil && ipkg.Types.Complete() {
  619. return ipkg.Types, nil
  620. }
  621. log.Fatalf("internal error: nil Pkg importing %q from %q", path, lpkg)
  622. panic("unreachable")
  623. })
  624. // type-check
  625. tc := &types.Config{
  626. Importer: importer,
  627. // Type-check bodies of functions only in non-initial packages.
  628. // Example: for import graph A->B->C and initial packages {A,C},
  629. // we can ignore function bodies in B.
  630. IgnoreFuncBodies: ld.Mode < LoadAllSyntax && !lpkg.initial,
  631. Error: appendError,
  632. Sizes: ld.sizes,
  633. }
  634. types.NewChecker(tc, ld.Fset, lpkg.Types, lpkg.TypesInfo).Files(lpkg.Syntax)
  635. lpkg.importErrors = nil // no longer needed
  636. // If !Cgo, the type-checker uses FakeImportC mode, so
  637. // it doesn't invoke the importer for import "C",
  638. // nor report an error for the import,
  639. // or for any undefined C.f reference.
  640. // We must detect this explicitly and correctly
  641. // mark the package as IllTyped (by reporting an error).
  642. // TODO(adonovan): if these errors are annoying,
  643. // we could just set IllTyped quietly.
  644. if tc.FakeImportC {
  645. outer:
  646. for _, f := range lpkg.Syntax {
  647. for _, imp := range f.Imports {
  648. if imp.Path.Value == `"C"` {
  649. err := types.Error{Fset: ld.Fset, Pos: imp.Pos(), Msg: `import "C" ignored`}
  650. appendError(err)
  651. break outer
  652. }
  653. }
  654. }
  655. }
  656. // Record accumulated errors.
  657. illTyped := len(lpkg.Errors) > 0
  658. if !illTyped {
  659. for _, imp := range lpkg.Imports {
  660. if imp.IllTyped {
  661. illTyped = true
  662. break
  663. }
  664. }
  665. }
  666. lpkg.IllTyped = illTyped
  667. }
  668. // An importFunc is an implementation of the single-method
  669. // types.Importer interface based on a function value.
  670. type importerFunc func(path string) (*types.Package, error)
  671. func (f importerFunc) Import(path string) (*types.Package, error) { return f(path) }
  672. // We use a counting semaphore to limit
  673. // the number of parallel I/O calls per process.
  674. var ioLimit = make(chan bool, 20)
  675. // parseFiles reads and parses the Go source files and returns the ASTs
  676. // of the ones that could be at least partially parsed, along with a
  677. // list of I/O and parse errors encountered.
  678. //
  679. // Because files are scanned in parallel, the token.Pos
  680. // positions of the resulting ast.Files are not ordered.
  681. //
  682. func (ld *loader) parseFiles(filenames []string) ([]*ast.File, []error) {
  683. var wg sync.WaitGroup
  684. n := len(filenames)
  685. parsed := make([]*ast.File, n)
  686. errors := make([]error, n)
  687. for i, file := range filenames {
  688. if ld.Config.Context.Err() != nil {
  689. parsed[i] = nil
  690. errors[i] = ld.Config.Context.Err()
  691. continue
  692. }
  693. wg.Add(1)
  694. go func(i int, filename string) {
  695. ioLimit <- true // wait
  696. // ParseFile may return both an AST and an error.
  697. var src []byte
  698. for f, contents := range ld.Config.Overlay {
  699. if sameFile(f, filename) {
  700. src = contents
  701. }
  702. }
  703. var err error
  704. if src == nil {
  705. src, err = ioutil.ReadFile(filename)
  706. }
  707. if err != nil {
  708. parsed[i], errors[i] = nil, err
  709. } else {
  710. parsed[i], errors[i] = ld.ParseFile(ld.Fset, filename, src)
  711. }
  712. <-ioLimit // signal
  713. wg.Done()
  714. }(i, file)
  715. }
  716. wg.Wait()
  717. // Eliminate nils, preserving order.
  718. var o int
  719. for _, f := range parsed {
  720. if f != nil {
  721. parsed[o] = f
  722. o++
  723. }
  724. }
  725. parsed = parsed[:o]
  726. o = 0
  727. for _, err := range errors {
  728. if err != nil {
  729. errors[o] = err
  730. o++
  731. }
  732. }
  733. errors = errors[:o]
  734. return parsed, errors
  735. }
  736. // sameFile returns true if x and y have the same basename and denote
  737. // the same file.
  738. //
  739. func sameFile(x, y string) bool {
  740. if x == y {
  741. // It could be the case that y doesn't exist.
  742. // For instance, it may be an overlay file that
  743. // hasn't been written to disk. To handle that case
  744. // let x == y through. (We added the exact absolute path
  745. // string to the CompiledGoFiles list, so the unwritten
  746. // overlay case implies x==y.)
  747. return true
  748. }
  749. if strings.EqualFold(filepath.Base(x), filepath.Base(y)) { // (optimisation)
  750. if xi, err := os.Stat(x); err == nil {
  751. if yi, err := os.Stat(y); err == nil {
  752. return os.SameFile(xi, yi)
  753. }
  754. }
  755. }
  756. return false
  757. }
  758. // loadFromExportData returns type information for the specified
  759. // package, loading it from an export data file on the first request.
  760. func (ld *loader) loadFromExportData(lpkg *loaderPackage) (*types.Package, error) {
  761. if lpkg.PkgPath == "" {
  762. log.Fatalf("internal error: Package %s has no PkgPath", lpkg)
  763. }
  764. // Because gcexportdata.Read has the potential to create or
  765. // modify the types.Package for each node in the transitive
  766. // closure of dependencies of lpkg, all exportdata operations
  767. // must be sequential. (Finer-grained locking would require
  768. // changes to the gcexportdata API.)
  769. //
  770. // The exportMu lock guards the Package.Pkg field and the
  771. // types.Package it points to, for each Package in the graph.
  772. //
  773. // Not all accesses to Package.Pkg need to be protected by exportMu:
  774. // graph ordering ensures that direct dependencies of source
  775. // packages are fully loaded before the importer reads their Pkg field.
  776. ld.exportMu.Lock()
  777. defer ld.exportMu.Unlock()
  778. if tpkg := lpkg.Types; tpkg != nil && tpkg.Complete() {
  779. return tpkg, nil // cache hit
  780. }
  781. lpkg.IllTyped = true // fail safe
  782. if lpkg.ExportFile == "" {
  783. // Errors while building export data will have been printed to stderr.
  784. return nil, fmt.Errorf("no export data file")
  785. }
  786. f, err := os.Open(lpkg.ExportFile)
  787. if err != nil {
  788. return nil, err
  789. }
  790. defer f.Close()
  791. // Read gc export data.
  792. //
  793. // We don't currently support gccgo export data because all
  794. // underlying workspaces use the gc toolchain. (Even build
  795. // systems that support gccgo don't use it for workspace
  796. // queries.)
  797. r, err := gcexportdata.NewReader(f)
  798. if err != nil {
  799. return nil, fmt.Errorf("reading %s: %v", lpkg.ExportFile, err)
  800. }
  801. // Build the view.
  802. //
  803. // The gcexportdata machinery has no concept of package ID.
  804. // It identifies packages by their PkgPath, which although not
  805. // globally unique is unique within the scope of one invocation
  806. // of the linker, type-checker, or gcexportdata.
  807. //
  808. // So, we must build a PkgPath-keyed view of the global
  809. // (conceptually ID-keyed) cache of packages and pass it to
  810. // gcexportdata. The view must contain every existing
  811. // package that might possibly be mentioned by the
  812. // current package---its transitive closure.
  813. //
  814. // In loadPackage, we unconditionally create a types.Package for
  815. // each dependency so that export data loading does not
  816. // create new ones.
  817. //
  818. // TODO(adonovan): it would be simpler and more efficient
  819. // if the export data machinery invoked a callback to
  820. // get-or-create a package instead of a map.
  821. //
  822. view := make(map[string]*types.Package) // view seen by gcexportdata
  823. seen := make(map[*loaderPackage]bool) // all visited packages
  824. var visit func(pkgs map[string]*Package)
  825. visit = func(pkgs map[string]*Package) {
  826. for _, p := range pkgs {
  827. lpkg := ld.pkgs[p.ID]
  828. if !seen[lpkg] {
  829. seen[lpkg] = true
  830. view[lpkg.PkgPath] = lpkg.Types
  831. visit(lpkg.Imports)
  832. }
  833. }
  834. }
  835. visit(lpkg.Imports)
  836. viewLen := len(view) + 1 // adding the self package
  837. // Parse the export data.
  838. // (May modify incomplete packages in view but not create new ones.)
  839. tpkg, err := gcexportdata.Read(r, ld.Fset, view, lpkg.PkgPath)
  840. if err != nil {
  841. return nil, fmt.Errorf("reading %s: %v", lpkg.ExportFile, err)
  842. }
  843. if viewLen != len(view) {
  844. log.Fatalf("Unexpected package creation during export data loading")
  845. }
  846. lpkg.Types = tpkg
  847. lpkg.IllTyped = false
  848. return tpkg, nil
  849. }
  850. func usesExportData(cfg *Config) bool {
  851. return LoadTypes <= cfg.Mode && cfg.Mode < LoadAllSyntax
  852. }