github.com/jhump/golang-x-tools@v0.0.0-20220218190644-4958d6d39439/go/packages/packages.go (about)

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