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