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