gopkg.in/alecthomas/gometalinter.v3@v3.0.0/_linters/src/golang.org/x/tools/go/packages/packages.go (about)

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