github.com/gernest/nezuko@v0.1.2/internal/load/pkg.go (about)

     1  // Copyright 2011 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 load loads packages.
     6  package load
     7  
     8  import (
     9  	"bytes"
    10  	"fmt"
    11  	"go/token"
    12  	"io/ioutil"
    13  	"os"
    14  	pathpkg "path"
    15  	"path/filepath"
    16  	"sort"
    17  	"strconv"
    18  	"strings"
    19  	"unicode"
    20  	"unicode/utf8"
    21  
    22  	"github.com/gernest/nezuko/internal/build"
    23  
    24  	"github.com/gernest/nezuko/internal/base"
    25  	"github.com/gernest/nezuko/internal/cfg"
    26  	"github.com/gernest/nezuko/internal/modinfo"
    27  	"github.com/gernest/nezuko/internal/search"
    28  	"github.com/gernest/nezuko/internal/str"
    29  )
    30  
    31  var (
    32  	// module initialization hook; never nil, no-op if module use is disabled
    33  	ModInit func()
    34  
    35  	// module hooks; nil if module use is disabled
    36  	ModBinDir            func() string                                       // return effective bin directory
    37  	ModLookup            func(path string) (dir, realPath string, err error) // lookup effective meaning of import
    38  	ModPackageModuleInfo func(path string) *modinfo.ModulePublic             // return module info for Package struct
    39  	ModImportPaths       func(args []string) []*search.Match                 // expand import paths
    40  	ModPackageBuildInfo  func(main string, deps []string) string             // return module info to embed in binary
    41  	ModInfoProg          func(info string) []byte                            // wrap module info in .go code for binary
    42  	ModImportFromFiles   func([]string)                                      // update z.mod to add modules for imports in these files
    43  	ModDirImportPath     func(string) string                                 // return effective import path for directory
    44  )
    45  
    46  var IgnoreImports bool // control whether we ignore imports in packages
    47  
    48  // A Package describes a single package found in a directory.
    49  type Package struct {
    50  	PackagePublic                 // visible in 'go list'
    51  	Internal      PackageInternal // for use inside go command only
    52  }
    53  
    54  type PackagePublic struct {
    55  	// Note: These fields are part of the go command's public API.
    56  	// See list.go. It is okay to add fields, but not to change or
    57  	// remove existing ones. Keep in sync with list.go
    58  	Dir           string                `json:",omitempty"` // directory containing package sources
    59  	ImportPath    string                `json:",omitempty"` // import path of package in dir
    60  	ImportComment string                `json:",omitempty"` // path in import comment on package statement
    61  	Name          string                `json:",omitempty"` // package name
    62  	Doc           string                `json:",omitempty"` // package documentation string
    63  	Target        string                `json:",omitempty"` // installed target for this package (may be executable)
    64  	Shlib         string                `json:",omitempty"` // the shared library that contains this package (only set when -linkshared)
    65  	Root          string                `json:",omitempty"` // Go root or Go path dir containing this package
    66  	ConflictDir   string                `json:",omitempty"` // Dir is hidden by this other directory
    67  	ForTest       string                `json:",omitempty"` // package is only for use in named test
    68  	Export        string                `json:",omitempty"` // file containing export data (set by go list -export)
    69  	Module        *modinfo.ModulePublic `json:",omitempty"` // info about package's module, if any
    70  	Match         []string              `json:",omitempty"` // command-line patterns matching this package
    71  	Goroot        bool                  `json:",omitempty"` // is this package found in the Go root?
    72  	Standard      bool                  `json:",omitempty"` // is this package part of the standard Go library?
    73  	DepOnly       bool                  `json:",omitempty"` // package is only as a dependency, not explicitly listed
    74  	BinaryOnly    bool                  `json:",omitempty"` // package cannot be recompiled
    75  	Incomplete    bool                  `json:",omitempty"` // was there an error loading this package or dependencies?
    76  
    77  	// Stale and StaleReason remain here *only* for the list command.
    78  	// They are only initialized in preparation for list execution.
    79  	// The regular build determines staleness on the fly during action execution.
    80  	Stale       bool   `json:",omitempty"` // would 'go install' do anything for this package?
    81  	StaleReason string `json:",omitempty"` // why is Stale true?
    82  
    83  	// Source files
    84  	// If you add to this list you MUST add to p.AllFiles (below) too.
    85  	// Otherwise file name security lists will not apply to any new additions.
    86  	GoFiles         []string `json:",omitempty"` // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles)
    87  	CgoFiles        []string `json:",omitempty"` // .go source files that import "C"
    88  	CompiledGoFiles []string `json:",omitempty"` // .go output from running cgo on CgoFiles
    89  	IgnoredGoFiles  []string `json:",omitempty"` // .go source files ignored due to build constraints
    90  	CFiles          []string `json:",omitempty"` // .c source files
    91  	CXXFiles        []string `json:",omitempty"` // .cc, .cpp and .cxx source files
    92  	MFiles          []string `json:",omitempty"` // .m source files
    93  	HFiles          []string `json:",omitempty"` // .h, .hh, .hpp and .hxx source files
    94  	FFiles          []string `json:",omitempty"` // .f, .F, .for and .f90 Fortran source files
    95  	SFiles          []string `json:",omitempty"` // .s source files
    96  	SwigFiles       []string `json:",omitempty"` // .swig files
    97  	SwigCXXFiles    []string `json:",omitempty"` // .swigcxx files
    98  	SysoFiles       []string `json:",omitempty"` // .syso system object files added to package
    99  
   100  	// Cgo directives
   101  	CgoCFLAGS    []string `json:",omitempty"` // cz: flags for C compiler
   102  	CgoCPPFLAGS  []string `json:",omitempty"` // cz: flags for C preprocessor
   103  	CgoCXXFLAGS  []string `json:",omitempty"` // cz: flags for C++ compiler
   104  	CgoFFLAGS    []string `json:",omitempty"` // cz: flags for Fortran compiler
   105  	CgoLDFLAGS   []string `json:",omitempty"` // cz: flags for linker
   106  	CgoPkgConfig []string `json:",omitempty"` // cz: pkg-config names
   107  
   108  	// Dependency information
   109  	Imports   []string          `json:",omitempty"` // import paths used by this package
   110  	ImportMap map[string]string `json:",omitempty"` // map from source import to ImportPath (identity entries omitted)
   111  	Deps      []string          `json:",omitempty"` // all (recursively) imported dependencies
   112  
   113  	// Error information
   114  	// Incomplete is above, packed into the other bools
   115  	Error      *PackageError   `json:",omitempty"` // error loading this package (not dependencies)
   116  	DepsErrors []*PackageError `json:",omitempty"` // errors loading dependencies
   117  
   118  	// Test information
   119  	// If you add to this list you MUST add to p.AllFiles (below) too.
   120  	// Otherwise file name security lists will not apply to any new additions.
   121  	TestGoFiles  []string `json:",omitempty"` // _test.go files in package
   122  	TestImports  []string `json:",omitempty"` // imports from TestGoFiles
   123  	XTestGoFiles []string `json:",omitempty"` // _test.go files outside package
   124  	XTestImports []string `json:",omitempty"` // imports from XTestGoFiles
   125  }
   126  
   127  // AllFiles returns the names of all the files considered for the package.
   128  // This is used for sanity and security checks, so we include all files,
   129  // even IgnoredGoFiles, because some subcommands consider them.
   130  // The go/build package filtered others out (like foo_wrongGOARCH.s)
   131  // and that's OK.
   132  func (p *Package) AllFiles() []string {
   133  	return str.StringList(
   134  		p.GoFiles,
   135  		p.CgoFiles,
   136  		// no p.CompiledGoFiles, because they are from GoFiles or generated by us
   137  		p.IgnoredGoFiles,
   138  		p.CFiles,
   139  		p.CXXFiles,
   140  		p.MFiles,
   141  		p.HFiles,
   142  		p.FFiles,
   143  		p.SFiles,
   144  		p.SwigFiles,
   145  		p.SwigCXXFiles,
   146  		p.SysoFiles,
   147  		p.TestGoFiles,
   148  		p.XTestGoFiles,
   149  	)
   150  }
   151  
   152  // Desc returns the package "description", for use in b.showOutput.
   153  func (p *Package) Desc() string {
   154  	if p.ForTest != "" {
   155  		return p.ImportPath + " [" + p.ForTest + ".test]"
   156  	}
   157  	return p.ImportPath
   158  }
   159  
   160  type PackageInternal struct {
   161  	// Unexported fields are not part of the public API.
   162  	Build             *build.Package
   163  	Imports           []*Package           // this package's direct imports
   164  	CompiledImports   []string             // additional Imports necessary when using CompiledGoFiles (all from standard library)
   165  	RawImports        []string             // this package's original imports as they appear in the text of the program
   166  	ForceLibrary      bool                 // this package is a library (even if named "main")
   167  	CmdlineFiles      bool                 // package built from files listed on command line
   168  	CmdlinePkg        bool                 // package listed on command line
   169  	CmdlinePkgLiteral bool                 // package listed as literal on command line (not via wildcard)
   170  	Local             bool                 // imported via local path (./ or ../)
   171  	LocalPrefix       string               // interpret ./ and ../ imports relative to this prefix
   172  	ExeName           string               // desired name for temporary executable
   173  	CoverMode         string               // preprocess Go source files with the coverage tool in this mode
   174  	CoverVars         map[string]*CoverVar // variables created by coverage analysis
   175  	OmitDebug         bool                 // tell linker not to write debug information
   176  	GobinSubdir       bool                 // install target would be subdir of GOBIN
   177  	BuildInfo         string               // add this info to package main
   178  	TestmainGo        *[]byte              // content for _testmain.go
   179  
   180  	Asmflags   []string // -asmflags for this package
   181  	Gcflags    []string // -gcflags for this package
   182  	Ldflags    []string // -ldflags for this package
   183  	Gccgoflags []string // -gccgoflags for this package
   184  }
   185  
   186  type NoGoError struct {
   187  	Package *Package
   188  }
   189  
   190  func (e *NoGoError) Error() string {
   191  	// Count files beginning with _ and ., which we will pretend don't exist at all.
   192  	dummy := 0
   193  	for _, name := range e.Package.IgnoredGoFiles {
   194  		if strings.HasPrefix(name, "_") || strings.HasPrefix(name, ".") {
   195  			dummy++
   196  		}
   197  	}
   198  
   199  	if len(e.Package.IgnoredGoFiles) > dummy {
   200  		// Go files exist, but they were ignored due to build constraints.
   201  		return "build constraints exclude all Go files in " + e.Package.Dir
   202  	}
   203  	if len(e.Package.TestGoFiles)+len(e.Package.XTestGoFiles) > 0 {
   204  		// Test Go files exist, but we're not interested in them.
   205  		// The double-negative is unfortunate but we want e.Package.Dir
   206  		// to appear at the end of error message.
   207  		return "no non-test Go files in " + e.Package.Dir
   208  	}
   209  	return "no Go files in " + e.Package.Dir
   210  }
   211  
   212  // Resolve returns the resolved version of imports,
   213  // which should be p.TestImports or p.XTestImports, NOT p.Imports.
   214  // The imports in p.TestImports and p.XTestImports are not recursively
   215  // loaded during the initial load of p, so they list the imports found in
   216  // the source file, but most processing should be over the vendor-resolved
   217  // import paths. We do this resolution lazily both to avoid file system work
   218  // and because the eventual real load of the test imports (during 'go test')
   219  // can produce better error messages if it starts with the original paths.
   220  // The initial load of p loads all the non-test imports and rewrites
   221  // the vendored paths, so nothing should ever call p.vendored(p.Imports).
   222  func (p *Package) Resolve(imports []string) []string {
   223  	if len(imports) > 0 && len(p.Imports) > 0 && &imports[0] == &p.Imports[0] {
   224  		panic("internal error: p.Resolve(p.Imports) called")
   225  	}
   226  	seen := make(map[string]bool)
   227  	var all []string
   228  	for _, path := range imports {
   229  		path = ResolveImportPath(p, path)
   230  		if !seen[path] {
   231  			seen[path] = true
   232  			all = append(all, path)
   233  		}
   234  	}
   235  	sort.Strings(all)
   236  	return all
   237  }
   238  
   239  // CoverVar holds the name of the generated coverage variables targeting the named file.
   240  type CoverVar struct {
   241  	File string // local file name
   242  	Var  string // name of count struct
   243  }
   244  
   245  func (p *Package) copyBuild(pp *build.Package) {
   246  	p.Internal.Build = pp
   247  
   248  	p.Dir = pp.Dir
   249  	p.ImportPath = pp.ImportPath
   250  	p.ImportComment = pp.ImportComment
   251  	p.Name = pp.Name
   252  	p.Doc = pp.Doc
   253  	p.Root = pp.Root
   254  
   255  	p.Standard = p.Goroot && p.ImportPath != "" && search.IsStandardImportPath(p.ImportPath)
   256  	p.GoFiles = pp.GoFiles
   257  	// We modify p.Imports in place, so make copy now.
   258  	p.Imports = make([]string, len(pp.Imports))
   259  	copy(p.Imports, pp.Imports)
   260  	p.Internal.RawImports = pp.Imports
   261  	if IgnoreImports {
   262  		p.Imports = nil
   263  		p.Internal.RawImports = nil
   264  		p.TestImports = nil
   265  		p.XTestImports = nil
   266  	}
   267  }
   268  
   269  // A PackageError describes an error loading information about a package.
   270  type PackageError struct {
   271  	ImportStack   []string // shortest path from package named on command line to this one
   272  	Pos           string   // position of error
   273  	Err           string   // the error itself
   274  	IsImportCycle bool     `json:"-"` // the error is an import cycle
   275  	Hard          bool     `json:"-"` // whether the error is soft or hard; soft errors are ignored in some places
   276  }
   277  
   278  func (p *PackageError) Error() string {
   279  	// Import cycles deserve special treatment.
   280  	if p.IsImportCycle {
   281  		return fmt.Sprintf("%s\npackage %s\n", p.Err, strings.Join(p.ImportStack, "\n\timports "))
   282  	}
   283  	if p.Pos != "" {
   284  		// Omit import stack. The full path to the file where the error
   285  		// is the most important thing.
   286  		return p.Pos + ": " + p.Err
   287  	}
   288  	if len(p.ImportStack) == 0 {
   289  		return p.Err
   290  	}
   291  	return "package " + strings.Join(p.ImportStack, "\n\timports ") + ": " + p.Err
   292  }
   293  
   294  // An ImportStack is a stack of import paths, possibly with the suffix " (test)" appended.
   295  // The import path of a test package is the import path of the corresponding
   296  // non-test package with the suffix "_test" added.
   297  type ImportStack []string
   298  
   299  func (s *ImportStack) Push(p string) {
   300  	*s = append(*s, p)
   301  }
   302  
   303  func (s *ImportStack) Pop() {
   304  	*s = (*s)[0 : len(*s)-1]
   305  }
   306  
   307  func (s *ImportStack) Copy() []string {
   308  	return append([]string{}, *s...)
   309  }
   310  
   311  // shorterThan reports whether sp is shorter than t.
   312  // We use this to record the shortest import sequence
   313  // that leads to a particular package.
   314  func (sp *ImportStack) shorterThan(t []string) bool {
   315  	s := *sp
   316  	if len(s) != len(t) {
   317  		return len(s) < len(t)
   318  	}
   319  	// If they are the same length, settle ties using string ordering.
   320  	for i := range s {
   321  		if s[i] != t[i] {
   322  			return s[i] < t[i]
   323  		}
   324  	}
   325  	return false // they are equal
   326  }
   327  
   328  // packageCache is a lookup cache for loadPackage,
   329  // so that if we look up a package multiple times
   330  // we return the same pointer each time.
   331  var packageCache = map[string]*Package{}
   332  
   333  func ClearPackageCache() {
   334  	for name := range packageCache {
   335  		delete(packageCache, name)
   336  	}
   337  }
   338  
   339  func ClearPackageCachePartial(args []string) {
   340  	for _, arg := range args {
   341  		p := packageCache[arg]
   342  		if p != nil {
   343  			delete(packageCache, p.Dir)
   344  			delete(packageCache, p.ImportPath)
   345  		}
   346  	}
   347  }
   348  
   349  // dirToImportPath returns the pseudo-import path we use for a package
   350  // outside the Go path. It begins with _/ and then contains the full path
   351  // to the directory. If the package lives in c:\home\gopher\my\pkg then
   352  // the pseudo-import path is _/c_/home/gopher/my/pkg.
   353  // Using a pseudo-import path like this makes the ./ imports no longer
   354  // a special case, so that all the code to deal with ordinary imports works
   355  // automatically.
   356  func dirToImportPath(dir string) string {
   357  	return pathpkg.Join("_", strings.Map(makeImportValid, filepath.ToSlash(dir)))
   358  }
   359  
   360  func makeImportValid(r rune) rune {
   361  	// Should match Go spec, compilers, and ../../go/parser/parser.go:/isValidImport.
   362  	const illegalChars = `!"#$%&'()*,:;<=>?[\]^{|}` + "`\uFFFD"
   363  	if !unicode.IsGraphic(r) || unicode.IsSpace(r) || strings.ContainsRune(illegalChars, r) {
   364  		return '_'
   365  	}
   366  	return r
   367  }
   368  
   369  // Mode flags for loadImport and download (in get.go).
   370  const (
   371  	// ResolveImport means that loadImport should do import path expansion.
   372  	// That is, ResolveImport means that the import path came from
   373  	// a source file and has not been expanded yet to account for
   374  	// vendoring or possible module adjustment.
   375  	// Every import path should be loaded initially with ResolveImport,
   376  	// and then the expanded version (for example with the /vendor/ in it)
   377  	// gets recorded as the canonical import path. At that point, future loads
   378  	// of that package must not pass ResolveImport, because
   379  	// disallowVendor will reject direct use of paths containing /vendor/.
   380  	ResolveImport = 1 << iota
   381  
   382  	// ResolveModule is for download (part of "go get") and indicates
   383  	// that the module adjustment should be done, but not vendor adjustment.
   384  	ResolveModule
   385  
   386  	// GetTestDeps is for download (part of "go get") and indicates
   387  	// that test dependencies should be fetched too.
   388  	GetTestDeps
   389  )
   390  
   391  // LoadImport scans the directory named by path, which must be an import path,
   392  // but possibly a local import path (an absolute file system path or one beginning
   393  // with ./ or ../). A local relative path is interpreted relative to srcDir.
   394  // It returns a *Package describing the package found in that directory.
   395  // LoadImport does not set tool flags and should only be used by
   396  // this package, as part of a bigger load operation, and by GOPATH-based "go get".
   397  // TODO(rsc): When GOPATH-based "go get" is removed, unexport this function.
   398  func LoadImport(path, srcDir string, parent *Package, stk *ImportStack, importPos []token.Position, mode int) *Package {
   399  	if path == "" {
   400  		panic("LoadImport called with empty package path")
   401  	}
   402  
   403  	stk.Push(path)
   404  	defer stk.Pop()
   405  
   406  	if strings.HasPrefix(path, "mod/") {
   407  		// Paths beginning with "mod/" might accidentally
   408  		// look in the module cache directory tree in $GOPATH/pkg/mod/.
   409  		// This prefix is owned by the Go core for possible use in the
   410  		// standard library (since it does not begin with a domain name),
   411  		// so it's OK to disallow entirely.
   412  		return &Package{
   413  			PackagePublic: PackagePublic{
   414  				ImportPath: path,
   415  				Error: &PackageError{
   416  					ImportStack: stk.Copy(),
   417  					Err:         fmt.Sprintf("disallowed import path %q", path),
   418  				},
   419  			},
   420  		}
   421  	}
   422  
   423  	if strings.Contains(path, "@") {
   424  		var text string
   425  		if cfg.ModulesEnabled {
   426  			text = "can only use path@version syntax with 'go get'"
   427  		} else {
   428  			text = "cannot use path@version syntax in GOPATH mode"
   429  		}
   430  		return &Package{
   431  			PackagePublic: PackagePublic{
   432  				ImportPath: path,
   433  				Error: &PackageError{
   434  					ImportStack: stk.Copy(),
   435  					Err:         text,
   436  				},
   437  			},
   438  		}
   439  	}
   440  
   441  	parentPath := ""
   442  	if parent != nil {
   443  		parentPath = parent.ImportPath
   444  	}
   445  
   446  	// Determine canonical identifier for this package.
   447  	// For a local import the identifier is the pseudo-import path
   448  	// we create from the full directory to the package.
   449  	// Otherwise it is the usual import path.
   450  	// For vendored imports, it is the expanded form.
   451  	importPath := path
   452  	origPath := path
   453  	isLocal := build.IsLocalImport(path)
   454  	var modDir string
   455  	var modErr error
   456  	if isLocal {
   457  		importPath = dirToImportPath(filepath.Join(srcDir, path))
   458  	} else if cfg.ModulesEnabled {
   459  		var p string
   460  		modDir, p, modErr = ModLookup(path)
   461  		if modErr == nil {
   462  			importPath = p
   463  		}
   464  	} else if mode&ResolveImport != 0 {
   465  		// We do our own path resolution, because we want to
   466  		// find out the key to use in packageCache without the
   467  		// overhead of repeated calls to buildContext.Import.
   468  		// The code is also needed in a few other places anyway.
   469  		path = ResolveImportPath(parent, path)
   470  		importPath = path
   471  	} else if mode&ResolveModule != 0 {
   472  		path = ModuleImportPath(parent, path)
   473  		importPath = path
   474  	}
   475  
   476  	p := packageCache[importPath]
   477  	if p != nil {
   478  		p = reusePackage(p, stk)
   479  	} else {
   480  		p = new(Package)
   481  		p.Internal.Local = isLocal
   482  		p.ImportPath = importPath
   483  		packageCache[importPath] = p
   484  
   485  		// Load package.
   486  		// Import always returns bp != nil, even if an error occurs,
   487  		// in order to return partial information.
   488  		var bp *build.Package
   489  		var err error
   490  		if modDir != "" {
   491  			bp, err = cfg.BuildContext.ImportDir(modDir, 0)
   492  		} else if modErr != nil {
   493  			bp = new(build.Package)
   494  			err = fmt.Errorf("unknown import path %q: %v", importPath, modErr)
   495  		} else if cfg.ModulesEnabled && path != "unsafe" {
   496  			bp = new(build.Package)
   497  			err = fmt.Errorf("unknown import path %q: internal error: module loader did not resolve import", importPath)
   498  		} else {
   499  			buildMode := build.ImportComment
   500  			if mode&ResolveImport == 0 || path != origPath {
   501  				// Not vendoring, or we already found the vendored path.
   502  				buildMode |= build.IgnoreVendor
   503  			}
   504  			bp, err = cfg.BuildContext.Import(path, srcDir, buildMode)
   505  		}
   506  		bp.ImportPath = importPath
   507  		if modDir == "" && err == nil && !isLocal && bp.ImportComment != "" && bp.ImportComment != path &&
   508  			!strings.Contains(path, "/vendor/") && !strings.HasPrefix(path, "vendor/") {
   509  			err = fmt.Errorf("code in directory %s expects import %q", bp.Dir, bp.ImportComment)
   510  		}
   511  		p.load(stk, bp, err)
   512  		if p.Error != nil && p.Error.Pos == "" {
   513  			p = setErrorPos(p, importPos)
   514  		}
   515  
   516  		if modDir == "" && origPath != cleanImport(origPath) {
   517  			p.Error = &PackageError{
   518  				ImportStack: stk.Copy(),
   519  				Err:         fmt.Sprintf("non-canonical import path: %q should be %q", origPath, pathpkg.Clean(origPath)),
   520  			}
   521  			p.Incomplete = true
   522  		}
   523  	}
   524  
   525  	// Checked on every import because the rules depend on the code doing the importing.
   526  	if perr := disallowInternal(srcDir, parent, parentPath, p, stk); perr != p {
   527  		return setErrorPos(perr, importPos)
   528  	}
   529  	if mode&ResolveImport != 0 {
   530  		if perr := disallowVendor(srcDir, parent, parentPath, origPath, p, stk); perr != p {
   531  			return setErrorPos(perr, importPos)
   532  		}
   533  	}
   534  
   535  	if p.Name == "main" && parent != nil && parent.Dir != p.Dir {
   536  		perr := *p
   537  		perr.Error = &PackageError{
   538  			ImportStack: stk.Copy(),
   539  			Err:         fmt.Sprintf("import %q is a program, not an importable package", path),
   540  		}
   541  		return setErrorPos(&perr, importPos)
   542  	}
   543  
   544  	if p.Internal.Local && parent != nil && !parent.Internal.Local {
   545  		perr := *p
   546  		perr.Error = &PackageError{
   547  			ImportStack: stk.Copy(),
   548  			Err:         fmt.Sprintf("local import %q in non-local package", path),
   549  		}
   550  		return setErrorPos(&perr, importPos)
   551  	}
   552  
   553  	return p
   554  }
   555  
   556  func setErrorPos(p *Package, importPos []token.Position) *Package {
   557  	if len(importPos) > 0 {
   558  		pos := importPos[0]
   559  		pos.Filename = base.ShortPath(pos.Filename)
   560  		p.Error.Pos = pos.String()
   561  	}
   562  	return p
   563  }
   564  
   565  func cleanImport(path string) string {
   566  	orig := path
   567  	path = pathpkg.Clean(path)
   568  	if strings.HasPrefix(orig, "./") && path != ".." && !strings.HasPrefix(path, "../") {
   569  		path = "./" + path
   570  	}
   571  	return path
   572  }
   573  
   574  var isDirCache = map[string]bool{}
   575  
   576  func isDir(path string) bool {
   577  	result, ok := isDirCache[path]
   578  	if ok {
   579  		return result
   580  	}
   581  
   582  	fi, err := os.Stat(path)
   583  	result = err == nil && fi.IsDir()
   584  	isDirCache[path] = result
   585  	return result
   586  }
   587  
   588  // ResolveImportPath returns the true meaning of path when it appears in parent.
   589  // There are two different resolutions applied.
   590  // First, there is Go 1.5 vendoring (golang.org/s/go15vendor).
   591  // If vendor expansion doesn't trigger, then the path is also subject to
   592  // Go 1.11 module legacy conversion (golang.org/issue/25069).
   593  func ResolveImportPath(parent *Package, path string) (found string) {
   594  	if cfg.ModulesEnabled {
   595  		if _, p, e := ModLookup(path); e == nil {
   596  			return p
   597  		}
   598  		return path
   599  	}
   600  	found = VendoredImportPath(parent, path)
   601  	if found != path {
   602  		return found
   603  	}
   604  	return ModuleImportPath(parent, path)
   605  }
   606  
   607  // dirAndRoot returns the source directory and workspace root
   608  // for the package p, guaranteeing that root is a path prefix of dir.
   609  func dirAndRoot(p *Package) (dir, root string) {
   610  	dir = filepath.Clean(p.Dir)
   611  	root = filepath.Join(p.Root, "src")
   612  	if !str.HasFilePathPrefix(dir, root) || p.ImportPath != "command-line-arguments" && filepath.Join(root, p.ImportPath) != dir {
   613  		// Look for symlinks before reporting error.
   614  		dir = expandPath(dir)
   615  		root = expandPath(root)
   616  	}
   617  
   618  	if !str.HasFilePathPrefix(dir, root) || len(dir) <= len(root) || dir[len(root)] != filepath.Separator || p.ImportPath != "command-line-arguments" && !p.Internal.Local && filepath.Join(root, p.ImportPath) != dir {
   619  		base.Fatalf("unexpected directory layout:\n"+
   620  			"	import path: %s\n"+
   621  			"	root: %s\n"+
   622  			"	dir: %s\n"+
   623  			"	expand root: %s\n"+
   624  			"	expand dir: %s\n"+
   625  			"	separator: %s",
   626  			p.ImportPath,
   627  			filepath.Join(p.Root, "src"),
   628  			filepath.Clean(p.Dir),
   629  			root,
   630  			dir,
   631  			string(filepath.Separator))
   632  	}
   633  
   634  	return dir, root
   635  }
   636  
   637  // VendoredImportPath returns the vendor-expansion of path when it appears in parent.
   638  // If parent is x/y/z, then path might expand to x/y/z/vendor/path, x/y/vendor/path,
   639  // x/vendor/path, vendor/path, or else stay path if none of those exist.
   640  // VendoredImportPath returns the expanded path or, if no expansion is found, the original.
   641  func VendoredImportPath(parent *Package, path string) (found string) {
   642  	if parent == nil || parent.Root == "" {
   643  		return path
   644  	}
   645  
   646  	dir, root := dirAndRoot(parent)
   647  
   648  	vpath := "vendor/" + path
   649  	for i := len(dir); i >= len(root); i-- {
   650  		if i < len(dir) && dir[i] != filepath.Separator {
   651  			continue
   652  		}
   653  		// Note: checking for the vendor directory before checking
   654  		// for the vendor/path directory helps us hit the
   655  		// isDir cache more often. It also helps us prepare a more useful
   656  		// list of places we looked, to report when an import is not found.
   657  		if !isDir(filepath.Join(dir[:i], "vendor")) {
   658  			continue
   659  		}
   660  		targ := filepath.Join(dir[:i], vpath)
   661  		if isDir(targ) && hasGoFiles(targ) {
   662  			importPath := parent.ImportPath
   663  			if importPath == "command-line-arguments" {
   664  				// If parent.ImportPath is 'command-line-arguments'.
   665  				// set to relative directory to root (also chopped root directory)
   666  				importPath = dir[len(root)+1:]
   667  			}
   668  			// We started with parent's dir c:\gopath\src\foo\bar\baz\quux\xyzzy.
   669  			// We know the import path for parent's dir.
   670  			// We chopped off some number of path elements and
   671  			// added vendor\path to produce c:\gopath\src\foo\bar\baz\vendor\path.
   672  			// Now we want to know the import path for that directory.
   673  			// Construct it by chopping the same number of path elements
   674  			// (actually the same number of bytes) from parent's import path
   675  			// and then append /vendor/path.
   676  			chopped := len(dir) - i
   677  			if chopped == len(importPath)+1 {
   678  				// We walked up from c:\gopath\src\foo\bar
   679  				// and found c:\gopath\src\vendor\path.
   680  				// We chopped \foo\bar (length 8) but the import path is "foo/bar" (length 7).
   681  				// Use "vendor/path" without any prefix.
   682  				return vpath
   683  			}
   684  			return importPath[:len(importPath)-chopped] + "/" + vpath
   685  		}
   686  	}
   687  	return path
   688  }
   689  
   690  var (
   691  	modulePrefix   = []byte("\nmodule ")
   692  	goModPathCache = make(map[string]string)
   693  )
   694  
   695  // goModPath returns the module path in the z.mod in dir, if any.
   696  func goModPath(dir string) (path string) {
   697  	path, ok := goModPathCache[dir]
   698  	if ok {
   699  		return path
   700  	}
   701  	defer func() {
   702  		goModPathCache[dir] = path
   703  	}()
   704  
   705  	data, err := ioutil.ReadFile(filepath.Join(dir, "z.mod"))
   706  	if err != nil {
   707  		return ""
   708  	}
   709  	var i int
   710  	if bytes.HasPrefix(data, modulePrefix[1:]) {
   711  		i = 0
   712  	} else {
   713  		i = bytes.Index(data, modulePrefix)
   714  		if i < 0 {
   715  			return ""
   716  		}
   717  		i++
   718  	}
   719  	line := data[i:]
   720  
   721  	// Cut line at \n, drop trailing \r if present.
   722  	if j := bytes.IndexByte(line, '\n'); j >= 0 {
   723  		line = line[:j]
   724  	}
   725  	if line[len(line)-1] == '\r' {
   726  		line = line[:len(line)-1]
   727  	}
   728  	line = line[len("module "):]
   729  
   730  	// If quoted, unquote.
   731  	path = strings.TrimSpace(string(line))
   732  	if path != "" && path[0] == '"' {
   733  		s, err := strconv.Unquote(path)
   734  		if err != nil {
   735  			return ""
   736  		}
   737  		path = s
   738  	}
   739  	return path
   740  }
   741  
   742  // findVersionElement returns the slice indices of the final version element /vN in path.
   743  // If there is no such element, it returns -1, -1.
   744  func findVersionElement(path string) (i, j int) {
   745  	j = len(path)
   746  	for i = len(path) - 1; i >= 0; i-- {
   747  		if path[i] == '/' {
   748  			if isVersionElement(path[i:j]) {
   749  				return i, j
   750  			}
   751  			j = i
   752  		}
   753  	}
   754  	return -1, -1
   755  }
   756  
   757  // isVersionElement reports whether s is a well-formed path version element:
   758  // v2, v3, v10, etc, but not v0, v05, v1.
   759  func isVersionElement(s string) bool {
   760  	if len(s) < 3 || s[0] != '/' || s[1] != 'v' || s[2] == '0' || s[2] == '1' && len(s) == 3 {
   761  		return false
   762  	}
   763  	for i := 2; i < len(s); i++ {
   764  		if s[i] < '0' || '9' < s[i] {
   765  			return false
   766  		}
   767  	}
   768  	return true
   769  }
   770  
   771  // ModuleImportPath translates import paths found in z modules
   772  // back down to paths that can be resolved in ordinary builds.
   773  //
   774  // Define “new” code as code with a z.mod file in the same directory
   775  // or a parent directory. If an import in new code says x/y/v2/z but
   776  // x/y/v2/z does not exist and x/y/z.mod says “module x/y/v2”,
   777  // then go build will read the import as x/y/z instead.
   778  // See golang.org/issue/25069.
   779  func ModuleImportPath(parent *Package, path string) (found string) {
   780  	if parent == nil || parent.Root == "" {
   781  		return path
   782  	}
   783  
   784  	// If there are no vN elements in path, leave it alone.
   785  	// (The code below would do the same, but only after
   786  	// some other file system accesses that we can avoid
   787  	// here by returning early.)
   788  	if i, _ := findVersionElement(path); i < 0 {
   789  		return path
   790  	}
   791  
   792  	dir, root := dirAndRoot(parent)
   793  
   794  	// Consider dir and parents, up to and including root.
   795  	for i := len(dir); i >= len(root); i-- {
   796  		if i < len(dir) && dir[i] != filepath.Separator {
   797  			continue
   798  		}
   799  		if goModPath(dir[:i]) != "" {
   800  			goto HaveGoMod
   801  		}
   802  	}
   803  	// This code is not in a tree with a z.mod,
   804  	// so apply no changes to the path.
   805  	return path
   806  
   807  HaveGoMod:
   808  	// This import is in a tree with a z.mod.
   809  	// Allow it to refer to code in GOPATH/src/x/y/z as x/y/v2/z
   810  	// if GOPATH/src/x/y/z.mod says module "x/y/v2",
   811  
   812  	// If x/y/v2/z exists, use it unmodified.
   813  	if bp, _ := cfg.BuildContext.Import(path, "", build.IgnoreVendor); bp.Dir != "" {
   814  		return path
   815  	}
   816  
   817  	// Otherwise look for a z.mod supplying a version element.
   818  	// Some version-like elements may appear in paths but not
   819  	// be module versions; we skip over those to look for module
   820  	// versions. For example the module m/v2 might have a
   821  	// package m/v2/api/v1/foo.
   822  	limit := len(path)
   823  	for limit > 0 {
   824  		i, j := findVersionElement(path[:limit])
   825  		if i < 0 {
   826  			return path
   827  		}
   828  		if bp, _ := cfg.BuildContext.Import(path[:i], "", build.IgnoreVendor); bp.Dir != "" {
   829  			if mpath := goModPath(bp.Dir); mpath != "" {
   830  				// Found a valid z.mod file, so we're stopping the search.
   831  				// If the path is m/v2/p and we found m/z.mod that says
   832  				// "module m/v2", then we return "m/p".
   833  				if mpath == path[:j] {
   834  					return path[:i] + path[j:]
   835  				}
   836  				// Otherwise just return the original path.
   837  				// We didn't find anything worth rewriting,
   838  				// and the z.mod indicates that we should
   839  				// not consider parent directories.
   840  				return path
   841  			}
   842  		}
   843  		limit = i
   844  	}
   845  	return path
   846  }
   847  
   848  // hasGoFiles reports whether dir contains any files with names ending in .go.
   849  // For a vendor check we must exclude directories that contain no .go files.
   850  // Otherwise it is not possible to vendor just a/b/c and still import the
   851  // non-vendored a/b. See golang.org/issue/13832.
   852  func hasGoFiles(dir string) bool {
   853  	fis, _ := ioutil.ReadDir(dir)
   854  	for _, fi := range fis {
   855  		if !fi.IsDir() && strings.HasSuffix(fi.Name(), ".go") {
   856  			return true
   857  		}
   858  	}
   859  	return false
   860  }
   861  
   862  // reusePackage reuses package p to satisfy the import at the top
   863  // of the import stack stk. If this use causes an import loop,
   864  // reusePackage updates p's error information to record the loop.
   865  func reusePackage(p *Package, stk *ImportStack) *Package {
   866  	// We use p.Internal.Imports==nil to detect a package that
   867  	// is in the midst of its own loadPackage call
   868  	// (all the recursion below happens before p.Internal.Imports gets set).
   869  	if p.Internal.Imports == nil {
   870  		if p.Error == nil {
   871  			p.Error = &PackageError{
   872  				ImportStack:   stk.Copy(),
   873  				Err:           "import cycle not allowed",
   874  				IsImportCycle: true,
   875  			}
   876  		}
   877  		p.Incomplete = true
   878  	}
   879  	// Don't rewrite the import stack in the error if we have an import cycle.
   880  	// If we do, we'll lose the path that describes the cycle.
   881  	if p.Error != nil && !p.Error.IsImportCycle && stk.shorterThan(p.Error.ImportStack) {
   882  		p.Error.ImportStack = stk.Copy()
   883  	}
   884  	return p
   885  }
   886  
   887  // disallowInternal checks that srcDir (containing package importerPath, if non-empty)
   888  // is allowed to import p.
   889  // If the import is allowed, disallowInternal returns the original package p.
   890  // If not, it returns a new package containing just an appropriate error.
   891  func disallowInternal(srcDir string, importer *Package, importerPath string, p *Package, stk *ImportStack) *Package {
   892  	// golang.org/s/go14internal:
   893  	// An import of a path containing the element “internal”
   894  	// is disallowed if the importing code is outside the tree
   895  	// rooted at the parent of the “internal” directory.
   896  
   897  	// There was an error loading the package; stop here.
   898  	if p.Error != nil {
   899  		return p
   900  	}
   901  
   902  	// The generated 'testmain' package is allowed to access testing/internal/...,
   903  	// as if it were generated into the testing directory tree
   904  	// (it's actually in a temporary directory outside any Go tree).
   905  	// This cleans up a former kludge in passing functionality to the testing package.
   906  	if strings.HasPrefix(p.ImportPath, "testing/internal") && len(*stk) >= 2 && (*stk)[len(*stk)-2] == "testmain" {
   907  		return p
   908  	}
   909  
   910  	// The stack includes p.ImportPath.
   911  	// If that's the only thing on the stack, we started
   912  	// with a name given on the command line, not an
   913  	// import. Anything listed on the command line is fine.
   914  	if len(*stk) == 1 {
   915  		return p
   916  	}
   917  
   918  	// Check for "internal" element: three cases depending on begin of string and/or end of string.
   919  	i, ok := findInternal(p.ImportPath)
   920  	if !ok {
   921  		return p
   922  	}
   923  
   924  	// Internal is present.
   925  	// Map import path back to directory corresponding to parent of internal.
   926  	if i > 0 {
   927  		i-- // rewind over slash in ".../internal"
   928  	}
   929  
   930  	if p.Module == nil {
   931  		parent := p.Dir[:i+len(p.Dir)-len(p.ImportPath)]
   932  
   933  		if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) {
   934  			return p
   935  		}
   936  
   937  		// Look for symlinks before reporting error.
   938  		srcDir = expandPath(srcDir)
   939  		parent = expandPath(parent)
   940  		if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) {
   941  			return p
   942  		}
   943  	} else {
   944  		// p is in a module, so make it available based on the importer's import path instead
   945  		// of the file path (https://golang.org/issue/23970).
   946  		if importer.Internal.CmdlineFiles {
   947  			// The importer is a list of command-line files.
   948  			// Pretend that the import path is the import path of the
   949  			// directory containing them.
   950  			// If the directory is outside the main module, this will resolve to ".",
   951  			// which is not a prefix of any valid module.
   952  			importerPath = ModDirImportPath(importer.Dir)
   953  		}
   954  		parentOfInternal := p.ImportPath[:i]
   955  		if str.HasPathPrefix(importerPath, parentOfInternal) {
   956  			return p
   957  		}
   958  	}
   959  
   960  	// Internal is present, and srcDir is outside parent's tree. Not allowed.
   961  	perr := *p
   962  	perr.Error = &PackageError{
   963  		ImportStack: stk.Copy(),
   964  		Err:         "use of internal package " + p.ImportPath + " not allowed",
   965  	}
   966  	perr.Incomplete = true
   967  	return &perr
   968  }
   969  
   970  // findInternal looks for the final "internal" path element in the given import path.
   971  // If there isn't one, findInternal returns ok=false.
   972  // Otherwise, findInternal returns ok=true and the index of the "internal".
   973  func findInternal(path string) (index int, ok bool) {
   974  	// Three cases, depending on internal at start/end of string or not.
   975  	// The order matters: we must return the index of the final element,
   976  	// because the final one produces the most restrictive requirement
   977  	// on the importer.
   978  	switch {
   979  	case strings.HasSuffix(path, "/internal"):
   980  		return len(path) - len("internal"), true
   981  	case strings.Contains(path, "/internal/"):
   982  		return strings.LastIndex(path, "/internal/") + 1, true
   983  	case path == "internal", strings.HasPrefix(path, "internal/"):
   984  		return 0, true
   985  	}
   986  	return 0, false
   987  }
   988  
   989  // disallowVendor checks that srcDir (containing package importerPath, if non-empty)
   990  // is allowed to import p as path.
   991  // If the import is allowed, disallowVendor returns the original package p.
   992  // If not, it returns a new package containing just an appropriate error.
   993  func disallowVendor(srcDir string, importer *Package, importerPath, path string, p *Package, stk *ImportStack) *Package {
   994  	// The stack includes p.ImportPath.
   995  	// If that's the only thing on the stack, we started
   996  	// with a name given on the command line, not an
   997  	// import. Anything listed on the command line is fine.
   998  	if len(*stk) == 1 {
   999  		return p
  1000  	}
  1001  
  1002  	if perr := disallowVendorVisibility(srcDir, p, stk); perr != p {
  1003  		return perr
  1004  	}
  1005  
  1006  	// Paths like x/vendor/y must be imported as y, never as x/vendor/y.
  1007  	if i, ok := FindVendor(path); ok {
  1008  		perr := *p
  1009  		perr.Error = &PackageError{
  1010  			ImportStack: stk.Copy(),
  1011  			Err:         "must be imported as " + path[i+len("vendor/"):],
  1012  		}
  1013  		perr.Incomplete = true
  1014  		return &perr
  1015  	}
  1016  
  1017  	return p
  1018  }
  1019  
  1020  // disallowVendorVisibility checks that srcDir is allowed to import p.
  1021  // The rules are the same as for /internal/ except that a path ending in /vendor
  1022  // is not subject to the rules, only subdirectories of vendor.
  1023  // This allows people to have packages and commands named vendor,
  1024  // for maximal compatibility with existing source trees.
  1025  func disallowVendorVisibility(srcDir string, p *Package, stk *ImportStack) *Package {
  1026  	// The stack includes p.ImportPath.
  1027  	// If that's the only thing on the stack, we started
  1028  	// with a name given on the command line, not an
  1029  	// import. Anything listed on the command line is fine.
  1030  	if len(*stk) == 1 {
  1031  		return p
  1032  	}
  1033  
  1034  	// Check for "vendor" element.
  1035  	i, ok := FindVendor(p.ImportPath)
  1036  	if !ok {
  1037  		return p
  1038  	}
  1039  
  1040  	// Vendor is present.
  1041  	// Map import path back to directory corresponding to parent of vendor.
  1042  	if i > 0 {
  1043  		i-- // rewind over slash in ".../vendor"
  1044  	}
  1045  	truncateTo := i + len(p.Dir) - len(p.ImportPath)
  1046  	if truncateTo < 0 || len(p.Dir) < truncateTo {
  1047  		return p
  1048  	}
  1049  	parent := p.Dir[:truncateTo]
  1050  	if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) {
  1051  		return p
  1052  	}
  1053  
  1054  	// Look for symlinks before reporting error.
  1055  	srcDir = expandPath(srcDir)
  1056  	parent = expandPath(parent)
  1057  	if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) {
  1058  		return p
  1059  	}
  1060  
  1061  	// Vendor is present, and srcDir is outside parent's tree. Not allowed.
  1062  	perr := *p
  1063  	perr.Error = &PackageError{
  1064  		ImportStack: stk.Copy(),
  1065  		Err:         "use of vendored package not allowed",
  1066  	}
  1067  	perr.Incomplete = true
  1068  	return &perr
  1069  }
  1070  
  1071  // FindVendor looks for the last non-terminating "vendor" path element in the given import path.
  1072  // If there isn't one, FindVendor returns ok=false.
  1073  // Otherwise, FindVendor returns ok=true and the index of the "vendor".
  1074  //
  1075  // Note that terminating "vendor" elements don't count: "x/vendor" is its own package,
  1076  // not the vendored copy of an import "" (the empty import path).
  1077  // This will allow people to have packages or commands named vendor.
  1078  // This may help reduce breakage, or it may just be confusing. We'll see.
  1079  func FindVendor(path string) (index int, ok bool) {
  1080  	// Two cases, depending on internal at start of string or not.
  1081  	// The order matters: we must return the index of the final element,
  1082  	// because the final one is where the effective import path starts.
  1083  	switch {
  1084  	case strings.Contains(path, "/vendor/"):
  1085  		return strings.LastIndex(path, "/vendor/") + 1, true
  1086  	case strings.HasPrefix(path, "vendor/"):
  1087  		return 0, true
  1088  	}
  1089  	return 0, false
  1090  }
  1091  
  1092  type TargetDir int
  1093  
  1094  const (
  1095  	ToTool    TargetDir = iota // to GOROOT/pkg/tool (default for cmd/*)
  1096  	ToBin                      // to bin dir inside package root (default for non-cmd/*)
  1097  	StalePath                  // an old import path; fail to build
  1098  )
  1099  
  1100  // InstallTargetDir reports the target directory for installing the command p.
  1101  func InstallTargetDir(p *Package) TargetDir {
  1102  	if strings.HasPrefix(p.ImportPath, "code.google.com/p/go.tools/cmd/") {
  1103  		return StalePath
  1104  	}
  1105  	if p.Goroot && strings.HasPrefix(p.ImportPath, "cmd/") && p.Name == "main" {
  1106  		switch p.ImportPath {
  1107  		case "cmd/go", "cmd/gofmt":
  1108  			return ToBin
  1109  		}
  1110  		return ToTool
  1111  	}
  1112  	return ToBin
  1113  }
  1114  
  1115  var cgoExclude = map[string]bool{
  1116  	"runtime/cgo": true,
  1117  }
  1118  
  1119  var cgoSyscallExclude = map[string]bool{
  1120  	"runtime/cgo":  true,
  1121  	"runtime/race": true,
  1122  	"runtime/msan": true,
  1123  }
  1124  
  1125  var foldPath = make(map[string]string)
  1126  
  1127  // DefaultExecName returns the default executable name
  1128  // for a package with the import path importPath.
  1129  //
  1130  // The default executable name is the last element of the import path.
  1131  // In module-aware mode, an additional rule is used. If the last element
  1132  // is a vN path element specifying the major version, then the second last
  1133  // element of the import path is used instead.
  1134  func DefaultExecName(importPath string) string {
  1135  	_, elem := pathpkg.Split(importPath)
  1136  	if cfg.ModulesEnabled {
  1137  		// If this is example.com/mycmd/v2, it's more useful to install it as mycmd than as v2.
  1138  		// See golang.org/issue/24667.
  1139  		isVersion := func(v string) bool {
  1140  			if len(v) < 2 || v[0] != 'v' || v[1] < '1' || '9' < v[1] {
  1141  				return false
  1142  			}
  1143  			for i := 2; i < len(v); i++ {
  1144  				if c := v[i]; c < '0' || '9' < c {
  1145  					return false
  1146  				}
  1147  			}
  1148  			return true
  1149  		}
  1150  		if isVersion(elem) {
  1151  			_, elem = pathpkg.Split(pathpkg.Dir(importPath))
  1152  		}
  1153  	}
  1154  	return elem
  1155  }
  1156  
  1157  // load populates p using information from bp, err, which should
  1158  // be the result of calling build.Context.Import.
  1159  func (p *Package) load(stk *ImportStack, bp *build.Package, err error) {
  1160  	p.copyBuild(bp)
  1161  
  1162  	// The localPrefix is the path we interpret ./ imports relative to.
  1163  	// Synthesized main packages sometimes override this.
  1164  	if p.Internal.Local {
  1165  		p.Internal.LocalPrefix = dirToImportPath(p.Dir)
  1166  	}
  1167  
  1168  	if err != nil {
  1169  		p.Incomplete = true
  1170  		err = base.ExpandScanner(err)
  1171  		p.Error = &PackageError{
  1172  			ImportStack: stk.Copy(),
  1173  			Err:         err.Error(),
  1174  		}
  1175  		return
  1176  	}
  1177  
  1178  	// Build augmented import list to add implicit dependencies.
  1179  	// Be careful not to add imports twice, just to avoid confusion.
  1180  	importPaths := p.Imports
  1181  
  1182  	// Check for case-insensitive collision of input files.
  1183  	// To avoid problems on case-insensitive files, we reject any package
  1184  	// where two different input files have equal names under a case-insensitive
  1185  	// comparison.
  1186  	inputs := p.AllFiles()
  1187  	f1, f2 := str.FoldDup(inputs)
  1188  	if f1 != "" {
  1189  		p.Error = &PackageError{
  1190  			ImportStack: stk.Copy(),
  1191  			Err:         fmt.Sprintf("case-insensitive file name collision: %q and %q", f1, f2),
  1192  		}
  1193  		return
  1194  	}
  1195  
  1196  	// If first letter of input file is ASCII, it must be alphanumeric.
  1197  	// This avoids files turning into flags when invoking commands,
  1198  	// and other problems we haven't thought of yet.
  1199  	// Also, _cgo_ files must be generated by us, not supplied.
  1200  	// They are allowed to have //go:cgo_ldflag directives.
  1201  	// The directory scan ignores files beginning with _,
  1202  	// so we shouldn't see any _cgo_ files anyway, but just be safe.
  1203  	for _, file := range inputs {
  1204  		if !SafeArg(file) || strings.HasPrefix(file, "_cgo_") {
  1205  			p.Error = &PackageError{
  1206  				ImportStack: stk.Copy(),
  1207  				Err:         fmt.Sprintf("invalid input file name %q", file),
  1208  			}
  1209  			return
  1210  		}
  1211  	}
  1212  	if name := pathpkg.Base(p.ImportPath); !SafeArg(name) {
  1213  		p.Error = &PackageError{
  1214  			ImportStack: stk.Copy(),
  1215  			Err:         fmt.Sprintf("invalid input directory name %q", name),
  1216  		}
  1217  		return
  1218  	}
  1219  	if !SafeArg(p.ImportPath) {
  1220  		p.Error = &PackageError{
  1221  			ImportStack: stk.Copy(),
  1222  			Err:         fmt.Sprintf("invalid import path %q", p.ImportPath),
  1223  		}
  1224  		return
  1225  	}
  1226  
  1227  	// Build list of imported packages and full dependency list.
  1228  	imports := make([]*Package, 0, len(p.Imports))
  1229  	for i, path := range importPaths {
  1230  		p1 := LoadImport(path, p.Dir, p, stk, nil, ResolveImport)
  1231  		if p.Standard && p.Error == nil && !p1.Standard && p1.Error == nil {
  1232  			p.Error = &PackageError{
  1233  				ImportStack: stk.Copy(),
  1234  				Err:         fmt.Sprintf("non-standard import %q in standard package %q", path, p.ImportPath),
  1235  			}
  1236  		}
  1237  
  1238  		path = p1.ImportPath
  1239  		importPaths[i] = path
  1240  		if i < len(p.Imports) {
  1241  			p.Imports[i] = path
  1242  		}
  1243  
  1244  		imports = append(imports, p1)
  1245  		if p1.Incomplete {
  1246  			p.Incomplete = true
  1247  		}
  1248  	}
  1249  	p.Internal.Imports = imports
  1250  
  1251  	deps := make(map[string]*Package)
  1252  	var q []*Package
  1253  	q = append(q, imports...)
  1254  	for i := 0; i < len(q); i++ {
  1255  		p1 := q[i]
  1256  		path := p1.ImportPath
  1257  		// The same import path could produce an error or not,
  1258  		// depending on what tries to import it.
  1259  		// Prefer to record entries with errors, so we can report them.
  1260  		p0 := deps[path]
  1261  		if p0 == nil || p1.Error != nil && (p0.Error == nil || len(p0.Error.ImportStack) > len(p1.Error.ImportStack)) {
  1262  			deps[path] = p1
  1263  			for _, p2 := range p1.Internal.Imports {
  1264  				if deps[p2.ImportPath] != p2 {
  1265  					q = append(q, p2)
  1266  				}
  1267  			}
  1268  		}
  1269  	}
  1270  
  1271  	p.Deps = make([]string, 0, len(deps))
  1272  	for dep := range deps {
  1273  		p.Deps = append(p.Deps, dep)
  1274  	}
  1275  	sort.Strings(p.Deps)
  1276  	for _, dep := range p.Deps {
  1277  		p1 := deps[dep]
  1278  		if p1 == nil {
  1279  			panic("impossible: missing entry in package cache for " + dep + " imported by " + p.ImportPath)
  1280  		}
  1281  		if p1.Error != nil {
  1282  			p.DepsErrors = append(p.DepsErrors, p1.Error)
  1283  		}
  1284  	}
  1285  
  1286  	setError := func(msg string) {
  1287  		p.Error = &PackageError{
  1288  			ImportStack: stk.Copy(),
  1289  			Err:         msg,
  1290  		}
  1291  	}
  1292  
  1293  	// Check for case-insensitive collisions of import paths.
  1294  	fold := str.ToFold(p.ImportPath)
  1295  	if other := foldPath[fold]; other == "" {
  1296  		foldPath[fold] = p.ImportPath
  1297  	} else if other != p.ImportPath {
  1298  		setError(fmt.Sprintf("case-insensitive import collision: %q and %q", p.ImportPath, other))
  1299  		return
  1300  	}
  1301  
  1302  	if cfg.ModulesEnabled {
  1303  		mainPath := p.ImportPath
  1304  		if p.Internal.CmdlineFiles {
  1305  			mainPath = "command-line-arguments"
  1306  		}
  1307  		p.Module = ModPackageModuleInfo(mainPath)
  1308  		if p.Name == "main" {
  1309  			p.Internal.BuildInfo = ModPackageBuildInfo(mainPath, p.Deps)
  1310  		}
  1311  	}
  1312  }
  1313  
  1314  // SafeArg reports whether arg is a "safe" command-line argument,
  1315  // meaning that when it appears in a command-line, it probably
  1316  // doesn't have some special meaning other than its own name.
  1317  // Obviously args beginning with - are not safe (they look like flags).
  1318  // Less obviously, args beginning with @ are not safe (they look like
  1319  // GNU binutils flagfile specifiers, sometimes called "response files").
  1320  // To be conservative, we reject almost any arg beginning with non-alphanumeric ASCII.
  1321  // We accept leading . _ and / as likely in file system paths.
  1322  // There is a copy of this function in cmd/compile/internal/gc/noder.go.
  1323  func SafeArg(name string) bool {
  1324  	if name == "" {
  1325  		return false
  1326  	}
  1327  	c := name[0]
  1328  	return '0' <= c && c <= '9' || 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || c == '.' || c == '_' || c == '/' || c >= utf8.RuneSelf
  1329  }
  1330  
  1331  // LinkerDeps returns the list of linker-induced dependencies for main package p.
  1332  func LinkerDeps(p *Package) []string {
  1333  	// Everything links runtime.
  1334  	deps := []string{"runtime"}
  1335  
  1336  	// Using the race detector forces an import of runtime/race.
  1337  	if cfg.BuildRace {
  1338  		deps = append(deps, "runtime/race")
  1339  	}
  1340  	// Using memory sanitizer forces an import of runtime/msan.
  1341  	if cfg.BuildMSan {
  1342  		deps = append(deps, "runtime/msan")
  1343  	}
  1344  
  1345  	return deps
  1346  }
  1347  
  1348  // externalLinkingForced reports whether external linking is being
  1349  // forced even for programs that do not use cgo.
  1350  func externalLinkingForced(p *Package) bool {
  1351  	return false
  1352  }
  1353  
  1354  // mkAbs rewrites list, which must be paths relative to p.Dir,
  1355  // into a sorted list of absolute paths. It edits list in place but for
  1356  // convenience also returns list back to its caller.
  1357  func (p *Package) mkAbs(list []string) []string {
  1358  	for i, f := range list {
  1359  		list[i] = filepath.Join(p.Dir, f)
  1360  	}
  1361  	sort.Strings(list)
  1362  	return list
  1363  }
  1364  
  1365  // InternalGoFiles returns the list of Go files being built for the package,
  1366  // using absolute paths.
  1367  func (p *Package) InternalGoFiles() []string {
  1368  	return p.mkAbs(str.StringList(p.GoFiles, p.CgoFiles, p.TestGoFiles))
  1369  }
  1370  
  1371  // InternalXGoFiles returns the list of Go files being built for the XTest package,
  1372  // using absolute paths.
  1373  func (p *Package) InternalXGoFiles() []string {
  1374  	return p.mkAbs(p.XTestGoFiles)
  1375  }
  1376  
  1377  // InternalGoFiles returns the list of all Go files possibly relevant for the package,
  1378  // using absolute paths. "Possibly relevant" means that files are not excluded
  1379  // due to build tags, but files with names beginning with . or _ are still excluded.
  1380  func (p *Package) InternalAllGoFiles() []string {
  1381  	var extra []string
  1382  	for _, f := range p.IgnoredGoFiles {
  1383  		if f != "" && f[0] != '.' || f[0] != '_' {
  1384  			extra = append(extra, f)
  1385  		}
  1386  	}
  1387  	return p.mkAbs(str.StringList(extra, p.GoFiles, p.CgoFiles, p.TestGoFiles, p.XTestGoFiles))
  1388  }
  1389  
  1390  // usesSwig reports whether the package needs to run SWIG.
  1391  func (p *Package) UsesSwig() bool {
  1392  	return len(p.SwigFiles) > 0 || len(p.SwigCXXFiles) > 0
  1393  }
  1394  
  1395  // usesCgo reports whether the package needs to run cgo
  1396  func (p *Package) UsesCgo() bool {
  1397  	return len(p.CgoFiles) > 0
  1398  }
  1399  
  1400  // PackageList returns the list of packages in the dag rooted at roots
  1401  // as visited in a depth-first post-order traversal.
  1402  func PackageList(roots []*Package) []*Package {
  1403  	seen := map[*Package]bool{}
  1404  	all := []*Package{}
  1405  	var walk func(*Package)
  1406  	walk = func(p *Package) {
  1407  		if seen[p] {
  1408  			return
  1409  		}
  1410  		seen[p] = true
  1411  		for _, p1 := range p.Internal.Imports {
  1412  			walk(p1)
  1413  		}
  1414  		all = append(all, p)
  1415  	}
  1416  	for _, root := range roots {
  1417  		walk(root)
  1418  	}
  1419  	return all
  1420  }
  1421  
  1422  var cmdCache = map[string]*Package{}
  1423  
  1424  func ClearCmdCache() {
  1425  	for name := range cmdCache {
  1426  		delete(cmdCache, name)
  1427  	}
  1428  }
  1429  
  1430  // LoadPackage loads the package named by arg.
  1431  func LoadPackage(arg string, stk *ImportStack) *Package {
  1432  	p := loadPackage(arg, stk)
  1433  	setToolFlags(p)
  1434  	return p
  1435  }
  1436  
  1437  // LoadPackageNoFlags is like LoadPackage
  1438  // but does not guarantee that the build tool flags are set in the result.
  1439  // It is only for use by GOPATH-based "go get"
  1440  // and is only appropriate for preliminary loading of packages.
  1441  // A real load using LoadPackage or (more likely)
  1442  // Packages, PackageAndErrors, or PackagesForBuild
  1443  // must be done before passing the package to any build
  1444  // steps, so that the tool flags can be set properly.
  1445  // TODO(rsc): When GOPATH-based "go get" is removed, delete this function.
  1446  func LoadPackageNoFlags(arg string, stk *ImportStack) *Package {
  1447  	return loadPackage(arg, stk)
  1448  }
  1449  
  1450  // loadPackage is like loadImport but is used for command-line arguments,
  1451  // not for paths found in import statements. In addition to ordinary import paths,
  1452  // loadPackage accepts pseudo-paths beginning with cmd/ to denote commands
  1453  // in the Go command directory, as well as paths to those directories.
  1454  func loadPackage(arg string, stk *ImportStack) *Package {
  1455  	if arg == "" {
  1456  		panic("loadPackage called with empty package path")
  1457  	}
  1458  
  1459  	// Wasn't a command; must be a package.
  1460  	// If it is a local import path but names a standard package,
  1461  	// we treat it as if the user specified the standard package.
  1462  	// This lets you run go test ./ioutil in package io and be
  1463  	// referring to io/ioutil rather than a hypothetical import of
  1464  	// "./ioutil".
  1465  	if build.IsLocalImport(arg) || filepath.IsAbs(arg) {
  1466  		dir := arg
  1467  		if !filepath.IsAbs(arg) {
  1468  			dir = filepath.Join(base.Cwd, arg)
  1469  		}
  1470  		bp, _ := cfg.BuildContext.ImportDir(dir, 0)
  1471  		if bp.ImportPath != "" && bp.ImportPath != "." {
  1472  			arg = bp.ImportPath
  1473  		}
  1474  	}
  1475  
  1476  	return LoadImport(arg, base.Cwd, nil, stk, nil, 0)
  1477  }
  1478  
  1479  // Packages returns the packages named by the
  1480  // command line arguments 'args'. If a named package
  1481  // cannot be loaded at all (for example, if the directory does not exist),
  1482  // then packages prints an error and does not include that
  1483  // package in the results. However, if errors occur trying
  1484  // to load dependencies of a named package, the named
  1485  // package is still returned, with p.Incomplete = true
  1486  // and details in p.DepsErrors.
  1487  func Packages(args []string) []*Package {
  1488  	var pkgs []*Package
  1489  	for _, pkg := range PackagesAndErrors(args) {
  1490  		if pkg.Error != nil {
  1491  			base.Errorf("can't load package: %s", pkg.Error)
  1492  			continue
  1493  		}
  1494  		pkgs = append(pkgs, pkg)
  1495  	}
  1496  	return pkgs
  1497  }
  1498  
  1499  // PackagesAndErrors is like 'packages' but returns a
  1500  // *Package for every argument, even the ones that
  1501  // cannot be loaded at all.
  1502  // The packages that fail to load will have p.Error != nil.
  1503  func PackagesAndErrors(patterns []string) []*Package {
  1504  	if len(patterns) > 0 && strings.HasSuffix(patterns[0], ".go") {
  1505  		return []*Package{GoFilesPackage(patterns)}
  1506  	}
  1507  
  1508  	matches := ImportPaths(patterns)
  1509  	var (
  1510  		pkgs    []*Package
  1511  		stk     ImportStack
  1512  		seenPkg = make(map[*Package]bool)
  1513  	)
  1514  
  1515  	for _, m := range matches {
  1516  		for _, pkg := range m.Pkgs {
  1517  			if pkg == "" {
  1518  				panic(fmt.Sprintf("ImportPaths returned empty package for pattern %s", m.Pattern))
  1519  			}
  1520  			p := loadPackage(pkg, &stk)
  1521  			p.Match = append(p.Match, m.Pattern)
  1522  			p.Internal.CmdlinePkg = true
  1523  			if m.Literal {
  1524  				// Note: do not set = m.Literal unconditionally
  1525  				// because maybe we'll see p matching both
  1526  				// a literal and also a non-literal pattern.
  1527  				p.Internal.CmdlinePkgLiteral = true
  1528  			}
  1529  			if seenPkg[p] {
  1530  				continue
  1531  			}
  1532  			seenPkg[p] = true
  1533  			pkgs = append(pkgs, p)
  1534  		}
  1535  	}
  1536  
  1537  	// Now that CmdlinePkg is set correctly,
  1538  	// compute the effective flags for all loaded packages
  1539  	// (not just the ones matching the patterns but also
  1540  	// their dependencies).
  1541  	setToolFlags(pkgs...)
  1542  
  1543  	return pkgs
  1544  }
  1545  
  1546  func setToolFlags(pkgs ...*Package) {
  1547  	for _, p := range PackageList(pkgs) {
  1548  		p.Internal.Asmflags = BuildAsmflags.For(p)
  1549  		p.Internal.Gcflags = BuildGcflags.For(p)
  1550  		p.Internal.Ldflags = BuildLdflags.For(p)
  1551  		p.Internal.Gccgoflags = BuildGccgoflags.For(p)
  1552  	}
  1553  }
  1554  
  1555  func ImportPaths(args []string) []*search.Match {
  1556  	if ModInit(); cfg.ModulesEnabled {
  1557  		return ModImportPaths(args)
  1558  	}
  1559  	return search.ImportPaths(args)
  1560  }
  1561  
  1562  // PackagesForBuild is like Packages but exits
  1563  // if any of the packages or their dependencies have errors
  1564  // (cannot be built).
  1565  func PackagesForBuild(args []string) []*Package {
  1566  	pkgs := PackagesAndErrors(args)
  1567  	printed := map[*PackageError]bool{}
  1568  	for _, pkg := range pkgs {
  1569  		if pkg.Error != nil {
  1570  			base.Errorf("can't load package: %s", pkg.Error)
  1571  			printed[pkg.Error] = true
  1572  		}
  1573  		for _, err := range pkg.DepsErrors {
  1574  			// Since these are errors in dependencies,
  1575  			// the same error might show up multiple times,
  1576  			// once in each package that depends on it.
  1577  			// Only print each once.
  1578  			if !printed[err] {
  1579  				printed[err] = true
  1580  				base.Errorf("%s", err)
  1581  			}
  1582  		}
  1583  	}
  1584  	base.ExitIfErrors()
  1585  
  1586  	// Check for duplicate loads of the same package.
  1587  	// That should be impossible, but if it does happen then
  1588  	// we end up trying to build the same package twice,
  1589  	// usually in parallel overwriting the same files,
  1590  	// which doesn't work very well.
  1591  	seen := map[string]bool{}
  1592  	reported := map[string]bool{}
  1593  	for _, pkg := range PackageList(pkgs) {
  1594  		if seen[pkg.ImportPath] && !reported[pkg.ImportPath] {
  1595  			reported[pkg.ImportPath] = true
  1596  			base.Errorf("internal error: duplicate loads of %s", pkg.ImportPath)
  1597  		}
  1598  		seen[pkg.ImportPath] = true
  1599  	}
  1600  	base.ExitIfErrors()
  1601  
  1602  	return pkgs
  1603  }
  1604  
  1605  // GoFilesPackage creates a package for building a collection of Go files
  1606  // (typically named on the command line). The target is named p.a for
  1607  // package p or named after the first Go file for package main.
  1608  func GoFilesPackage(gofiles []string) *Package {
  1609  	ModInit()
  1610  
  1611  	for _, f := range gofiles {
  1612  		if !strings.HasSuffix(f, ".go") {
  1613  			base.Fatalf("named files must be .go files")
  1614  		}
  1615  	}
  1616  
  1617  	var stk ImportStack
  1618  	ctxt := cfg.BuildContext
  1619  
  1620  	// Synthesize fake "directory" that only shows the named files,
  1621  	// to make it look like this is a standard package or
  1622  	// command directory. So that local imports resolve
  1623  	// consistently, the files must all be in the same directory.
  1624  	var dirent []os.FileInfo
  1625  	var dir string
  1626  	for _, file := range gofiles {
  1627  		fi, err := os.Stat(file)
  1628  		if err != nil {
  1629  			base.Fatalf("%s", err)
  1630  		}
  1631  		if fi.IsDir() {
  1632  			base.Fatalf("%s is a directory, should be a Go file", file)
  1633  		}
  1634  		dir1, _ := filepath.Split(file)
  1635  		if dir1 == "" {
  1636  			dir1 = "./"
  1637  		}
  1638  		if dir == "" {
  1639  			dir = dir1
  1640  		} else if dir != dir1 {
  1641  			base.Fatalf("named files must all be in one directory; have %s and %s", dir, dir1)
  1642  		}
  1643  		dirent = append(dirent, fi)
  1644  	}
  1645  	ctxt.ReadDir = func(string) ([]os.FileInfo, error) { return dirent, nil }
  1646  
  1647  	if cfg.ModulesEnabled {
  1648  		ModImportFromFiles(gofiles)
  1649  	}
  1650  
  1651  	var err error
  1652  	if dir == "" {
  1653  		dir = base.Cwd
  1654  	}
  1655  	dir, err = filepath.Abs(dir)
  1656  	if err != nil {
  1657  		base.Fatalf("%s", err)
  1658  	}
  1659  
  1660  	bp, err := ctxt.ImportDir(dir, 0)
  1661  	pkg := new(Package)
  1662  	pkg.Internal.Local = true
  1663  	pkg.Internal.CmdlineFiles = true
  1664  	stk.Push("main")
  1665  	pkg.load(&stk, bp, err)
  1666  	stk.Pop()
  1667  	pkg.Internal.LocalPrefix = dirToImportPath(dir)
  1668  	pkg.ImportPath = "command-line-arguments"
  1669  	pkg.Target = ""
  1670  	pkg.Match = gofiles
  1671  
  1672  	if pkg.Name == "main" {
  1673  		_, elem := filepath.Split(gofiles[0])
  1674  		exe := elem[:len(elem)-len(".go")] + cfg.ExeSuffix
  1675  		if cfg.BuildO == "" {
  1676  			cfg.BuildO = exe
  1677  		}
  1678  		pkg.Target = filepath.Join(ModBinDir(), exe)
  1679  	}
  1680  
  1681  	setToolFlags(pkg)
  1682  
  1683  	return pkg
  1684  }