...

Source file src/golang.org/x/tools/go/packages/packages.go

Documentation: golang.org/x/tools/go/packages

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

View as plain text